@jackwener/opencli 1.7.16 → 1.7.17

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.
Files changed (149) hide show
  1. package/README.md +8 -9
  2. package/README.zh-CN.md +8 -8
  3. package/cli-manifest.json +97 -271
  4. package/clis/chatgpt/ask.js +1 -1
  5. package/clis/chatgpt/commands.test.js +2 -2
  6. package/clis/chatgpt/detail.js +1 -1
  7. package/clis/chatgpt/history.js +1 -1
  8. package/clis/chatgpt/image.js +38 -4
  9. package/clis/chatgpt/image.test.js +68 -1
  10. package/clis/chatgpt/new.js +1 -1
  11. package/clis/chatgpt/read.js +1 -1
  12. package/clis/chatgpt/send.js +1 -1
  13. package/clis/chatgpt/status.js +1 -1
  14. package/clis/chatgpt/utils.js +208 -16
  15. package/clis/chatgpt/utils.test.js +131 -2
  16. package/clis/claude/ask.js +1 -1
  17. package/clis/claude/detail.js +1 -1
  18. package/clis/claude/history.js +1 -1
  19. package/clis/claude/new.js +1 -1
  20. package/clis/claude/read.js +1 -1
  21. package/clis/claude/send.js +1 -1
  22. package/clis/claude/status.js +1 -1
  23. package/clis/deepseek/ask.js +1 -1
  24. package/clis/deepseek/detail.js +1 -1
  25. package/clis/deepseek/history.js +1 -1
  26. package/clis/deepseek/new.js +1 -1
  27. package/clis/deepseek/read.js +1 -1
  28. package/clis/deepseek/send.js +1 -1
  29. package/clis/deepseek/status.js +1 -1
  30. package/clis/doubao/ask.js +1 -1
  31. package/clis/doubao/detail.js +1 -1
  32. package/clis/doubao/history.js +1 -1
  33. package/clis/doubao/meeting-summary.js +1 -1
  34. package/clis/doubao/meeting-transcript.js +1 -1
  35. package/clis/doubao/new.js +1 -1
  36. package/clis/doubao/read.js +1 -1
  37. package/clis/doubao/send.js +1 -1
  38. package/clis/doubao/status.js +1 -1
  39. package/clis/gemini/ask.js +1 -1
  40. package/clis/gemini/deep-research-result.js +1 -1
  41. package/clis/gemini/deep-research.js +1 -1
  42. package/clis/gemini/image.js +1 -1
  43. package/clis/gemini/new.js +1 -1
  44. package/clis/grok/ask.js +1 -1
  45. package/clis/grok/detail.js +1 -1
  46. package/clis/grok/history.js +1 -1
  47. package/clis/grok/image.js +1 -1
  48. package/clis/grok/new.js +1 -1
  49. package/clis/grok/read.js +1 -1
  50. package/clis/grok/send.js +1 -1
  51. package/clis/grok/status.js +1 -1
  52. package/clis/notebooklm/current.js +1 -1
  53. package/clis/notebooklm/get.js +1 -1
  54. package/clis/notebooklm/history.js +1 -1
  55. package/clis/notebooklm/note-list.js +1 -1
  56. package/clis/notebooklm/notes-get.js +1 -1
  57. package/clis/notebooklm/open.js +2 -2
  58. package/clis/notebooklm/open.test.js +1 -1
  59. package/clis/notebooklm/source-fulltext.js +1 -1
  60. package/clis/notebooklm/source-get.js +1 -1
  61. package/clis/notebooklm/source-guide.js +1 -1
  62. package/clis/notebooklm/source-list.js +1 -1
  63. package/clis/notebooklm/summary.js +1 -1
  64. package/clis/qwen/ask.js +1 -1
  65. package/clis/qwen/detail.js +1 -1
  66. package/clis/qwen/history.js +1 -1
  67. package/clis/qwen/image.js +1 -1
  68. package/clis/qwen/new.js +1 -1
  69. package/clis/qwen/read.js +1 -1
  70. package/clis/qwen/send.js +1 -1
  71. package/clis/qwen/status.js +1 -1
  72. package/clis/reddit/comment.js +1 -1
  73. package/clis/reddit/frontpage.js +1 -1
  74. package/clis/reddit/popular.js +1 -1
  75. package/clis/reddit/read.js +1 -1
  76. package/clis/reddit/read.test.js +2 -2
  77. package/clis/reddit/save.js +1 -1
  78. package/clis/reddit/saved.js +1 -1
  79. package/clis/reddit/search.js +1 -1
  80. package/clis/reddit/subreddit.js +1 -1
  81. package/clis/reddit/subscribe.js +1 -1
  82. package/clis/reddit/upvote.js +1 -1
  83. package/clis/reddit/upvoted.js +1 -1
  84. package/clis/reddit/user-comments.js +1 -1
  85. package/clis/reddit/user-posts.js +1 -1
  86. package/clis/reddit/user.js +1 -1
  87. package/clis/twitter/article.js +1 -1
  88. package/clis/twitter/bookmark-folder.js +1 -1
  89. package/clis/twitter/bookmark-folders.js +1 -1
  90. package/clis/twitter/bookmarks.js +1 -1
  91. package/clis/twitter/download.js +1 -1
  92. package/clis/twitter/followers.js +1 -1
  93. package/clis/twitter/following.js +1 -1
  94. package/clis/twitter/likes.js +1 -1
  95. package/clis/twitter/list-tweets.js +1 -1
  96. package/clis/twitter/lists.js +1 -1
  97. package/clis/twitter/notifications.js +1 -1
  98. package/clis/twitter/profile.js +1 -1
  99. package/clis/twitter/search.js +1 -1
  100. package/clis/twitter/thread.js +1 -1
  101. package/clis/twitter/timeline.js +1 -1
  102. package/clis/twitter/trending.js +1 -1
  103. package/clis/twitter/tweets.js +1 -1
  104. package/clis/yuanbao/ask.js +1 -1
  105. package/clis/yuanbao/detail.js +1 -1
  106. package/clis/yuanbao/history.js +1 -1
  107. package/clis/yuanbao/new.js +1 -1
  108. package/clis/yuanbao/read.js +1 -1
  109. package/clis/yuanbao/send.js +1 -1
  110. package/clis/yuanbao/status.js +1 -1
  111. package/dist/src/browser/bridge.d.ts +3 -1
  112. package/dist/src/browser/bridge.js +3 -1
  113. package/dist/src/browser/cdp.d.ts +3 -1
  114. package/dist/src/browser/daemon-client.d.ts +7 -14
  115. package/dist/src/browser/daemon-client.js +2 -6
  116. package/dist/src/browser/network-cache.d.ts +5 -5
  117. package/dist/src/browser/network-cache.js +8 -8
  118. package/dist/src/browser/network-cache.test.js +4 -4
  119. package/dist/src/browser/page.d.ts +8 -7
  120. package/dist/src/browser/page.js +23 -16
  121. package/dist/src/browser/page.test.js +60 -30
  122. package/dist/src/build-manifest.js +1 -1
  123. package/dist/src/cli.js +60 -162
  124. package/dist/src/cli.test.js +178 -197
  125. package/dist/src/commanderAdapter.js +2 -0
  126. package/dist/src/discovery.js +1 -1
  127. package/dist/src/doctor.d.ts +0 -4
  128. package/dist/src/doctor.js +8 -72
  129. package/dist/src/doctor.test.js +26 -97
  130. package/dist/src/execution.d.ts +1 -0
  131. package/dist/src/execution.js +20 -21
  132. package/dist/src/execution.test.js +27 -31
  133. package/dist/src/help.js +7 -1
  134. package/dist/src/main.js +0 -19
  135. package/dist/src/manifest-types.d.ts +2 -4
  136. package/dist/src/observation/artifact.js +1 -1
  137. package/dist/src/observation/artifact.test.js +3 -3
  138. package/dist/src/observation/events.d.ts +1 -1
  139. package/dist/src/observation/manager.js +1 -1
  140. package/dist/src/observation/manager.test.js +3 -3
  141. package/dist/src/registry-api.d.ts +1 -1
  142. package/dist/src/registry.d.ts +3 -12
  143. package/dist/src/registry.js +6 -10
  144. package/dist/src/runtime.d.ts +7 -2
  145. package/dist/src/runtime.js +3 -1
  146. package/dist/src/serialization.d.ts +1 -1
  147. package/dist/src/serialization.js +1 -1
  148. package/dist/src/types.d.ts +0 -15
  149. package/package.json +1 -1
@@ -17,7 +17,7 @@ cli({
17
17
  await requireNotebooklmSession(page);
18
18
  const state = await getNotebooklmPageState(page);
19
19
  if (state.kind !== 'notebook') {
20
- throw new EmptyResultError('opencli notebooklm source-list', 'No NotebookLM notebook is open in the automation workspace. Run `opencli notebooklm open <notebook>` first.');
20
+ throw new EmptyResultError('opencli notebooklm source-list', 'No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.');
21
21
  }
22
22
  const rpcRows = await listNotebooklmSourcesViaRpc(page).catch(() => []);
23
23
  if (rpcRows.length > 0)
@@ -17,7 +17,7 @@ cli({
17
17
  await requireNotebooklmSession(page);
18
18
  const state = await getNotebooklmPageState(page);
19
19
  if (state.kind !== 'notebook') {
20
- throw new EmptyResultError('opencli notebooklm summary', 'No NotebookLM notebook is open in the automation workspace. Run `opencli notebooklm open <notebook>` first.');
20
+ throw new EmptyResultError('opencli notebooklm summary', 'No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.');
21
21
  }
22
22
  const domSummary = await readNotebooklmSummaryFromPage(page);
23
23
  if (domSummary)
package/clis/qwen/ask.js CHANGED
@@ -24,7 +24,7 @@ cli({
24
24
  domain: QIANWEN_DOMAIN,
25
25
  strategy: Strategy.COOKIE,
26
26
  browser: true,
27
- browserSession: { reuse: 'site' },
27
+ siteSession: 'persistent',
28
28
  navigateBefore: false,
29
29
  defaultFormat: 'plain',
30
30
  args: [
@@ -18,7 +18,7 @@ cli({
18
18
  strategy: Strategy.COOKIE,
19
19
  browser: true,
20
20
  navigateBefore: false,
21
- browserSession: { reuse: 'site' },
21
+ siteSession: 'persistent',
22
22
  args: [
23
23
  { name: 'id', positional: true, required: true, help: 'Session ID (32-char hex) or full https://www.qianwen.com/chat/<id> URL' },
24
24
  { name: 'markdown', type: 'boolean', default: false, help: 'Emit assistant replies as markdown' },
@@ -24,7 +24,7 @@ cli({
24
24
  domain: QIANWEN_DOMAIN,
25
25
  strategy: Strategy.COOKIE,
26
26
  browser: true,
27
- browserSession: { reuse: 'site' },
27
+ siteSession: 'persistent',
28
28
  navigateBefore: false,
29
29
  args: [
30
30
  { name: 'limit', type: 'int', default: 20, help: 'Max conversations to show (default 20, max 100)' },
@@ -99,7 +99,7 @@ cli({
99
99
  domain: QIANWEN_DOMAIN,
100
100
  strategy: Strategy.COOKIE,
101
101
  browser: true,
102
- browserSession: { reuse: 'site' },
102
+ siteSession: 'persistent',
103
103
  navigateBefore: false,
104
104
  defaultFormat: 'plain',
105
105
  args: [
package/clis/qwen/new.js CHANGED
@@ -9,7 +9,7 @@ cli({
9
9
  domain: QIANWEN_DOMAIN,
10
10
  strategy: Strategy.COOKIE,
11
11
  browser: true,
12
- browserSession: { reuse: 'site' },
12
+ siteSession: 'persistent',
13
13
  navigateBefore: false,
14
14
  args: [],
15
15
  columns: ['Status'],
package/clis/qwen/read.js CHANGED
@@ -16,7 +16,7 @@ cli({
16
16
  domain: QIANWEN_DOMAIN,
17
17
  strategy: Strategy.COOKIE,
18
18
  browser: true,
19
- browserSession: { reuse: 'site' },
19
+ siteSession: 'persistent',
20
20
  navigateBefore: false,
21
21
  args: [
22
22
  { name: 'markdown', type: 'boolean', default: false, help: 'Emit assistant replies as markdown' },
package/clis/qwen/send.js CHANGED
@@ -20,7 +20,7 @@ cli({
20
20
  domain: QIANWEN_DOMAIN,
21
21
  strategy: Strategy.COOKIE,
22
22
  browser: true,
23
- browserSession: { reuse: 'site' },
23
+ siteSession: 'persistent',
24
24
  navigateBefore: false,
25
25
  args: [
26
26
  { name: 'prompt', required: true, positional: true, help: 'Prompt to send to Qianwen' },
@@ -9,7 +9,7 @@ cli({
9
9
  domain: QIANWEN_DOMAIN,
10
10
  strategy: Strategy.COOKIE,
11
11
  browser: true,
12
- browserSession: { reuse: 'site' },
12
+ siteSession: 'persistent',
13
13
  navigateBefore: false,
14
14
  args: [],
15
15
  columns: ['Status', 'Login', 'Model', 'SessionId', 'Url'],
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'post-id', type: 'string', required: true, positional: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
14
14
  { name: 'text', type: 'string', required: true, positional: true, help: 'Comment text' },
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'limit', type: 'int', default: 15 },
13
13
  ],
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'limit', type: 'int', default: 20 },
13
13
  ],
@@ -16,7 +16,7 @@ cli({
16
16
  domain: 'reddit.com',
17
17
  strategy: Strategy.COOKIE,
18
18
  browser: true,
19
- browserSession: { reuse: 'site' },
19
+ siteSession: 'persistent',
20
20
  args: [
21
21
  { name: 'post-id', required: true, positional: true, help: 'Post ID (e.g. 1abc123) or full URL' },
22
22
  { name: 'sort', default: 'best', help: 'Comment sort: best, top, new, controversial, old, qa' },
@@ -3,9 +3,9 @@ import { getRegistry } from '@jackwener/opencli/registry';
3
3
  import './read.js';
4
4
  describe('reddit read adapter', () => {
5
5
  const command = getRegistry().get('reddit/read');
6
- it('opts into the Reddit site browser session lease', () => {
6
+ it('opts into the Reddit persistent site session', () => {
7
7
  expect(command?.browser).toBe(true);
8
- expect(command?.browserSession).toEqual({ reuse: 'site' });
8
+ expect(command?.siteSession).toBe('persistent');
9
9
  });
10
10
  it('returns threaded rows from the browser-evaluated payload', async () => {
11
11
  const page = {
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'post-id', type: 'string', required: true, positional: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
14
14
  { name: 'undo', type: 'boolean', default: false, help: 'Unsave instead of save' },
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'limit', type: 'int', default: 15 },
14
14
  ],
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'query', type: 'string', required: true, positional: true, help: 'Reddit search query' },
13
13
  {
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'name', type: 'string', required: true, positional: true, help: 'Subreddit name (no `r/` prefix; e.g. `python`)' },
13
13
  {
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'subreddit', type: 'string', required: true, positional: true, help: 'Subreddit name (e.g. python)' },
14
14
  { name: 'undo', type: 'boolean', default: false, help: 'Unsubscribe instead of subscribe' },
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'post-id', type: 'string', required: true, positional: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
14
14
  { name: 'direction', type: 'string', default: 'up', help: 'Vote direction: up, down, none' },
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'reddit.com',
9
9
  strategy: Strategy.COOKIE,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'limit', type: 'int', default: 15 },
14
14
  ],
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'username', type: 'string', required: true, positional: true, help: 'Reddit username (no `u/` prefix needed)' },
13
13
  { name: 'limit', type: 'int', default: 15 },
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'username', type: 'string', required: true, positional: true, help: 'Reddit username (no `u/` prefix needed)' },
13
13
  { name: 'limit', type: 'int', default: 15 },
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'reddit.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  browser: true,
10
- browserSession: { reuse: 'site' },
10
+ siteSession: 'persistent',
11
11
  args: [
12
12
  { name: 'username', type: 'string', required: true, positional: true, help: 'Reddit username (no `u/` prefix needed)' },
13
13
  ],
@@ -11,7 +11,7 @@ cli({
11
11
  domain: 'x.com',
12
12
  strategy: Strategy.COOKIE,
13
13
  browser: true,
14
- browserSession: { reuse: 'site' },
14
+ siteSession: 'persistent',
15
15
  args: [
16
16
  { name: 'tweet-id', type: 'string', positional: true, required: true, help: 'Tweet ID or URL containing the article' },
17
17
  ],
@@ -122,7 +122,7 @@ cli({
122
122
  domain: 'x.com',
123
123
  strategy: Strategy.COOKIE,
124
124
  browser: true,
125
- browserSession: { reuse: 'site' },
125
+ siteSession: 'persistent',
126
126
  args: [
127
127
  { name: 'folder-id', positional: true, type: 'string', required: true, help: 'Folder id from `opencli twitter bookmark-folders`.' },
128
128
  { name: 'limit', type: 'int', default: 20, help: 'Maximum number of bookmarks to return (default 20).' },
@@ -77,7 +77,7 @@ cli({
77
77
  domain: 'x.com',
78
78
  strategy: Strategy.COOKIE,
79
79
  browser: true,
80
- browserSession: { reuse: 'site' },
80
+ siteSession: 'persistent',
81
81
  args: [],
82
82
  columns: ['id', 'name', 'items', 'created_at'],
83
83
  func: async (page) => {
@@ -105,7 +105,7 @@ cli({
105
105
  domain: 'x.com',
106
106
  strategy: Strategy.COOKIE,
107
107
  browser: true,
108
- browserSession: { reuse: 'site' },
108
+ siteSession: 'persistent',
109
109
  args: [
110
110
  { name: 'limit', type: 'int', default: 20, help: 'Maximum number of bookmarks to return (default 20).' },
111
111
  { name: 'top-by-engagement', type: 'int', default: 0, help: 'When set to N>0, re-rank the bookmarks by weighted engagement (likes×1 + retweets×3 + replies×2 + bookmarks×5 + log10(views+1)×0.5) and return the top N. Default 0 keeps the API\'s native (saved-time) ordering.' },
@@ -15,7 +15,7 @@ cli({
15
15
  description: 'Download Twitter/X media (images and videos). Provide either <username> to scan a profile\'s media tab, or --tweet-url to download a single tweet.',
16
16
  domain: 'x.com',
17
17
  strategy: Strategy.COOKIE,
18
- browserSession: { reuse: 'site' },
18
+ siteSession: 'persistent',
19
19
  args: [
20
20
  { name: 'username', positional: true, help: 'Twitter username (with or without @) to scan their /media tab. Either <username> or --tweet-url is required.' },
21
21
  { name: 'tweet-url', help: 'Single tweet URL to download. Use this OR <username>, not both required at once.' },
@@ -83,7 +83,7 @@ cli({
83
83
  domain: 'x.com',
84
84
  strategy: Strategy.UI,
85
85
  browser: true,
86
- browserSession: { reuse: 'site' },
86
+ siteSession: 'persistent',
87
87
  args: [
88
88
  {
89
89
  name: 'user',
@@ -139,7 +139,7 @@ cli({
139
139
  domain: 'x.com',
140
140
  strategy: Strategy.COOKIE,
141
141
  browser: true,
142
- browserSession: { reuse: 'site' },
142
+ siteSession: 'persistent',
143
143
  args: [
144
144
  {
145
145
  name: 'user',
@@ -142,7 +142,7 @@ cli({
142
142
  domain: 'x.com',
143
143
  strategy: Strategy.COOKIE,
144
144
  browser: true,
145
- browserSession: { reuse: 'site' },
145
+ siteSession: 'persistent',
146
146
  args: [
147
147
  { name: 'username', type: 'string', positional: true, help: 'Twitter screen name (with or without @). Defaults to the logged-in user when omitted.' },
148
148
  { name: 'limit', type: 'int', default: 20, help: 'Maximum number of liked tweets to return (default 20).' },
@@ -112,7 +112,7 @@ cli({
112
112
  domain: 'x.com',
113
113
  strategy: Strategy.COOKIE,
114
114
  browser: true,
115
- browserSession: { reuse: 'site' },
115
+ siteSession: 'persistent',
116
116
  args: [
117
117
  { name: 'listId', positional: true, type: 'string', required: true, help: 'Numeric ID of a Twitter/X list (e.g. from `opencli twitter lists`)' },
118
118
  { name: 'limit', type: 'int', default: 50 },
@@ -92,7 +92,7 @@ export const command = cli({
92
92
  domain: 'x.com',
93
93
  strategy: Strategy.COOKIE,
94
94
  browser: true,
95
- browserSession: { reuse: 'site' },
95
+ siteSession: 'persistent',
96
96
  args: [
97
97
  { name: 'limit', type: 'int', default: 50, help: 'Maximum number of lists to return (default 50).' },
98
98
  ],
@@ -8,7 +8,7 @@ cli({
8
8
  domain: 'x.com',
9
9
  strategy: Strategy.INTERCEPT,
10
10
  browser: true,
11
- browserSession: { reuse: 'site' },
11
+ siteSession: 'persistent',
12
12
  args: [
13
13
  { name: 'limit', type: 'int', default: 20, help: 'Maximum number of notifications to return (default 20).' },
14
14
  ],
@@ -11,7 +11,7 @@ cli({
11
11
  domain: 'x.com',
12
12
  strategy: Strategy.COOKIE,
13
13
  browser: true,
14
- browserSession: { reuse: 'site' },
14
+ siteSession: 'persistent',
15
15
  args: [
16
16
  { name: 'username', type: 'string', positional: true, help: 'Twitter screen name (with or without @). Defaults to the logged-in user when omitted.' },
17
17
  ],
@@ -228,7 +228,7 @@ cli({
228
228
  domain: 'x.com',
229
229
  strategy: Strategy.INTERCEPT, // Use intercept strategy
230
230
  browser: true,
231
- browserSession: { reuse: 'site' },
231
+ siteSession: 'persistent',
232
232
  args: [
233
233
  { name: 'query', type: 'string', required: true, positional: true, help: 'Search query. Raw X operators (e.g. "exact phrase", #tag, OR, lang:en, since:YYYY-MM-DD, from:, since:) are passed through unchanged.' },
234
234
  { name: 'filter', type: 'string', default: 'top', choices: ['top', 'live'], help: 'Legacy alias for --product. Kept for backwards compatibility; if --product is set it wins.' },
@@ -100,7 +100,7 @@ cli({
100
100
  domain: 'x.com',
101
101
  strategy: Strategy.COOKIE,
102
102
  browser: true,
103
- browserSession: { reuse: 'site' },
103
+ siteSession: 'persistent',
104
104
  args: [
105
105
  { name: 'tweet-id', positional: true, type: 'string', required: true, help: 'Tweet numeric ID (e.g. 1234567890) or full status URL' },
106
106
  { name: 'limit', type: 'int', default: 50 },
@@ -141,7 +141,7 @@ cli({
141
141
  domain: 'x.com',
142
142
  strategy: Strategy.COOKIE,
143
143
  browser: true,
144
- browserSession: { reuse: 'site' },
144
+ siteSession: 'persistent',
145
145
  args: [
146
146
  {
147
147
  name: 'type',
@@ -17,7 +17,7 @@ cli({
17
17
  domain: 'x.com',
18
18
  strategy: Strategy.COOKIE,
19
19
  browser: true,
20
- browserSession: { reuse: 'site' },
20
+ siteSession: 'persistent',
21
21
  args: [
22
22
  { name: 'limit', type: 'int', default: 20, help: 'Number of trends to show' },
23
23
  ],
@@ -149,7 +149,7 @@ cli({
149
149
  domain: 'x.com',
150
150
  strategy: Strategy.COOKIE,
151
151
  browser: true,
152
- browserSession: { reuse: 'site' },
152
+ siteSession: 'persistent',
153
153
  args: [
154
154
  { name: 'username', type: 'string', positional: true, required: true, help: 'Twitter screen name (with or without @)' },
155
155
  { name: 'limit', type: 'int', default: 20, help: 'Max tweets to return' },
@@ -305,7 +305,7 @@ export const askCommand = cli({
305
305
  domain: YUANBAO_DOMAIN,
306
306
  strategy: Strategy.COOKIE,
307
307
  browser: true,
308
- browserSession: { reuse: 'site' },
308
+ siteSession: 'persistent',
309
309
  navigateBefore: false,
310
310
  defaultFormat: 'plain',
311
311
  args: [
@@ -18,7 +18,7 @@ cli({
18
18
  domain: YUANBAO_DOMAIN,
19
19
  strategy: Strategy.COOKIE,
20
20
  browser: true,
21
- browserSession: { reuse: 'site' },
21
+ siteSession: 'persistent',
22
22
  navigateBefore: false,
23
23
  args: [
24
24
  {
@@ -17,7 +17,7 @@ cli({
17
17
  domain: YUANBAO_DOMAIN,
18
18
  strategy: Strategy.COOKIE,
19
19
  browser: true,
20
- browserSession: { reuse: 'site' },
20
+ siteSession: 'persistent',
21
21
  navigateBefore: false,
22
22
  args: [
23
23
  { name: 'limit', type: 'int', default: 20, help: 'Max conversations to list (sidebar virtual scroll caps actual count)' },
@@ -55,7 +55,7 @@ export const newCommand = cli({
55
55
  domain: YUANBAO_DOMAIN,
56
56
  strategy: Strategy.COOKIE,
57
57
  browser: true,
58
- browserSession: { reuse: 'site' },
58
+ siteSession: 'persistent',
59
59
  navigateBefore: false,
60
60
  args: [],
61
61
  columns: ['Status', 'Action'],
@@ -14,7 +14,7 @@ cli({
14
14
  domain: YUANBAO_DOMAIN,
15
15
  strategy: Strategy.COOKIE,
16
16
  browser: true,
17
- browserSession: { reuse: 'site' },
17
+ siteSession: 'persistent',
18
18
  navigateBefore: false,
19
19
  args: [],
20
20
  columns: ['Role', 'Text'],
@@ -18,7 +18,7 @@ cli({
18
18
  domain: YUANBAO_DOMAIN,
19
19
  strategy: Strategy.COOKIE,
20
20
  browser: true,
21
- browserSession: { reuse: 'site' },
21
+ siteSession: 'persistent',
22
22
  navigateBefore: false,
23
23
  args: [
24
24
  { name: 'prompt', positional: true, required: true, help: 'Prompt to send to Yuanbao' },
@@ -15,7 +15,7 @@ cli({
15
15
  domain: YUANBAO_DOMAIN,
16
16
  strategy: Strategy.COOKIE,
17
17
  browser: true,
18
- browserSession: { reuse: 'site' },
18
+ siteSession: 'persistent',
19
19
  navigateBefore: false,
20
20
  args: [],
21
21
  columns: ['Status', 'Login', 'Model', 'ModelId', 'AgentId', 'SessionId', 'Url'],
@@ -14,10 +14,12 @@ export declare class BrowserBridge implements IBrowserFactory {
14
14
  get state(): BrowserBridgeState;
15
15
  connect(opts?: {
16
16
  timeout?: number;
17
- workspace?: string;
17
+ session?: string;
18
18
  idleTimeout?: number;
19
19
  contextId?: string;
20
20
  windowMode?: 'foreground' | 'background';
21
+ surface?: 'browser' | 'adapter';
22
+ siteSession?: 'ephemeral' | 'persistent';
21
23
  }): Promise<IPage>;
22
24
  close(): Promise<void>;
23
25
  private _ensureDaemon;
@@ -32,7 +32,9 @@ export class BrowserBridge {
32
32
  try {
33
33
  const contextId = opts.contextId ?? resolveProfileContextId();
34
34
  await this._ensureDaemon(opts.timeout, contextId);
35
- this._page = new Page(opts.workspace, opts.idleTimeout, contextId, opts.windowMode);
35
+ if (!opts.session?.trim())
36
+ throw new Error('Browser session is required');
37
+ this._page = new Page(opts.session.trim(), opts.idleTimeout, contextId, opts.windowMode, opts.surface, opts.siteSession);
36
38
  this._state = 'connected';
37
39
  return this._page;
38
40
  }
@@ -23,11 +23,13 @@ export declare class CDPBridge implements IBrowserFactory {
23
23
  private _eventListeners;
24
24
  connect(opts?: {
25
25
  timeout?: number;
26
- workspace?: string;
26
+ session?: string;
27
27
  cdpEndpoint?: string;
28
28
  contextId?: string;
29
29
  idleTimeout?: number;
30
30
  windowMode?: 'foreground' | 'background';
31
+ surface?: 'browser' | 'adapter';
32
+ siteSession?: 'ephemeral' | 'persistent';
31
33
  }): Promise<IPage>;
32
34
  close(): Promise<void>;
33
35
  send(method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
@@ -3,20 +3,20 @@
3
3
  *
4
4
  * Provides a typed send() function that posts a Command and returns a Result.
5
5
  */
6
- import type { BrowserSessionInfo } from '../types.js';
7
6
  export interface DaemonCommand {
8
7
  id: string;
9
- action: 'exec' | 'navigate' | 'tabs' | 'cookies' | 'screenshot' | 'close-window' | 'sessions' | 'set-file-input' | 'insert-text' | 'bind' | 'network-capture-start' | 'network-capture-read' | 'wait-download' | 'cdp' | 'frames';
8
+ action: 'exec' | 'navigate' | 'tabs' | 'cookies' | 'screenshot' | 'close-window' | 'set-file-input' | 'insert-text' | 'bind' | 'network-capture-start' | 'network-capture-read' | 'wait-download' | 'cdp' | 'frames';
10
9
  /** Target page identity (targetId). Cross-layer contract with the extension. */
11
10
  page?: string;
12
11
  code?: string;
13
- workspace?: string;
12
+ session?: string;
13
+ surface?: 'browser' | 'adapter';
14
+ /** Adapter site session lifecycle. Persistent site sessions do not idle-expire. */
15
+ siteSession?: 'ephemeral' | 'persistent';
14
16
  url?: string;
15
17
  op?: string;
16
18
  index?: number;
17
19
  domain?: string;
18
- matchDomain?: string;
19
- matchPathPrefix?: string;
20
20
  format?: 'png' | 'jpeg';
21
21
  quality?: number;
22
22
  fullPage?: boolean;
@@ -38,10 +38,8 @@ export interface DaemonCommand {
38
38
  cdpParams?: Record<string, unknown>;
39
39
  /** Window foreground/background policy for owned Browser Bridge containers. */
40
40
  windowMode?: 'foreground' | 'background';
41
- /** Custom idle timeout in seconds for this workspace session. Overrides the default. */
41
+ /** Custom idle timeout in seconds for this session. Overrides the default. */
42
42
  idleTimeout?: number;
43
- /** Explicitly allow navigation inside a borrowed bound tab. */
44
- allowBoundNavigation?: boolean;
45
43
  /** Frame index for cross-frame operations (0-based, from 'frames' action) */
46
44
  frameIndex?: number;
47
45
  /** Browser profile/context to route the command to. */
@@ -129,11 +127,6 @@ export declare function sendCommandFull(action: DaemonCommand['action'], params?
129
127
  data: unknown;
130
128
  page?: string;
131
129
  }>;
132
- export declare function listSessions(opts?: {
133
- contextId?: string;
134
- }): Promise<BrowserSessionInfo[]>;
135
- export declare function bindTab(workspace: string, opts?: {
136
- matchDomain?: string;
137
- matchPathPrefix?: string;
130
+ export declare function bindTab(session: string, opts?: {
138
131
  contextId?: string;
139
132
  }): Promise<unknown>;
@@ -146,10 +146,6 @@ export async function sendCommandFull(action, params = {}) {
146
146
  const result = await sendCommandRaw(action, params);
147
147
  return { data: result.data, page: result.page };
148
148
  }
149
- export async function listSessions(opts) {
150
- const result = await sendCommand('sessions', { ...(opts?.contextId && { contextId: opts.contextId }) });
151
- return Array.isArray(result) ? result : [];
152
- }
153
- export async function bindTab(workspace, opts = {}) {
154
- return sendCommand('bind', { workspace, ...opts });
149
+ export async function bindTab(session, opts = {}) {
150
+ return sendCommand('bind', { session, surface: 'browser', ...opts });
155
151
  }