yunti-browser-runtime 0.1.0

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 (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/bin/yunti-browser-runtime.js +86 -0
  4. package/docs/EXECUTION_PLAN.md +1278 -0
  5. package/docs/INSTALL.md +205 -0
  6. package/docs/PROJECT_INTENT.md +44 -0
  7. package/docs/PROJECT_STATUS.md +263 -0
  8. package/docs/PUBLISHING_BLOCKERS.md +110 -0
  9. package/docs/RELEASE.md +148 -0
  10. package/docs/ROADMAP.md +42 -0
  11. package/docs/SECURITY.md +56 -0
  12. package/docs/TOOL_GUIDE.md +69 -0
  13. package/extension/background.js +55 -0
  14. package/extension/cdp.js +582 -0
  15. package/extension/content.css +9 -0
  16. package/extension/content.js +946 -0
  17. package/extension/manifest.json +35 -0
  18. package/extension/network-monitor.js +140 -0
  19. package/extension/popup.css +66 -0
  20. package/extension/popup.html +30 -0
  21. package/extension/popup.js +55 -0
  22. package/extension/session-manager.js +332 -0
  23. package/extension/settings.js +94 -0
  24. package/extension/tool-handlers.js +1158 -0
  25. package/lib/runtime-paths.js +39 -0
  26. package/mcp/bridge-hub.js +604 -0
  27. package/mcp/http-server.js +326 -0
  28. package/mcp/json-rpc.js +35 -0
  29. package/mcp/memory.js +126 -0
  30. package/mcp/redaction.js +94 -0
  31. package/mcp/server.js +269 -0
  32. package/mcp/tools.js +1092 -0
  33. package/package.json +60 -0
  34. package/scripts/check-package-metadata.js +131 -0
  35. package/scripts/check-published-package.js +113 -0
  36. package/scripts/doctor.js +163 -0
  37. package/scripts/package-extension.js +137 -0
  38. package/scripts/print-config.js +116 -0
  39. package/scripts/release-check.js +472 -0
  40. package/skills/yunti-browser-runtime/SKILL.md +77 -0
@@ -0,0 +1,148 @@
1
+ # Release Runbook
2
+
3
+ This runbook describes the local release checklist for Yunti Browser Runtime.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 22 or newer.
8
+ - A clean local checkout of the project.
9
+ - Access to the public repository that will be listed in `package.json`.
10
+ - npm publish permission for the `yunti-browser-runtime` package name.
11
+
12
+ ## Required External Confirmation
13
+
14
+ Before publishing, confirm the package metadata points to live public URLs:
15
+
16
+ ```bash
17
+ npm run check:metadata
18
+ ```
19
+
20
+ Expected pre-first-release state:
21
+
22
+ - GitHub repository URL returns a non-404 status.
23
+ - GitHub issues URL returns a non-404 status or the issue tracker URL is updated.
24
+ - `npm view yunti-browser-runtime` may return E404 if `0.1.0` is the first release.
25
+
26
+ If the GitHub URLs return 404, do not publish. Create or publicize the repository,
27
+ or update `repository`, `homepage`, and `bugs.url` in `package.json`.
28
+ Detailed remediation options are tracked in
29
+ [`docs/PUBLISHING_BLOCKERS.md`](PUBLISHING_BLOCKERS.md).
30
+
31
+ `npm run check:metadata` exits non-zero when repository, homepage, or issue URLs
32
+ are not publicly reachable. It treats npm E404 as acceptable for a first release
33
+ and reports that state in JSON.
34
+
35
+ ## Local Release Gate
36
+
37
+ Run the consolidated release gate:
38
+
39
+ ```bash
40
+ npm run release:check
41
+ ```
42
+
43
+ This command verifies:
44
+
45
+ - public docs do not contain local/internal residue;
46
+ - public Markdown relative links resolve to existing files;
47
+ - `package.json` and `extension/manifest.json` use the same version;
48
+ - npm bin smoke checks for `yunti-browser-runtime --help` and `--version` pass;
49
+ - Agent config smoke checks for Codex, Claude Code, Cursor, and Cline pass;
50
+ - doctor JSON smoke check returns structured diagnostics and local file checks;
51
+ - all JavaScript files pass `node --check`;
52
+ - the unit test suite passes;
53
+ - `npm pack --json --dry-run` includes required runtime, extension, skill,
54
+ release documentation, and release helper files.
55
+ - `npm run package:extension` creates an extension zip containing only the
56
+ required runtime files.
57
+
58
+ After external package metadata is live, run the stricter prepublish gate:
59
+
60
+ ```bash
61
+ npm run release:prepublish
62
+ ```
63
+
64
+ This runs `npm run check:metadata` first, then `npm run release:check`.
65
+ For the current `dingguangyi0/yunti-browser-runtime` repository metadata, this
66
+ gate is expected to pass before publishing.
67
+
68
+ ## Extension Package
69
+
70
+ Build and inspect the browser extension zip:
71
+
72
+ ```bash
73
+ npm run package:extension
74
+ unzip -l dist/yunti-browser-runtime-extension-0.1.0.zip
75
+ ```
76
+
77
+ `npm run release:check` also validates this zip automatically by parsing the
78
+ actual archive entries.
79
+
80
+ The zip should contain only the extension runtime files:
81
+
82
+ - `background.js`
83
+ - `cdp.js`
84
+ - `content.css`
85
+ - `content.js`
86
+ - `network-monitor.js`
87
+ - `manifest.json`
88
+ - `popup.css`
89
+ - `popup.html`
90
+ - `popup.js`
91
+ - `session-manager.js`
92
+ - `settings.js`
93
+ - `tool-handlers.js`
94
+
95
+ ## Optional Real-Browser Smoke Test
96
+
97
+ Run this when Playwright and Chromium are available:
98
+
99
+ ```bash
100
+ YUNTI_E2E=1 npm run test:e2e
101
+ ```
102
+
103
+ The default `npm test` run skips the real-browser smoke test unless `YUNTI_E2E=1`
104
+ is set.
105
+
106
+ ## Publish
107
+
108
+ After the external URL confirmation and local release gate pass:
109
+
110
+ ```bash
111
+ npm run release:dry-run
112
+ npm run release:publish
113
+ ```
114
+
115
+ The dry-run and publish scripts both run `npm run release:prepublish` before
116
+ publishing. They also pin `https://registry.npmjs.org/` so a local mirror
117
+ registry configuration cannot accidentally receive the release.
118
+ `npm run release:publish` also runs `npm run release:whoami` before publishing.
119
+
120
+ If npm auth is missing, log in first:
121
+
122
+ ```bash
123
+ npm adduser --registry=https://registry.npmjs.org/
124
+ npm run release:whoami
125
+ ```
126
+
127
+ If the npm account requires two-factor authentication for publishing, pass the
128
+ current one-time password to the publish script:
129
+
130
+ ```bash
131
+ npm run release:publish -- --otp=<6-digit-code>
132
+ ```
133
+
134
+ Alternatively, publish with a granular access token that has package publish
135
+ permission and bypass 2FA enabled.
136
+
137
+ After publishing, verify:
138
+
139
+ ```bash
140
+ npm run release:verify-published
141
+ ```
142
+
143
+ ## Post-Release
144
+
145
+ - Re-run `npm run doctor` in a fresh local setup.
146
+ - Re-run `npm run print-config -- --agent codex --human`.
147
+ - Load or package the extension from the published source.
148
+ - Update `docs/PROJECT_STATUS.md` with the release result and published version.
@@ -0,0 +1,42 @@
1
+ # Roadmap
2
+
3
+ ## Phase 0: Scaffold
4
+
5
+ - Create standalone repository structure.
6
+ - Document project intent and status.
7
+ - Define local-first architecture.
8
+
9
+ ## Phase 1: Local Runtime MVP
10
+
11
+ - MCP stdio server starts a local bridge automatically.
12
+ - Browser extension registers local tabs with the bridge.
13
+ - Agent can list browser targets.
14
+ - Agent can inspect a page snapshot.
15
+ - Agent can send CDP commands through a stable browser route.
16
+ - Agent can click, type, navigate, screenshot, and read network/console logs.
17
+
18
+ ## Phase 2: Install Experience
19
+
20
+ - Add `npm run doctor`.
21
+ - Add `npm run package:extension`.
22
+ - Add MCP config printer.
23
+ - Add clear Chrome/Edge extension loading instructions.
24
+
25
+ ## Phase 3: Reliability
26
+
27
+ - Add session TTL and fast stale-session failures.
28
+ - Add better error messages for wrong parameter combinations.
29
+ - Add smoke tests for bridge, MCP, and extension message contracts.
30
+
31
+ ## Phase 4: Productization
32
+
33
+ - Rename tools to `yunti_*`.
34
+ - Keep compatibility aliases only when useful.
35
+ - Publish an npm package.
36
+ - Prepare public docs and examples.
37
+
38
+ ## Future: Remote Mode
39
+
40
+ Remote multi-user operation is intentionally out of the first release. It should
41
+ be designed as a separate server layer on top of the local runtime, not mixed
42
+ into the local core.
@@ -0,0 +1,56 @@
1
+ # Security, Permissions, And Privacy Notes
2
+
3
+ ## Current Boundary
4
+
5
+ The first release is local single-user software:
6
+
7
+ - bridge binds to `127.0.0.1` by default;
8
+ - bridge routes require `x-yunti-browser-token` except limited `/health`;
9
+ - CORS only echoes local debug origins and browser-extension origins by default;
10
+ - extension talks to the local bridge;
11
+ - MCP tools default to `userId=local`;
12
+ - no remote relay is part of the documented install path.
13
+
14
+ ## Data Handling
15
+
16
+ - Cookies and raw authorization headers are not returned by network tools.
17
+ - Network URLs, headers, request bodies, and console messages are sanitized.
18
+ - Learning memory is stored under `~/.yunti_agent/users/{userId}/memory`.
19
+ - The content script does not call product-specific login APIs.
20
+
21
+ ## Browser Permissions
22
+
23
+ The extension uses browser permissions required for automation:
24
+
25
+ - `tabs` for tab inventory and activation;
26
+ - `debugger` for CDP commands;
27
+ - `storage` for local bridge URL, token, user, and page-match settings;
28
+ - `webRequest` for sanitized network observations;
29
+ - `activeTab` for visible-tab capture fallback paths.
30
+
31
+ The extension currently declares broad `http://*/*` and `https://*/*` host
32
+ access so it can register and operate arbitrary local user-selected pages. It
33
+ also declares localhost bridge access for the local HTTP bridge. A narrower
34
+ allowlist can be configured in the extension popup with page match patterns, and
35
+ store-distributed releases should re-review whether broad host permissions are
36
+ still appropriate for the intended audience.
37
+
38
+ Users should only load the extension from a trusted local checkout.
39
+
40
+ ## Privacy Notes
41
+
42
+ - The runtime is local-first and does not send browser observations to a Yunti
43
+ hosted service.
44
+ - Raw cookies, authorization headers, passwords, and token-like fields are not
45
+ returned by the documented tools.
46
+ - Learning memory is local filesystem data and should not contain secrets.
47
+ - Agents should summarize sensitive-looking output instead of repeating it.
48
+
49
+ ## Not Yet Implemented
50
+
51
+ - Signed extension release package.
52
+ - Remote multi-user isolation layer.
53
+ - Per-tool allow/deny policy.
54
+
55
+ Remote deployment must be designed separately and should not reuse the local
56
+ single-user defaults without an authentication and ownership model.
@@ -0,0 +1,69 @@
1
+ # Tool Guide
2
+
3
+ ## Agent Workflow
4
+
5
+ 1. Call `yunti_get_tool_usage_hints` when unsure about parameters or routing.
6
+ 2. Call `yunti_list_browser_targets` to understand the live browser state.
7
+ 3. Keep the returned `browserSessionId` for follow-up page/CDP tools.
8
+ 4. If the session becomes stale, call `yunti_list_browser_targets` again and
9
+ retry with the latest route.
10
+ 5. For multi-step page work, prefer one stable `browserSessionId` throughout the
11
+ task.
12
+
13
+ Sessions expire when the extension stops polling the local bridge. Stale-session
14
+ errors include a reason and recovery hint; do not keep retrying an expired id.
15
+
16
+ ## Core Tools
17
+
18
+ - `yunti_list_browser_targets`: canonical live inventory for tabs and targets.
19
+ - `yunti_list_pages`: compatibility alias for the same live inventory.
20
+ - `yunti_get_page_snapshot`: lightweight page state and visible context.
21
+ - `yunti_take_snapshot`: element-oriented snapshot for uid-based actions.
22
+ - `yunti_click`, `yunti_fill`, `yunti_hover`: common DOM actions.
23
+ - `yunti_cdp_send_command`: low-level CDP access routed through the extension.
24
+ - `yunti_get_network_log`, `yunti_list_network_requests`: sanitized network
25
+ observations.
26
+ - `yunti_list_console_messages`: console diagnostics.
27
+ - `yunti_remember_learning`, `yunti_get_learning_memory`: local agent memory.
28
+
29
+ ## Routing Rules
30
+
31
+ - Standalone local mode defaults to `userId=local`.
32
+ - Agents do not need to pass `userId` unless they intentionally override
33
+ `YUNTI_BROWSER_USER_ID`.
34
+ - `browserSessionId` identifies a registered browser page route.
35
+ - `browserSessionId` expires without extension heartbeat; refresh live inventory
36
+ when a stale-session error appears.
37
+ - New tabs can return a new `browserSessionId`; use the returned value for
38
+ follow-up calls on that tab.
39
+ - Raw `targetId` or `tabId` is for CDP/tab operations, not a replacement for
40
+ `browserSessionId`.
41
+
42
+ ## CDP Rules
43
+
44
+ - Do not run CDP method names in a shell.
45
+ - Use `yunti_cdp_send_command` with `method` and optional `params`.
46
+ - `params` must be an object when provided.
47
+ - For `Target.activateTarget` or `Target.closeTarget`, pass top-level `tabId`
48
+ or `targetId` with a valid `browserSessionId`.
49
+ - Use `Runtime.evaluate` for JavaScript evaluation, but keep related multi-step
50
+ work in one eval when page state must stay in the same execution context.
51
+
52
+ ## Parameter Rules
53
+
54
+ - `yunti_click` and `yunti_hover` require a `uid`, a `selector`, or both `x`
55
+ and `y`; use `yunti_take_snapshot` to get stable uids.
56
+ - `yunti_fill` requires `value` and either `uid` or `selector`; it does not
57
+ support coordinate-only targeting.
58
+ - `yunti_close_page` closes by `browserSessionId`; to close by raw `tabId` or
59
+ `targetId`, use `yunti_cdp_send_command` with `Target.closeTarget`.
60
+ - `yunti_forget_learning_memory` requires `id`, or `all=true` plus
61
+ `confirmed=true` when deleting every memory.
62
+
63
+ ## Safety Rules
64
+
65
+ - Read-only inspection is allowed by default.
66
+ - Destructive, financial, credential, upload, or submit actions should require
67
+ explicit user confirmation in the agent workflow.
68
+ - Tool outputs redact likely cookies, authorization headers, passwords, and
69
+ token-like values.
@@ -0,0 +1,55 @@
1
+ import { createCdpController } from "./cdp.js"
2
+ import { installNetworkMonitor } from "./network-monitor.js"
3
+ import { createSessionManager } from "./session-manager.js"
4
+ import { createToolDispatcher } from "./tool-handlers.js"
5
+
6
+ const sessionManager = createSessionManager()
7
+ const {
8
+ forwardConsoleEvent,
9
+ postBridge,
10
+ pollers,
11
+ sessionsByTab,
12
+ startPolling,
13
+ } = sessionManager
14
+
15
+ const cdp = createCdpController({
16
+ sessionsByTab,
17
+ pollers,
18
+ postBridge,
19
+ startPolling,
20
+ forwardConsoleEvent,
21
+ })
22
+
23
+ const { detachCdpTab, installCdpEventForwarder } = cdp
24
+ const { executeToolRequest } = createToolDispatcher({
25
+ sessionsByTab,
26
+ pollers,
27
+ postBridge,
28
+ startPolling,
29
+ cdp,
30
+ })
31
+
32
+ sessionManager.setToolRequestHandler(executeToolRequest)
33
+
34
+ installNetworkMonitor({
35
+ sessionsByTab,
36
+ postBridge,
37
+ getPlatformMatches: sessionManager.getPlatformMatches,
38
+ })
39
+ installCdpEventForwarder()
40
+
41
+ chrome.tabs.onRemoved.addListener((tabId) => {
42
+ void detachCdpTab(tabId, null, "tab_removed").catch(() => {})
43
+ sessionManager.forgetTab(tabId)
44
+ })
45
+
46
+ chrome.tabs.onActivated.addListener(({ tabId }) => {
47
+ void sessionManager.activateTab(tabId)
48
+ })
49
+
50
+ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
51
+ void sessionManager.handleMessage(message, sender).then(sendResponse, (error) =>
52
+ sendResponse({ ok: false, error: error?.message || String(error) })
53
+ )
54
+ return true
55
+ })