opencode-pair-autonomy 1.0.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 (128) hide show
  1. package/README.md +90 -0
  2. package/bin/opencode-pair-autonomy.js +20 -0
  3. package/dist/__tests__/comment-guard.test.d.ts +1 -0
  4. package/dist/__tests__/config.test.d.ts +1 -0
  5. package/dist/__tests__/learning.test.d.ts +1 -0
  6. package/dist/__tests__/plan-mode.test.d.ts +1 -0
  7. package/dist/agents.d.ts +2 -0
  8. package/dist/cli.d.ts +1 -0
  9. package/dist/cli.js +15351 -0
  10. package/dist/commands.d.ts +2 -0
  11. package/dist/config.d.ts +3 -0
  12. package/dist/hooks/comment-guard.d.ts +15 -0
  13. package/dist/hooks/file-edited.d.ts +7 -0
  14. package/dist/hooks/index.d.ts +46 -0
  15. package/dist/hooks/post-tool-use.d.ts +5 -0
  16. package/dist/hooks/pre-compact.d.ts +4 -0
  17. package/dist/hooks/pre-tool-use.d.ts +5 -0
  18. package/dist/hooks/prompt-refiner.d.ts +38 -0
  19. package/dist/hooks/runtime.d.ts +91 -0
  20. package/dist/hooks/sdk.d.ts +6 -0
  21. package/dist/hooks/session-end.d.ts +4 -0
  22. package/dist/hooks/session-start.d.ts +19 -0
  23. package/dist/hooks/stop.d.ts +5 -0
  24. package/dist/i18n/index.d.ts +15 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.js +17823 -0
  27. package/dist/installer.d.ts +12 -0
  28. package/dist/learning/analyzer.d.ts +15 -0
  29. package/dist/learning/store.d.ts +4 -0
  30. package/dist/learning/types.d.ts +32 -0
  31. package/dist/mcp.d.ts +4 -0
  32. package/dist/project-facts.d.ts +8 -0
  33. package/dist/prompts/coordinator.d.ts +2 -0
  34. package/dist/prompts/shared.d.ts +5 -0
  35. package/dist/prompts/workers.d.ts +8 -0
  36. package/dist/types.d.ts +81 -0
  37. package/dist/utils.d.ts +6 -0
  38. package/examples/opencode-pair-autonomy.jsonc +35 -0
  39. package/examples/opencode.jsonc +17 -0
  40. package/package.json +103 -0
  41. package/vendor/mcp/pg-mcp/README.md +91 -0
  42. package/vendor/mcp/pg-mcp/config.example.json +26 -0
  43. package/vendor/mcp/pg-mcp/config.json +15 -0
  44. package/vendor/mcp/pg-mcp/package-lock.json +1288 -0
  45. package/vendor/mcp/pg-mcp/package.json +18 -0
  46. package/vendor/mcp/pg-mcp/src/config.js +71 -0
  47. package/vendor/mcp/pg-mcp/src/db.js +85 -0
  48. package/vendor/mcp/pg-mcp/src/index.js +203 -0
  49. package/vendor/mcp/pg-mcp/src/sqlGuard.js +75 -0
  50. package/vendor/mcp/pg-mcp/src/tools.js +89 -0
  51. package/vendor/mcp/ssh-mcp/README.md +46 -0
  52. package/vendor/mcp/ssh-mcp/config.example.json +23 -0
  53. package/vendor/mcp/ssh-mcp/config.json +6 -0
  54. package/vendor/mcp/ssh-mcp/package-lock.json +1142 -0
  55. package/vendor/mcp/ssh-mcp/package.json +18 -0
  56. package/vendor/mcp/ssh-mcp/src/config.js +140 -0
  57. package/vendor/mcp/ssh-mcp/src/index.js +130 -0
  58. package/vendor/mcp/ssh-mcp/src/ssh.js +163 -0
  59. package/vendor/mcp/sudo-mcp/README.md +51 -0
  60. package/vendor/mcp/sudo-mcp/config.example.json +28 -0
  61. package/vendor/mcp/sudo-mcp/config.json +28 -0
  62. package/vendor/mcp/sudo-mcp/package-lock.json +1145 -0
  63. package/vendor/mcp/sudo-mcp/package.json +18 -0
  64. package/vendor/mcp/sudo-mcp/src/config.js +57 -0
  65. package/vendor/mcp/sudo-mcp/src/index.js +267 -0
  66. package/vendor/mcp/sudo-mcp/src/runner.js +168 -0
  67. package/vendor/mcp/web-agent-mcp/package-lock.json +2886 -0
  68. package/vendor/mcp/web-agent-mcp/package.json +28 -0
  69. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/adapter.ts +335 -0
  70. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/auth-heuristics.ts +324 -0
  71. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/launcher.ts +1340 -0
  72. package/vendor/mcp/web-agent-mcp/src/config/env.ts +107 -0
  73. package/vendor/mcp/web-agent-mcp/src/core/action-flow.ts +82 -0
  74. package/vendor/mcp/web-agent-mcp/src/core/artifact-store.ts +109 -0
  75. package/vendor/mcp/web-agent-mcp/src/core/errors.ts +108 -0
  76. package/vendor/mcp/web-agent-mcp/src/core/observation-flow.ts +38 -0
  77. package/vendor/mcp/web-agent-mcp/src/core/policy-engine.ts +113 -0
  78. package/vendor/mcp/web-agent-mcp/src/core/retry-policy.ts +42 -0
  79. package/vendor/mcp/web-agent-mcp/src/core/session-manager.ts +670 -0
  80. package/vendor/mcp/web-agent-mcp/src/core/session-restart-policy.ts +34 -0
  81. package/vendor/mcp/web-agent-mcp/src/core/task-history.ts +97 -0
  82. package/vendor/mcp/web-agent-mcp/src/index.ts +3 -0
  83. package/vendor/mcp/web-agent-mcp/src/schemas/act.ts +167 -0
  84. package/vendor/mcp/web-agent-mcp/src/schemas/common.ts +56 -0
  85. package/vendor/mcp/web-agent-mcp/src/schemas/observe.ts +214 -0
  86. package/vendor/mcp/web-agent-mcp/src/schemas/page.ts +21 -0
  87. package/vendor/mcp/web-agent-mcp/src/schemas/policy.ts +42 -0
  88. package/vendor/mcp/web-agent-mcp/src/schemas/runtime.ts +21 -0
  89. package/vendor/mcp/web-agent-mcp/src/schemas/session.ts +63 -0
  90. package/vendor/mcp/web-agent-mcp/src/server.ts +75 -0
  91. package/vendor/mcp/web-agent-mcp/src/tools/act/click.ts +68 -0
  92. package/vendor/mcp/web-agent-mcp/src/tools/act/drag.ts +57 -0
  93. package/vendor/mcp/web-agent-mcp/src/tools/act/enter-code.ts +78 -0
  94. package/vendor/mcp/web-agent-mcp/src/tools/act/fill.ts +65 -0
  95. package/vendor/mcp/web-agent-mcp/src/tools/act/pinch.ts +58 -0
  96. package/vendor/mcp/web-agent-mcp/src/tools/act/press.ts +67 -0
  97. package/vendor/mcp/web-agent-mcp/src/tools/act/shared.ts +73 -0
  98. package/vendor/mcp/web-agent-mcp/src/tools/act/swipe.ts +59 -0
  99. package/vendor/mcp/web-agent-mcp/src/tools/act/wait-for.ts +56 -0
  100. package/vendor/mcp/web-agent-mcp/src/tools/act/wheel.ts +59 -0
  101. package/vendor/mcp/web-agent-mcp/src/tools/observe/a11y.ts +60 -0
  102. package/vendor/mcp/web-agent-mcp/src/tools/observe/auth-state.ts +92 -0
  103. package/vendor/mcp/web-agent-mcp/src/tools/observe/boxes.ts +66 -0
  104. package/vendor/mcp/web-agent-mcp/src/tools/observe/console.ts +67 -0
  105. package/vendor/mcp/web-agent-mcp/src/tools/observe/dom.ts +60 -0
  106. package/vendor/mcp/web-agent-mcp/src/tools/observe/network.ts +67 -0
  107. package/vendor/mcp/web-agent-mcp/src/tools/observe/page-state.ts +93 -0
  108. package/vendor/mcp/web-agent-mcp/src/tools/observe/screenshot.ts +73 -0
  109. package/vendor/mcp/web-agent-mcp/src/tools/observe/text.ts +70 -0
  110. package/vendor/mcp/web-agent-mcp/src/tools/observe/wait-for-network.ts +70 -0
  111. package/vendor/mcp/web-agent-mcp/src/tools/page/navigate.ts +59 -0
  112. package/vendor/mcp/web-agent-mcp/src/tools/policy/recommend-observation.ts +40 -0
  113. package/vendor/mcp/web-agent-mcp/src/tools/register-tools.ts +55 -0
  114. package/vendor/mcp/web-agent-mcp/src/tools/runtime/evaluate-js.ts +83 -0
  115. package/vendor/mcp/web-agent-mcp/src/tools/session/close.ts +41 -0
  116. package/vendor/mcp/web-agent-mcp/src/tools/session/create.ts +86 -0
  117. package/vendor/mcp/web-agent-mcp/src/tools/session/restart.ts +72 -0
  118. package/vendor/mcp/web-agent-mcp/src/utils/fs.ts +28 -0
  119. package/vendor/mcp/web-agent-mcp/src/utils/ids.ts +9 -0
  120. package/vendor/mcp/web-agent-mcp/src/utils/time.ts +7 -0
  121. package/vendor/mcp/web-agent-mcp/tsconfig.json +22 -0
  122. package/vendor/skills/editorial-technical-ui/SKILL.md +84 -0
  123. package/vendor/skills/figma-console/SKILL.md +839 -0
  124. package/vendor/skills/go-fiber-postgres/SKILL.md +31 -0
  125. package/vendor/skills/opencode-plugin-dev/SKILL.md +31 -0
  126. package/vendor/skills/rust-media-desktop/SKILL.md +30 -0
  127. package/vendor/skills/vue-vite-ui/SKILL.md +31 -0
  128. package/vendor/skills/web-agent-browser/SKILL.md +140 -0
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: go-fiber-postgres
3
+ description: Build and update Go Fiber services with pgx/PostgreSQL, Redis, MinIO, JWT, validation, and dockerized local-dev patterns used across this workspace.
4
+ ---
5
+
6
+ ## Purpose
7
+ Use this skill for Go backend work in this workspace when the service follows the common Fiber + PostgreSQL stack.
8
+
9
+ ## Use When
10
+ - The repo uses `gofiber/fiber`, `pgx`, Redis, MinIO, JWT, or `go-playground/validator`.
11
+ - The task touches handlers, middleware, service layers, repositories, config, or docker-compose local services.
12
+ - You need to match the house style used by `play-action-backend`, `project-zur`, `go-micro`, or related services.
13
+
14
+ ## Working Method
15
+ 1. Inspect module layout, env loading, and existing route or service registration before changing structure.
16
+ 2. Follow the existing separation between transport, business logic, persistence, and middleware.
17
+ 3. Reuse existing request validation, auth, error response, and config patterns instead of introducing new abstractions.
18
+ 4. Keep SQL and pgx usage explicit, with predictable context handling and defensive error mapping.
19
+ 5. Verify local-dev assumptions against Docker, migrations, and service dependencies before finalizing changes.
20
+
21
+ ## Repo Conventions To Prefer
22
+ - Reuse existing env/config loaders and avoid adding new config systems.
23
+ - Keep handler code thin; move non-trivial logic into services or domain packages when the repo already does that.
24
+ - Preserve current auth and claims handling instead of inventing parallel JWT flows.
25
+ - Match existing database access style, transaction helpers, and migration tooling.
26
+ - Keep object storage and Redis integrations behind the current interfaces when present.
27
+
28
+ ## Guardrails
29
+ - Do not replace Fiber or pgx stack choices unless the user explicitly asks.
30
+ - Do not introduce heavy ORMs when the repo already uses SQL or pgx directly.
31
+ - Do not change public API shapes, auth behavior, or migration history without repo evidence or explicit instruction.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: opencode-plugin-dev
3
+ description: Build and refine OpenCode harness, MCP, plugin, prompt, and agent-tooling code while preserving the repo's existing architecture and conventions.
4
+ ---
5
+
6
+ ## Purpose
7
+ Use this skill for work in `oh-my-pair-code`, related OpenCode plugins, and MCP or agent-tooling repositories in this workspace.
8
+
9
+ ## Use When
10
+ - The task touches prompts, tool wiring, plugin install flows, MCP servers, vendor wrappers, or agent coordination.
11
+ - The repo uses TypeScript with `@modelcontextprotocol/sdk`, Zod, CLI wiring, plugin manifests, or prompt assembly.
12
+ - You need to preserve harness behavior while extending skill usage, tool exposure, or automation flows.
13
+
14
+ ## Working Method
15
+ 1. Inspect existing prompt layers, install flow, and tool contracts before changing behavior.
16
+ 2. Reuse current naming, file placement, and config conventions for plugins, MCP wrappers, and prompts.
17
+ 3. Keep changes additive and architecture-preserving unless the user explicitly requests a structural shift.
18
+ 4. Verify downstream behavior with targeted checks when touching prompt policy, installer logic, or plugin discovery.
19
+ 5. Surface user-visible behavior changes clearly, especially when they affect session restart, tool availability, or external installs.
20
+
21
+ ## Repo Conventions To Prefer
22
+ - Keep prompt policy explicit, concrete, and action-oriented.
23
+ - Prefer dedicated tools over shell when the harness already exposes a safer interface.
24
+ - Preserve non-interactive shell assumptions for installs, git, and automation.
25
+ - Keep MCP schemas and validation tight, with descriptive errors and stable tool names.
26
+ - Avoid hidden magic; make automation behavior legible in code and config.
27
+
28
+ ## Guardrails
29
+ - Do not silently broaden permissions, change security posture, or alter external side effects.
30
+ - Do not add new dependencies when current tooling or plugins already solve the problem.
31
+ - Do not make prompt changes that encourage architecture drift or speculative behavior.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: rust-media-desktop
3
+ description: Build and debug Rust desktop or media apps that use Tokio, Tauri, Slint, async pipelines, and workspace-based crate organization common in this workspace.
4
+ ---
5
+
6
+ ## Purpose
7
+ Use this skill for Rust desktop, torrent, playback, or media-pipeline work across the workspace.
8
+
9
+ ## Use When
10
+ - The repo uses Rust workspaces, Tokio, Tauri, Slint, async streaming, or media-processing crates.
11
+ - The task involves desktop UX, async orchestration, file IO, playback state, or cross-crate boundaries.
12
+ - You need to keep consistency with repos like `turp`, `rqbit`, or `ffmpeg-VideoPlayer-Rust_Slint`.
13
+
14
+ ## Working Method
15
+ 1. Inspect crate boundaries, feature flags, async runtime assumptions, and UI integration points first.
16
+ 2. Preserve existing ownership, error propagation, and tracing patterns.
17
+ 3. Keep UI state transitions explicit and resistant to background task races.
18
+ 4. Prefer small, composable changes across crates instead of collapsing responsibilities into one module.
19
+ 5. Verify platform-specific or media-specific behavior carefully when touching IO, playback, or concurrency.
20
+
21
+ ## Repo Conventions To Prefer
22
+ - Reuse `anyhow`, `thiserror`, `tracing`, and current async primitives when already present.
23
+ - Keep background work cancelable and surface progress or failure states to the UI cleanly.
24
+ - Preserve workspace organization and crate responsibilities.
25
+ - Match existing command, event, and state-management patterns in desktop apps.
26
+
27
+ ## Guardrails
28
+ - Do not replace runtime, UI toolkit, or media pipeline choices without explicit instruction.
29
+ - Do not hide concurrency risks behind broad locks or ad hoc global state.
30
+ - Do not trade correctness for terse code in playback, streaming, or filesystem flows.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: vue-vite-ui
3
+ description: Implement Vue 3 + Vite interfaces with Pinia, Vue Router, i18n, UnoCSS or Tailwind, and admin-style UX patterns common in this workspace.
4
+ ---
5
+
6
+ ## Purpose
7
+ Use this skill for frontend work in the Vue projects across this workspace.
8
+
9
+ ## Use When
10
+ - The repo uses Vue 3, Vite, Pinia, Vue Router, VueUse, Vuelidate, UnoCSS, or Tailwind.
11
+ - The task involves app screens, dashboard flows, forms, navigation, localization, or reusable UI patterns.
12
+ - You need to preserve the established architecture used by `dating-frontend`, `project-zur-panel-front`, or `turp-frontend`.
13
+
14
+ ## Working Method
15
+ 1. Inspect route structure, store layout, composables, and styling system before making UI changes.
16
+ 2. Extend existing components and utilities before creating one-off patterns.
17
+ 3. Preserve form behavior, validation, loading states, and localization hooks already present in the repo.
18
+ 4. Keep responsive behavior intentional on desktop and mobile; avoid flattening hierarchy when layouts collapse.
19
+ 5. Validate copy length, wrapping, and action-group behavior for multilingual interfaces.
20
+
21
+ ## Repo Conventions To Prefer
22
+ - Reuse existing Pinia stores, route guards, and composables.
23
+ - Match the active utility styling system instead of mixing new CSS approaches.
24
+ - Prefer semantic page sections, strong spacing rhythm, and predictable interaction states.
25
+ - Respect existing icon, notification, modal, and table patterns when available.
26
+ - Keep async UI states explicit: idle, loading, success, error, empty.
27
+
28
+ ## Guardrails
29
+ - Do not introduce a new design system when the repo already has one.
30
+ - Do not bypass localization for new user-facing strings.
31
+ - Do not add heavyweight dependencies for simple UI tasks when the current stack already covers them.
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: web-agent-browser
3
+ description: Browser automation with web-agent-mcp. Covers session management, iframe-based auth flows (Apple Developer, Google), 2FA handling, and reliable interaction patterns for complex web applications.
4
+ ---
5
+
6
+ ## Purpose
7
+ Use this skill for browser automation tasks using `web-agent-mcp`. Covers the proven patterns for interacting with embedded iframes, auth flows, 2FA prompts, and dynamic SPAs.
8
+
9
+ ## Use When
10
+ - The task involves web-agent-mcp tool usage (`session_create`, `act_fill`, `observe_screenshot`, etc.)
11
+ - The target page uses iframe-based auth (Apple Developer, Google, etc.)
12
+ - The task involves login, form submission, or multi-step auth flows
13
+ - 2FA / verification code input is needed
14
+
15
+ ---
16
+
17
+ ## Session Lifecycle
18
+
19
+ ```
20
+ 1. session_create → get session_id
21
+ 2. page_navigate (url, wait_until="networkidle")
22
+ 3. observe_screenshot → understand page state
23
+ 4. interact (act_fill / act_click / runtime_evaluate_js)
24
+ 5. session_close when done
25
+ ```
26
+
27
+ Always take a screenshot before interacting. Never guess the page state.
28
+
29
+ ---
30
+
31
+ ## Iframe Handling
32
+
33
+ ### Option A — frame_selector parameter (preferred for same-origin or Playwright-accessible iframes)
34
+ ```
35
+ act_fill:
36
+ selector: "input#account_name_text_field"
37
+ frame_selector: "iframe#aid-auth-widget-iFrame"
38
+ value: "user@example.com"
39
+ ```
40
+ Works for iframes Playwright can access via `frameLocator()`.
41
+
42
+ ### Option B — JavaScript contentDocument injection (fallback for same-session cross-origin iframes)
43
+ Use when `frame_selector` times out. Apple Developer's login iframe (`idmsa.apple.com`) is accessible via `contentDocument` in the same browser session:
44
+
45
+ ```javascript
46
+ // Fill email in Apple iframe
47
+ const iframe = document.querySelector('iframe#aid-auth-widget-iFrame');
48
+ const emailInput = iframe.contentDocument.querySelector('#account_name_text_field');
49
+ emailInput.focus();
50
+ emailInput.value = 'user@example.com';
51
+ emailInput.dispatchEvent(new Event('input', { bubbles: true }));
52
+ emailInput.dispatchEvent(new Event('change', { bubbles: true }));
53
+ ```
54
+
55
+ ```javascript
56
+ // Click Continue / Sign In button
57
+ const iframe = document.querySelector('iframe#aid-auth-widget-iFrame');
58
+ const btn = iframe.contentDocument.querySelector('#sign-in');
59
+ btn.click();
60
+ ```
61
+
62
+ ```javascript
63
+ // Wait and check state
64
+ await new Promise(r => setTimeout(r, 3000));
65
+ const iframe = document.querySelector('iframe#aid-auth-widget-iFrame');
66
+ const passwordField = iframe.contentDocument.querySelector('#password_text_field');
67
+ JSON.stringify({
68
+ passwordVisible: passwordField ? getComputedStyle(passwordField).display !== 'none' : false,
69
+ bodyText: iframe.contentDocument.body.innerText.substring(0, 500)
70
+ });
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Apple Developer Portal Login
76
+
77
+ **URL:** `https://developer.apple.com/account`
78
+
79
+ **Login flow:**
80
+ 1. `page_navigate` → `https://developer.apple.com/account`
81
+ 2. `observe_screenshot` — verify login form visible
82
+ 3. Fill email via JavaScript injection (Option B above) into `#account_name_text_field`
83
+ 4. Click `#sign-in` (Continue button)
84
+ 5. Wait 3s, take screenshot — password field should appear
85
+ 6. Fill password via JavaScript into `#password_text_field`
86
+ 7. Click `#sign-in` (Sign In button)
87
+ 8. Wait 5s, take screenshot — check for 2FA prompt
88
+
89
+ **Iframe selector:** `iframe#aid-auth-widget-iFrame`
90
+ **Email field:** `#account_name_text_field`
91
+ **Password field:** `#password_text_field`
92
+ **Action button:** `#sign-in` (used for both Continue and Sign In)
93
+
94
+ ### 2FA Handling
95
+ After sign-in, Apple shows phone number selection for SMS code:
96
+ 1. `observe_screenshot` to see the 2FA options
97
+ 2. Ask the user which phone number to use if multiple options shown
98
+ 3. Click the desired phone option
99
+ 4. Wait for user to provide the 6-digit code
100
+ 5. Use `act_enter_code` or `runtime_evaluate_js` to fill the code fields
101
+ 6. Submit
102
+
103
+ ---
104
+
105
+ ## General Patterns
106
+
107
+ ### Detecting page state after navigation
108
+ ```javascript
109
+ // Check current URL and key elements
110
+ JSON.stringify({
111
+ url: window.location.href,
112
+ title: document.title,
113
+ hasError: !!document.querySelector('.error, [role="alert"], .alert-error'),
114
+ errorText: document.querySelector('.error, [role="alert"]')?.textContent?.trim()
115
+ });
116
+ ```
117
+
118
+ ### React/Vue input filling (when plain value= doesn't work)
119
+ ```javascript
120
+ const input = document.querySelector('input#myField');
121
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
122
+ nativeInputValueSetter.call(input, 'new value');
123
+ input.dispatchEvent(new Event('input', { bubbles: true }));
124
+ input.dispatchEvent(new Event('change', { bubbles: true }));
125
+ ```
126
+
127
+ ### Checking for login success (Google pattern)
128
+ ```javascript
129
+ document.querySelector('a[href*="SignOutOptions"], [aria-label*="Google Account"], [data-ogsr-up]')?.getAttribute('aria-label') || 'not logged in';
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Guardrails
135
+ - Always `observe_screenshot` before each major action to confirm page state.
136
+ - After clicking Submit/Continue, wait 3-5 seconds before checking result.
137
+ - If `frame_selector` times out, switch to JavaScript `contentDocument` injection.
138
+ - Never store credentials in artifacts or history — use them directly in JS expressions.
139
+ - If 2FA code is needed, always ask the user and wait — do not attempt to bypass.
140
+ - Use `session_close` after completing the task to release the Chrome profile lock.