lazycodex-ai 5.0.0-beta.89 → 5.0.0-beta.90
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.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.ru.md +1 -1
- package/README.zh-cn.md +1 -1
- package/dist/cli/config-manager/refresh-opencode-plugin-sandbox.d.ts +31 -0
- package/dist/cli/doctor/checks/tui-plugin-config.d.ts +11 -0
- package/dist/cli/index.js +1661 -859
- package/dist/cli/install-native/index.d.ts +9 -1
- package/dist/cli/install-native/legacy-omo-bin.d.ts +27 -0
- package/dist/cli/install-native/offer-native-setup.d.ts +31 -0
- package/dist/cli/install-native/omo-bin-test-fixtures.d.ts +35 -0
- package/dist/cli/install-native/plan.d.ts +8 -0
- package/dist/cli/install-native/repair-legacy-omo-bin.d.ts +26 -0
- package/dist/cli/install-native/run-native-install.d.ts +11 -1
- package/dist/cli/install-native/verify-omo-command.d.ts +22 -0
- package/dist/cli/native-edition-hint.d.ts +2 -2
- package/dist/cli-node/index.js +1661 -859
- package/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +5 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +5 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +7 -3
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +7 -3
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -2
- package/packages/omo-codex/plugin/skills/browser/SKILL.md +8 -1
- package/packages/omo-codex/plugin/skills/browser/references/install.md +34 -5
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +2 -2
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +14 -3
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +13 -1
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +7 -3
- package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +63 -0
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +37 -25
- package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +187 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +66 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/cli-support.mjs +102 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +162 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-lite.mjs +204 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/design-spec.mjs +161 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/entities.mjs +39 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/entry-guard.mjs +21 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/format-extract-css.mjs +122 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/format-extract.mjs +229 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-figures.mjs +173 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-layout.mjs +146 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +167 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-structure.mjs +118 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-text.mjs +190 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +239 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/layout-probe.mjs +83 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +250 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/repair-tracker.mjs +171 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +214 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools.mjs +61 -0
- package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +3 -1
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +11 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -2
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +20 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
- package/packages/prompts-core/prompts/ultrawork/codex.md +7 -3
- package/packages/shared-skills/skills/browser/SKILL.md +8 -1
- package/packages/shared-skills/skills/browser/references/install.md +34 -5
- package/packages/shared-skills/skills/browser/runtime/omowright/index.js +2 -2
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +14 -3
- package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +13 -1
- package/packages/shared-skills/skills/ulw-research/AGENTS.md +63 -0
- package/packages/shared-skills/skills/ulw-research/SKILL.md +38 -26
- package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +187 -0
- package/packages/shared-skills/skills/ulw-research/references/report-gates.md +66 -0
- package/packages/shared-skills/skills/ulw-research/scripts/cli-support.mjs +102 -0
- package/packages/shared-skills/skills/ulw-research/scripts/cli-support.test.ts +88 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +162 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +177 -0
- package/packages/shared-skills/skills/ulw-research/scripts/css-lite.mjs +204 -0
- package/packages/shared-skills/skills/ulw-research/scripts/css-lite.test.ts +159 -0
- package/packages/shared-skills/skills/ulw-research/scripts/design-spec.mjs +161 -0
- package/packages/shared-skills/skills/ulw-research/scripts/design-spec.test.ts +162 -0
- package/packages/shared-skills/skills/ulw-research/scripts/entities.mjs +39 -0
- package/packages/shared-skills/skills/ulw-research/scripts/entry-guard.mjs +21 -0
- package/packages/shared-skills/skills/ulw-research/scripts/format-extract-css.mjs +122 -0
- package/packages/shared-skills/skills/ulw-research/scripts/format-extract.mjs +229 -0
- package/packages/shared-skills/skills/ulw-research/scripts/format-extract.test.ts +243 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-figures.mjs +173 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-layout.mjs +146 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-layout.test.ts +236 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +167 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.test.ts +265 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-structure.mjs +118 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-text.mjs +190 -0
- package/packages/shared-skills/skills/ulw-research/scripts/glossary-vocabulary.test.ts +43 -0
- package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +239 -0
- package/packages/shared-skills/skills/ulw-research/scripts/html-lite.test.ts +191 -0
- package/packages/shared-skills/skills/ulw-research/scripts/layout-probe.mjs +83 -0
- package/packages/shared-skills/skills/ulw-research/scripts/layout-probe.test.ts +89 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +250 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome.test.ts +281 -0
- package/packages/shared-skills/skills/ulw-research/scripts/repair-tracker.mjs +171 -0
- package/packages/shared-skills/skills/ulw-research/scripts/repair-tracker.test.ts +246 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +214 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +61 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +213 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/assets/figure-1.svg +1 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/bad-report.html +44 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/boxes.json +90 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/design-spec.md +29 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/good-report.html +57 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/reference-report.html +86 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/reference.md +23 -0
- package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +3 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-tool-use",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Matching Project Rules",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook post-tool-use-spawn",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Recording Spawn Admission",
|
|
12
12
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook post-tool-use-spawn"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Enforcing Unlimited Goal Budget",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use-spawn",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Guarding Ulw-Loop Spawns",
|
|
12
12
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use-spawn"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook pre-tool-use",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Recommending Git Bash MCP",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook pre-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/scripts/auto-update.mjs\" hook session-start",
|
|
9
9
|
"timeout": 15,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Auto Update",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\scripts\\auto-update.mjs\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
|
|
9
9
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
|
|
10
10
|
"timeout": 30,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Loading Project Rules",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/telemetry/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 15,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Recording Session Telemetry",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\telemetry\\dist\\cli.js\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-execute-continuation/dist/cli.js\" hook stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Ulw-Execute Continuation",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-execute-continuation\\dist\\cli.js\" hook stop"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Ulw-Loop Resume",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook stop"
|
|
12
12
|
}
|
|
13
13
|
]
|
package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Verifying LazyCodex Executor Evidence",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lazycodex-executor-verify\\dist\\cli.js\" hook subagent-stop"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ultrawork/dist/cli.js\" hook user-prompt-submit",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Ultrawork Trigger",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ultrawork\\dist\\cli.js\" hook user-prompt-submit"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook user-prompt-submit",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Checking Ulw-Loop Steering",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook user-prompt-submit"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook user-prompt-submit",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.90) Loading Project Rules",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook user-prompt-submit"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisyphuslabs/omo-codex-plugin",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.90",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@sisyphuslabs/omo-codex-plugin",
|
|
9
|
-
"version": "5.0.0-beta.
|
|
9
|
+
"version": "5.0.0-beta.90",
|
|
10
10
|
"workspaces": [
|
|
11
11
|
"components/comment-checker",
|
|
12
12
|
"components/git-bash",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"components/comment-checker": {
|
|
97
97
|
"name": "@code-yeongyu/codex-comment-checker",
|
|
98
|
-
"version": "5.0.0-beta.
|
|
98
|
+
"version": "5.0.0-beta.90",
|
|
99
99
|
"license": "MIT",
|
|
100
100
|
"bin": {
|
|
101
101
|
"omo-comment-checker": "dist/cli.js"
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
},
|
|
118
118
|
"components/git-bash": {
|
|
119
119
|
"name": "@sisyphuslabs/codex-git-bash-hook",
|
|
120
|
-
"version": "5.0.0-beta.
|
|
120
|
+
"version": "5.0.0-beta.90",
|
|
121
121
|
"bin": {
|
|
122
122
|
"omo-git-bash-hook": "dist/cli.js"
|
|
123
123
|
},
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
},
|
|
132
132
|
"components/lazycodex-executor-verify": {
|
|
133
133
|
"name": "@code-yeongyu/codex-lazycodex-executor-verify",
|
|
134
|
-
"version": "5.0.0-beta.
|
|
134
|
+
"version": "5.0.0-beta.90",
|
|
135
135
|
"license": "MIT",
|
|
136
136
|
"bin": {
|
|
137
137
|
"lazycodex-executor-verify": "dist/cli.js"
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
},
|
|
150
150
|
"components/lsp": {
|
|
151
151
|
"name": "@code-yeongyu/codex-lsp",
|
|
152
|
-
"version": "5.0.0-beta.
|
|
152
|
+
"version": "5.0.0-beta.90",
|
|
153
153
|
"license": "MIT",
|
|
154
154
|
"dependencies": {
|
|
155
155
|
"@code-yeongyu/lsp-daemon": "file:../../../../lsp-daemon",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
},
|
|
172
172
|
"components/rules": {
|
|
173
173
|
"name": "@code-yeongyu/codex-rules",
|
|
174
|
-
"version": "5.0.0-beta.
|
|
174
|
+
"version": "5.0.0-beta.90",
|
|
175
175
|
"license": "MIT",
|
|
176
176
|
"dependencies": {
|
|
177
177
|
"picomatch": "^4.0.7"
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
},
|
|
195
195
|
"components/teammode": {
|
|
196
196
|
"name": "@sisyphuslabs/codex-teammode",
|
|
197
|
-
"version": "5.0.0-beta.
|
|
197
|
+
"version": "5.0.0-beta.90",
|
|
198
198
|
"devDependencies": {
|
|
199
199
|
"@types/node": "^26.6.2",
|
|
200
200
|
"@vitest/coverage-v8": "5.0.1",
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
},
|
|
209
209
|
"components/telemetry": {
|
|
210
210
|
"name": "@code-yeongyu/codex-telemetry",
|
|
211
|
-
"version": "5.0.0-beta.
|
|
211
|
+
"version": "5.0.0-beta.90",
|
|
212
212
|
"license": "MIT",
|
|
213
213
|
"bin": {
|
|
214
214
|
"omo-telemetry": "dist/cli.js"
|
|
@@ -227,7 +227,7 @@
|
|
|
227
227
|
},
|
|
228
228
|
"components/ultrawork": {
|
|
229
229
|
"name": "@code-yeongyu/codex-ultrawork",
|
|
230
|
-
"version": "5.0.0-beta.
|
|
230
|
+
"version": "5.0.0-beta.90",
|
|
231
231
|
"license": "MIT",
|
|
232
232
|
"bin": {
|
|
233
233
|
"omo-ultrawork": "dist/cli.js"
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
},
|
|
247
247
|
"components/ulw-execute-continuation": {
|
|
248
248
|
"name": "@code-yeongyu/codex-ulw-execute-continuation",
|
|
249
|
-
"version": "5.0.0-beta.
|
|
249
|
+
"version": "5.0.0-beta.90",
|
|
250
250
|
"license": "MIT",
|
|
251
251
|
"bin": {
|
|
252
252
|
"omo-ulw-execute-continuation": "dist/cli.js"
|
|
@@ -264,7 +264,7 @@
|
|
|
264
264
|
},
|
|
265
265
|
"components/ulw-loop": {
|
|
266
266
|
"name": "@code-yeongyu/codex-ulw-loop",
|
|
267
|
-
"version": "5.0.0-beta.
|
|
267
|
+
"version": "5.0.0-beta.90",
|
|
268
268
|
"license": "MIT",
|
|
269
269
|
"bin": {
|
|
270
270
|
"omo-ulw-loop": "dist/cli.js",
|
|
@@ -171,8 +171,8 @@ private logs, or PII; summarize with lengths, hashes, and short non-sensitive
|
|
|
171
171
|
prefixes when identity is needed.
|
|
172
172
|
`;
|
|
173
173
|
|
|
174
|
-
const ulwResearchOriginalDeliveryGates = "
|
|
175
|
-
const ulwResearchCodexDeliveryGate = "
|
|
174
|
+
const ulwResearchOriginalDeliveryGates = "Reading the source markup is not visual QA; inspect the pixels.\n4. **Proofread gate \u2014 `task(category=\"writing\", ...)`.** Hand the final text to a dedicated `writing` worker whose only job is language: grammar, spelling, punctuation, terminology consistency, and whether the prose reads NATIVELY in the report's own language. It proofreads only and never composes. It returns a defect list; fix every item and re-run the gate on the delta. Deliver only on a clean pass \u2014 this gate runs BEFORE the first delivery, not after the user finds the typo.";
|
|
175
|
+
const ulwResearchCodexDeliveryGate = "Reading the source markup is not visual QA; inspect the pixels.";
|
|
176
176
|
|
|
177
177
|
export const ulwExecuteOriginalCompletion = [
|
|
178
178
|
"When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are complete:",
|
|
@@ -32,9 +32,16 @@ node "<skill-root>/scripts/browser-doctor.mjs" --json
|
|
|
32
32
|
| State | Meaning | Next |
|
|
33
33
|
|---|---|---|
|
|
34
34
|
| `ready` | CLI, daemon and a connected browser | start a session |
|
|
35
|
-
| `no-cli` / `no-daemon` / `no-extension` | something is missing | `node "<skill-root>/scripts/browser-install.mjs"` prepares everything it can
|
|
35
|
+
| `no-cli` / `no-daemon` / `no-extension` | something is missing | `node "<skill-root>/scripts/browser-install.mjs" [--browser=<id>]` prepares everything it can for **the browser the user uses**, then prints the **single** step only the user can do (relaunch that browser and click **Enable**); relay it verbatim, wait, re-run the doctor |
|
|
36
|
+
| `choose-browser` | the signals do not single out one browser (Safari/Firefox default, an idle default while another browser runs, several in use) | nothing was installed; take the browser from memory or ask the user, then `browser-install.mjs --browser=<id>` |
|
|
36
37
|
| `no-browser-support` | no Chromium-family profile on this machine | say so and stop |
|
|
37
38
|
|
|
39
|
+
**Install into the browser the user actually uses, never into whatever happens to be on disk.** Before
|
|
40
|
+
installing, check your memory for the user's browser; otherwise read the doctor's `browser` (picked
|
|
41
|
+
from the OS default browser, running apps and recent use — `candidates` shows the evidence). If memory
|
|
42
|
+
and the doctor disagree, or the doctor says `choose-browser`, ask the user. Pass the answer as
|
|
43
|
+
`--browser=<id>` and record it in memory. A Chrome that is merely installed is not their browser.
|
|
44
|
+
|
|
38
45
|
**Never launch a headless browser because the attached one is missing.** It has none of the
|
|
39
46
|
user's sessions, so every login turns into a ladder you should not be climbing. Say which state
|
|
40
47
|
you hit and ask.
|
|
@@ -13,18 +13,46 @@ Three pieces. The onboarding script prepares all three; a human finishes exactly
|
|
|
13
13
|
| | |
|
|
14
14
|
|---|---|
|
|
15
15
|
| Operating systems | macOS (Apple Silicon and Intel), Linux (x64, ARM64), Windows x64 |
|
|
16
|
-
| Browsers | Chrome, Microsoft Edge, Brave, Chromium —
|
|
16
|
+
| Browsers | Chrome, Microsoft Edge, Brave, Chromium, Arc, Dia, Vivaldi, Opera, Comet, Naver Whale — whichever the doctor lists under `candidates` |
|
|
17
|
+
|
|
18
|
+
## Which browser
|
|
19
|
+
|
|
20
|
+
The extension goes into exactly one browser: the one the user works in. Installed is not the same as
|
|
21
|
+
used — a Chrome launched once keeps its profile directory forever — so the scripts rank candidates by:
|
|
22
|
+
|
|
23
|
+
| Signal | Where it comes from |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Default browser | macOS LaunchServices `https` handler, Linux `xdg-settings`, Windows `UserChoice` ProgId |
|
|
26
|
+
| Running now | the app in `/Applications` (macOS), the process table elsewhere |
|
|
27
|
+
| Used in the last 7 days | the profile's `Local State` / `History` modification time |
|
|
28
|
+
|
|
29
|
+
Order of authority:
|
|
30
|
+
|
|
31
|
+
1. **Your memory.** If you recorded the user's browser before, pass it: `--browser=<id>`.
|
|
32
|
+
2. **`--browser=<id>` / `OMOWRIGHT_BROWSER`** set by the user.
|
|
33
|
+
3. **The default browser, when it is also in use** (or nothing else is).
|
|
34
|
+
4. **The only browser in use** when no default can be read.
|
|
35
|
+
|
|
36
|
+
Anything else is `choose-browser` (doctor) / `needsChoice: true` (install): nothing is registered and
|
|
37
|
+
`candidates` lists every browser with its signals. Ask the user which one they use, run the install
|
|
38
|
+
with `--browser=<id>`, and save the answer to memory so the next session does not ask again. When
|
|
39
|
+
the default browser is Safari or Firefox, BrowserSkill cannot drive it — say so and ask which
|
|
40
|
+
Chromium-family browser to use.
|
|
41
|
+
|
|
42
|
+
The doctor also lists `registeredElsewhere`: browsers that still carry an entry from an older
|
|
43
|
+
onboarding. They are not removed automatically (removing the entry uninstalls an extension the user
|
|
44
|
+
may have enabled); remove one only when the user asks, with omowright's `unregisterExternalExtension`.
|
|
17
45
|
|
|
18
46
|
## One command
|
|
19
47
|
|
|
20
48
|
```bash
|
|
21
|
-
node "<skill-root>/scripts/browser-install.mjs" [--json] [--wait-ms=180000]
|
|
49
|
+
node "<skill-root>/scripts/browser-install.mjs" [--browser=<id>] [--json] [--wait-ms=180000]
|
|
22
50
|
```
|
|
23
51
|
|
|
24
52
|
In order it: runs upstream's official `install.sh` / `install.ps1` into `~/.local/bin` (any PATH
|
|
25
53
|
line the installer appends to a shell rc file is reverted — the library calls the binary by
|
|
26
|
-
absolute path); starts the daemon with `bsk status`; and, for
|
|
27
|
-
|
|
54
|
+
absolute path); starts the daemon with `bsk status`; and, for **the one browser the user actually
|
|
55
|
+
uses**, registers the Web Store listing as an external extension:
|
|
28
56
|
|
|
29
57
|
| Platform | Where the entry goes | The user's one step |
|
|
30
58
|
|---|---|---|
|
|
@@ -32,6 +60,7 @@ finds, registers the Web Store listing as an external extension:
|
|
|
32
60
|
| Windows | `HKCU\Software\<vendor>\<browser>\Extensions\<id>` (`reg add`, no admin) | click **Enable** on the toolbar badge; no restart |
|
|
33
61
|
| Linux (Chromium) | `<user data dir>/External Extensions/<id>.json` | relaunch; installs without a prompt |
|
|
34
62
|
| Linux (Chrome / Edge / Brave) | `/opt/google/chrome/extensions/<id>.json` and siblings — root only | otherwise open the store link it prints and click **Add** |
|
|
63
|
+
| Opera, and Vivaldi / Whale off macOS | no external-extension path | open the store link it prints in that browser and click **Add** |
|
|
35
64
|
|
|
36
65
|
The script prints that step as `humanStep`. **Relay it verbatim and wait**; with `--wait-ms` it
|
|
37
66
|
keeps polling the daemon until the extension connects. An empty `browsersConnected` afterwards is
|
|
@@ -57,7 +86,7 @@ engine, one of them shadowing the one that knows about omowright and this packag
|
|
|
57
86
|
## Diagnosing
|
|
58
87
|
|
|
59
88
|
```bash
|
|
60
|
-
node "<skill-root>/scripts/browser-doctor.mjs" --json # this package's view: cli, daemon,
|
|
89
|
+
node "<skill-root>/scripts/browser-doctor.mjs" --json # this package's view: cli, daemon, the user's browser + candidates, registrations, connections
|
|
61
90
|
bsk doctor # upstream's own checks
|
|
62
91
|
bsk logs # daemon log
|
|
63
92
|
```
|
|
@@ -1530,5 +1530,5 @@ ${snapshot.tree}`}}var DEFAULT_TIMEOUT_MS=30000;var JSON_MIME=/^application\/jso
|
|
|
1530
1530
|
const css = {};
|
|
1531
1531
|
for (const ref of Object.keys(result.refs || {})) css[ref] = cssPath(api.elementRegistry.get(ref));
|
|
1532
1532
|
return { tree: result.tree, refs: result.refs || {}, css, error: result.error };
|
|
1533
|
-
})()`}async function bskSnapshot(session,{tabId,timeoutMs,...snapshotOptions}={}){const reply=await session.evaluate(buildSnapshotExpression(snapshotOptions),{tabId,timeoutMs,awaitPromise:false,returnByValue:true});if(!reply||reply.ok===false){const text=reply?.error?.text??"unknown error";throw new Error(`bskSnapshot failed inside the page: ${text}`)}const value=reply.value;if(!value||typeof value.tree!=="string")throw new Error("bskSnapshot: page returned no tree");if(value.error)throw new Error(`bskSnapshot: ${value.error}`);return{tree:value.tree,refs:value.refs,css:value.css}}import{existsSync as existsSync4,mkdirSync as mkdirSync2,readFileSync as readFileSync4,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{spawn as spawn4}from"node:child_process";import path11 from"node:path";import{existsSync as existsSync3}from"node:fs";import{homedir as homedir3}from"node:os";import path10 from"node:path";var BROWSERSKILL_EXTENSION_IDS=Object.freeze({chrome:"hhcmgoofomhgciiibhipgmgkgnoenaoi",edge:"emacgiaaaiojkkpkddmmdfhmokgmnikg"});var STORE_UPDATE_URLS=Object.freeze({chrome:"https://clients2.google.com/service/update2/crx",edge:"https://edge.microsoft.com/extensionwebstorebase/v1/crx"});var STORE_PAGE_URLS=Object.freeze({chrome:`https://chromewebstore.google.com/detail/${BROWSERSKILL_EXTENSION_IDS.chrome}`,edge:`https://microsoftedge.microsoft.com/addons/detail/browserskill/${BROWSERSKILL_EXTENSION_IDS.edge}`});var MAC=[{id:"chrome",store:"chrome",userData:"Library/Application Support/Google/Chrome",binary:"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",bundleId:"com.google.Chrome"},{id:"edge",store:"edge",userData:"Library/Application Support/Microsoft Edge",binary:"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",bundleId:"com.microsoft.edgemac"},{id:"brave",store:"chrome",userData:"Library/Application Support/BraveSoftware/Brave-Browser",binary:"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",bundleId:"com.brave.Browser"},{id:"chromium",store:"chrome",userData:"Library/Application Support/Chromium",binary:"/Applications/Chromium.app/Contents/MacOS/Chromium",bundleId:"org.chromium.Chromium"}];var LINUX=[{id:"chrome",store:"chrome",userData:".config/google-chrome",binaries:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/opt/google/chrome/chrome"],externalDir:"/opt/google/chrome/extensions",userExternalDir:false},{id:"chromium",store:"chrome",userData:".config/chromium",binaries:["/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium"],externalDir:"/usr/share/chromium/extensions",userExternalDir:true},{id:"edge",store:"edge",userData:".config/microsoft-edge",binaries:["/usr/bin/microsoft-edge","/opt/microsoft/msedge/msedge"],externalDir:"/usr/share/microsoft-edge/extensions",userExternalDir:false},{id:"brave",store:"chrome",userData:".config/BraveSoftware/Brave-Browser",binaries:["/usr/bin/brave-browser","/opt/brave.com/brave/brave"],externalDir:"/usr/share/brave/extensions",userExternalDir:false}];var WINDOWS=[{id:"chrome",store:"chrome",userData:"Google/Chrome/User Data",registryKey:"HKCU\\Software\\Google\\Chrome\\Extensions",binaryRel:"Google/Chrome/Application/chrome.exe"},{id:"edge",store:"edge",userData:"Microsoft/Edge/User Data",registryKey:"HKCU\\Software\\Microsoft\\Edge\\Extensions",binaryRel:"Microsoft/Edge/Application/msedge.exe"},{id:"brave",store:"chrome",userData:"BraveSoftware/Brave-Browser/User Data",registryKey:"HKCU\\Software\\BraveSoftware\\Brave-Browser\\Extensions",binaryRel:"BraveSoftware/Brave-Browser/Application/brave.exe"}];function detectBrowsers({platform=process.platform,home=homedir3(),env=process.env,exists=existsSync3}={}){if(platform==="darwin"){return MAC.filter((b)=>exists(path10.join(home,b.userData))).map((b)=>({id:b.id,store:b.store,userDataDir:path10.join(home,b.userData),binary:b.binary,bundleId:b.bundleId}))}if(platform==="linux"){return LINUX.filter((b)=>exists(path10.join(home,b.userData))).map((b)=>({id:b.id,store:b.store,userDataDir:path10.join(home,b.userData),binary:b.binaries.find((p)=>exists(p))??null,externalDir:b.externalDir,userExternalDir:b.userExternalDir}))}if(platform==="win32"){const localAppData=env.LOCALAPPDATA??path10.join(home,"AppData","Local");const programFiles=[env.PROGRAMFILES,env["PROGRAMFILES(X86)"],"C:\\Program Files","C:\\Program Files (x86)"].filter(Boolean);return WINDOWS.filter((b)=>exists(path10.join(localAppData,b.userData))).map((b)=>({id:b.id,store:b.store,userDataDir:path10.join(localAppData,b.userData),registryKey:b.registryKey,binary:programFiles.map((root)=>path10.join(root,b.binaryRel)).find((p)=>exists(p))??null}))}return[]}var ENABLE_STEP=(browser)=>`Quit ${browser} completely and open it again; a dialog offers to enable "BrowserSkill" — click Enable.`;var BADGE_STEP=(browser)=>`In ${browser}, open the menu (the badge on the toolbar) and enable "BrowserSkill" when prompted; no restart is needed.`;function externalExtensionEntry({platform=process.platform,browser}){const id=BROWSERSKILL_EXTENSION_IDS[browser.store];const updateUrl=STORE_UPDATE_URLS[browser.store];const label=browser.id.charAt(0).toUpperCase()+browser.id.slice(1);if(platform==="win32"){const key=`${browser.registryKey}\\${id}`;return{kind:"registry",key,needsRestart:false,storeUrl:STORE_PAGE_URLS[browser.store],regAddArgs:["add",key,"/v","update_url","/t","REG_SZ","/d",updateUrl,"/f"],regDeleteArgs:["delete",key,"/f"],humanStep:BADGE_STEP(label)}}const content=JSON.stringify({external_update_url:updateUrl},null,2)+`
|
|
1534
|
-
`;if(platform==="linux"&&!browser.userExternalDir){return{kind:"file",path:path11.join(browser.externalDir,`${id}.json`),content,needsRestart:true,storeUrl:STORE_PAGE_URLS[browser.store],humanStep:`Quit ${label} completely and open it again; the extension installs without a prompt.`}}return{kind:"file",path:path11.join(browser.userDataDir,"External Extensions",`${id}.json`),content,needsRestart:true,storeUrl:STORE_PAGE_URLS[browser.store],humanStep:platform==="linux"?`Quit ${label} completely and open it again; the extension installs without a prompt.`:ENABLE_STEP(label)}}function isBlocklisted(browser,id,{readFile=readFileSync4}={}){if(!browser.userDataDir)return false;for(const profile of["Default","Profile 1","Profile 2","Profile 3"]){const file=path11.join(browser.userDataDir,profile,"Preferences");let prefs;try{prefs=JSON.parse(readFile(file,"utf8"))}catch{continue}if(Array.isArray(prefs?.extensions?.external_uninstalls)&&prefs.extensions.external_uninstalls.includes(id))return true}return false}function runRegDefault(args){return new Promise((resolve)=>{const child=spawn4("reg",args,{stdio:["ignore","ignore","pipe"],windowsHide:true});let stderr="";child.stderr.on("data",(c)=>{stderr+=c});child.on("error",(error)=>resolve({code:-1,stderr:error.message}));child.on("exit",(code)=>resolve({code,stderr}))})}async function registerExternalExtension({platform=process.platform,browser,writeFile=writeFileSync2,readFile=readFileSync4,runReg=runRegDefault}={}){const entry=externalExtensionEntry({platform,browser});const id=BROWSERSKILL_EXTENSION_IDS[browser.store];const storeStep=`Open ${entry.storeUrl} in ${browser.id} and click "Add to ${browser.store==="edge"?"Edge":"Chrome"}".`;if(isBlocklisted(browser,id,{readFile})){return{...entry,registered:false,alreadyPresent:false,reason:"blocklisted",humanStep:`The extension was removed from ${browser.id} before, so external registration is ignored. ${storeStep}`}}if(entry.kind==="registry"){const result=await runReg(entry.regAddArgs);if(result.code!==0)return{...entry,registered:false,alreadyPresent:false,reason:"reg_failed",detail:result.stderr,humanStep:storeStep};return{...entry,registered:true,alreadyPresent:false}}let alreadyPresent=false;try{alreadyPresent=readFile(entry.path,"utf8")===entry.content}catch{}if(alreadyPresent)return{...entry,registered:true,alreadyPresent:true};try{mkdirSync2(path11.dirname(entry.path),{recursive:true});writeFile(entry.path,entry.content)}catch(error){if(error.code==="EACCES"||error.code==="EPERM"||error.code==="EROFS"){return{...entry,registered:false,alreadyPresent:false,reason:"not_writable",humanStep:`${entry.path} is not writable without administrator rights. ${storeStep}`}}throw error}return{...entry,registered:true,alreadyPresent:false}}async function unregisterExternalExtension({platform=process.platform,browser,runReg=runRegDefault}={}){const entry=externalExtensionEntry({platform,browser});if(entry.kind==="registry"){const result=await runReg(entry.regDeleteArgs);return{...entry,removed:result.code===0,detail:result.stderr}}const present=existsSync4(entry.path);if(present)rmSync2(entry.path,{force:true});return{...entry,removed:present}}import{existsSync as existsSync5,readFileSync as readFileSync5,rmSync as rmSync3,writeFileSync as writeFileSync3}from"node:fs";import{homedir as homedir4}from"node:os";import path12 from"node:path";import{spawn as spawn5}from"node:child_process";var INSTALL_SH="https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.sh";var INSTALL_PS1="https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.ps1";var RC_FILES=[".zshrc",".bashrc",".profile"];function cliInstallCommand({platform=process.platform,installDir,version}={}){const env={BSK_INSTALL_DIR:installDir};if(version)env.BSK_VERSION=version;if(platform==="win32"){return{command:"powershell",args:["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${INSTALL_PS1} | iex`],env}}return{command:"sh",args:["-c",`curl -fsSL ${INSTALL_SH} | sh`],env}}function runDefault(command,args,env){return new Promise((resolve)=>{const child=spawn5(command,args,{env:{...process.env,...env},stdio:["ignore","pipe","pipe"],windowsHide:true});let stdout="",stderr="";child.stdout.on("data",(c)=>{stdout=(stdout+c).slice(-8192)});child.stderr.on("data",(c)=>{stderr=(stderr+c).slice(-8192)});child.on("error",(error)=>resolve({code:-1,stdout,stderr:error.message}));child.on("exit",(code)=>resolve({code,stdout,stderr}))})}function snapshotRcFiles(home){const snapshot=new Map;for(const name of RC_FILES){const file=path12.join(home,name);snapshot.set(file,existsSync5(file)?readFileSync5(file):null)}return snapshot}function restoreRcFiles(snapshot){const restored=[];for(const[file,before]of snapshot){const after=existsSync5(file)?readFileSync5(file):null;if(before===null&&after===null)continue;if(before!==null&&after!==null&&before.equals(after))continue;if(before===null)rmSync3(file,{force:true});else writeFileSync3(file,before);restored.push(file)}return restored}async function installBskCli({platform=process.platform,home=homedir4(),installDir=path12.join(home,".local","bin"),version,run=runDefault}={}){const spec=cliInstallCommand({platform,installDir,version});const rcBefore=platform==="win32"?new Map:snapshotRcFiles(home);const result=await run(spec.command,spec.args,spec.env);const restoredRcFiles=restoreRcFiles(rcBefore);const bskBin=path12.join(installDir,platform==="win32"?"bsk.exe":"bsk");const installed=result.code===0&&existsSync5(bskBin);return{installed,bskBin:installed?bskBin:null,code:result.code,stdout:result.stdout,stderr:result.stderr,restoredRcFiles}}function cliVersionDefault(bskBin){return new Promise((resolve)=>{const child=spawn5(bskBin,["--version"],{stdio:["ignore","pipe","ignore"],windowsHide:true});let out="";child.stdout.on("data",(c)=>{out+=c});child.on("error",()=>resolve(null));child.on("exit",(code)=>resolve(code===0?out.trim():null))})}import{homedir as homedir5}from"node:os";import{existsSync as existsSync6,readFileSync as readFileSync6}from"node:fs";var DEFAULT_WAIT_TOTAL_MS=180000;function resolveBskBin(bskBin,env){if(bskBin===null)return null;return bskBin??findBskBinary(env)}async function cliReport({bskBin,env,cliVersion}){const bin=resolveBskBin(bskBin,env);if(!bin)return{installed:false,bskBin:null,version:null};const raw=await cliVersion(bin);return raw?{installed:true,bskBin:bin,version:raw.replace(/^bsk\s+/,"")}:{installed:false,bskBin:bin,version:null}}async function daemonReport(client,waitForBrowserMs){try{const status=await client.call("system.status",waitForBrowserMs>0?{wait_for_browser_ms:waitForBrowserMs}:{},{idPrefix:"status"});return{running:true,version:status.daemon_version,protocolVersion:status.protocol_version,browsers:status.browsers??[],sessions:status.sessions??[]}}catch(error){return{running:false,error:error.message,code:error.code,browsers:[],sessions:[]}}}function browserRows({platform,home,env}){return detectBrowsers({platform,home,env}).map((browser)=>{const entry=externalExtensionEntry({platform,browser});const extensionRegistered=entry.kind==="file"&&existsSync6(entry.path)&&readFileSync6(entry.path,"utf8")===entry.content;return{...browser,registration:entry,extensionRegistered}})}function nextStepFor({cli,daemon,browsers,browsersConnected}){if(browsersConnected.length>0)return null;if(!cli.installed)return"Install the bsk CLI (bskOnboard() runs the official installer).";if(!daemon.running)return"Start the BrowserSkill daemon: run `bsk status` once, or `bsk daemon start` in the environment that owns it.";if(browsers.length===0)return`No Chromium-family browser profile was found; install Chrome or Edge and add the extension from ${STORE_PAGE_URLS.chrome}.`;const unregistered=browsers.find((b)=>!b.extensionRegistered);if(unregistered)return`Register the BrowserSkill extension for ${unregistered.id} (bskOnboard() does this), then let the user enable it.`;return browsers[0].registration.humanStep}async function bskDoctor({platform=process.platform,home=homedir5(),env=process.env,client,bskBin,cliVersion=cliVersionDefault,waitForBrowserMs=0}={}){const cli=await cliReport({bskBin,env,cliVersion});const ipc=client??new BskIpcClient({env,bskBin:cli.bskBin??undefined,autoStart:false});const daemon=await daemonReport(ipc,waitForBrowserMs);const browsers=browserRows({platform,home,env});const browsersConnected=daemon.browsers;const report={cli,daemon,browsers,browsersConnected,ready:browsersConnected.length>0};report.nextStep=nextStepFor(report);return report}async function bskOnboard({platform=process.platform,home=homedir5(),env=process.env,client,bskBin,installDir,installCli=installBskCli,cliVersion=cliVersionDefault,onHumanStep=()=>{},waitForBrowserMs=15000,waitTotalMs=DEFAULT_WAIT_TOTAL_MS}={}){let cli=await cliReport({bskBin,env,cliVersion});let install=null;if(!cli.installed){install=await installCli({platform,home,installDir});cli=install.installed?await cliReport({bskBin:install.bskBin,env,cliVersion}):cli}const ipc=client??new BskIpcClient({env,bskBin:cli.bskBin??undefined,autoStart:true});let daemon=await daemonReport(ipc,0);const browsers=browserRows({platform,home,env});const registrations=[];let humanStep=null;if(daemon.browsers.length===0){for(const browser of browsers){const registration=await registerExternalExtension({platform,browser});registrations.push({browser:browser.id,...registration});if(!humanStep)humanStep=registration.humanStep;onHumanStep({browser:browser.id,step:registration.humanStep,registered:registration.registered,needsRestart:registration.needsRestart})}if(browsers.length===0)humanStep=`No Chromium-family browser profile was found. Install Chrome or Edge, then add the extension from ${STORE_PAGE_URLS.chrome}.`}const deadline=Date.now()+waitTotalMs;let browsersConnected=daemon.browsers;while(browsersConnected.length===0&&daemon.running&&Date.now()<deadline){browsersConnected=await listBrowsers(ipc,{waitForBrowserMs});if(waitForBrowserMs===0)break}daemon={...daemon,browsers:browsersConnected};const ready=browsersConnected.length>0;return{cli,install,daemon,browsers,registrations,humanStep:ready?null:humanStep,browsersConnected,ready}}export{AgentTabManager,BROWSERSKILL_EXTENSION_IDS,BROWSER_EVENT_NAMES,BridgeProtocolError,BridgeUnavailableError,BrowserCdpCommandError,BrowserConnection,BskIpcClient,BskRpcError,BskSession,CdpClient,CommandSchema,DEFAULT_AGENT_VIEWPORT,DEVICE_PRESETS,ElementHandle,EventSchema,ExtensionHelloSchema,FrameLocator,FrameManager,HostHelloSchema,Locator,ModifierState,OmOKeyboard,OmOMouse,OmOPage,PipeCdpClient,ResponseSchema,STORE_PAGE_URLS,SessionManager,TabRepository,UnsupportedOperationError,bskDoctor,bskOnboard,bskSnapshot,buildCloakBrowserArgs,buildSnapshotExpression,collectWhileScrolling,compactSnapshot,connect,connectBrowserSkill,connectCloakProfile,connectPipe,createAgentTabs,createBridgeClient,createCaptcha,createChromeApi2 as createChromeApi,createCua,createEvents,createNativeMessagingHost,createNetworkSnoop,createRoutes,createTrace,decodeFrames,describeLayers,detectBrowsers,emulate,encodeFrame,externalExtensionEntry,findCloakBrowserPath,injectCookies,installBskCli,installNativeMessagingHost,layersHeader,listBrowsers,macOSVisionOcr,normalizeDialogPolicy,pageBundle,readDaemonInfo,reconcileFrames,registerExternalExtension,repinViewport,requestHuman,resolveBskHome,resolveCloakProfile,resolveDialogAction,sanitizeCookies,snapshotTokens,snapshotWithFrames,snapshotWithLayers,takeSnapshot,toHar,toolSchemas,unregisterExternalExtension};
|
|
1533
|
+
})()`}async function bskSnapshot(session,{tabId,timeoutMs,...snapshotOptions}={}){const reply=await session.evaluate(buildSnapshotExpression(snapshotOptions),{tabId,timeoutMs,awaitPromise:false,returnByValue:true});if(!reply||reply.ok===false){const text=reply?.error?.text??"unknown error";throw new Error(`bskSnapshot failed inside the page: ${text}`)}const value=reply.value;if(!value||typeof value.tree!=="string")throw new Error("bskSnapshot: page returned no tree");if(value.error)throw new Error(`bskSnapshot: ${value.error}`);return{tree:value.tree,refs:value.refs,css:value.css}}import{existsSync as existsSync4,mkdirSync as mkdirSync2,readFileSync as readFileSync4,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{spawn as spawn4}from"node:child_process";import path11 from"node:path";import{existsSync as existsSync3}from"node:fs";import{homedir as homedir3}from"node:os";import path10 from"node:path";var BROWSERSKILL_EXTENSION_IDS=Object.freeze({chrome:"hhcmgoofomhgciiibhipgmgkgnoenaoi",edge:"emacgiaaaiojkkpkddmmdfhmokgmnikg"});var STORE_UPDATE_URLS=Object.freeze({chrome:"https://clients2.google.com/service/update2/crx",edge:"https://edge.microsoft.com/extensionwebstorebase/v1/crx"});var STORE_PAGE_URLS=Object.freeze({chrome:`https://chromewebstore.google.com/detail/${BROWSERSKILL_EXTENSION_IDS.chrome}`,edge:`https://microsoftedge.microsoft.com/addons/detail/browserskill/${BROWSERSKILL_EXTENSION_IDS.edge}`});var NON_CHROMIUM_DEFAULTS=Object.freeze([{id:"safari",label:"Safari",match:["com.apple.safari","safarihtml"]},{id:"firefox",label:"Firefox",match:["org.mozilla.firefox","firefox.desktop","firefoxurl","firefoxhtml"]},{id:"zen",label:"Zen",match:["app.zen-browser.zen","zen.desktop","zenhtml"]},{id:"orion",label:"Orion",match:["com.kagi.kagimacos"]}]);var MAC=[{id:"chrome",label:"Google Chrome",store:"chrome",userData:"Library/Application Support/Google/Chrome",app:"Google Chrome",bundleId:"com.google.Chrome"},{id:"edge",label:"Microsoft Edge",store:"edge",userData:"Library/Application Support/Microsoft Edge",app:"Microsoft Edge",bundleId:"com.microsoft.edgemac"},{id:"brave",label:"Brave",store:"chrome",userData:"Library/Application Support/BraveSoftware/Brave-Browser",app:"Brave Browser",bundleId:"com.brave.Browser"},{id:"chromium",label:"Chromium",store:"chrome",userData:"Library/Application Support/Chromium",app:"Chromium",bundleId:"org.chromium.Chromium"},{id:"arc",label:"Arc",store:"chrome",userData:"Library/Application Support/Arc/User Data",app:"Arc",bundleId:"company.thebrowser.Browser"},{id:"dia",label:"Dia",store:"chrome",userData:"Library/Application Support/Dia/User Data",app:"Dia",bundleId:"company.thebrowser.dia"},{id:"vivaldi",label:"Vivaldi",store:"chrome",userData:"Library/Application Support/Vivaldi",app:"Vivaldi",bundleId:"com.vivaldi.Vivaldi"},{id:"opera",label:"Opera",store:"chrome",userData:"Library/Application Support/com.operasoftware.Opera",app:"Opera",bundleId:"com.operasoftware.Opera",externalExtensions:false},{id:"comet",label:"Comet",store:"chrome",userData:"Library/Application Support/Comet",app:"Comet",bundleId:"ai.perplexity.comet"},{id:"aside",label:"Aside",store:"chrome",userData:"Library/Application Support/Aside",app:"Aside",bundleId:"at.studio.AsideBrowser"},{id:"whale",label:"Naver Whale",store:"chrome",userData:"Library/Application Support/Naver/Whale",app:"Naver Whale",bundleId:"com.naver.Whale"}];var LINUX=[{id:"chrome",label:"Google Chrome",store:"chrome",userData:".config/google-chrome",binaries:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/opt/google/chrome/chrome"],externalDir:"/opt/google/chrome/extensions",userExternalDir:false,desktopIds:["google-chrome.desktop","google-chrome-stable.desktop","com.google.Chrome.desktop"],processNames:["chrome","google-chrome"]},{id:"chromium",label:"Chromium",store:"chrome",userData:".config/chromium",binaries:["/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium"],externalDir:"/usr/share/chromium/extensions",userExternalDir:true,desktopIds:["chromium.desktop","chromium-browser.desktop","chromium_chromium.desktop","org.chromium.Chromium.desktop"],processNames:["chromium","chromium-browse"]},{id:"edge",label:"Microsoft Edge",store:"edge",userData:".config/microsoft-edge",binaries:["/usr/bin/microsoft-edge","/opt/microsoft/msedge/msedge"],externalDir:"/usr/share/microsoft-edge/extensions",userExternalDir:false,desktopIds:["microsoft-edge.desktop","microsoft-edge-stable.desktop","com.microsoft.Edge.desktop"],processNames:["msedge"]},{id:"brave",label:"Brave",store:"chrome",userData:".config/BraveSoftware/Brave-Browser",binaries:["/usr/bin/brave-browser","/opt/brave.com/brave/brave"],externalDir:"/usr/share/brave/extensions",userExternalDir:false,desktopIds:["brave-browser.desktop","com.brave.Browser.desktop"],processNames:["brave"]},{id:"vivaldi",label:"Vivaldi",store:"chrome",userData:".config/vivaldi",binaries:["/usr/bin/vivaldi","/opt/vivaldi/vivaldi"],externalDir:null,userExternalDir:false,externalExtensions:false,desktopIds:["vivaldi-stable.desktop","vivaldi.desktop"],processNames:["vivaldi-bin"]},{id:"opera",label:"Opera",store:"chrome",userData:".config/opera",binaries:["/usr/bin/opera"],externalDir:null,userExternalDir:false,externalExtensions:false,desktopIds:["opera.desktop"],processNames:["opera"]}];var WINDOWS=[{id:"chrome",label:"Google Chrome",store:"chrome",userData:"Google/Chrome/User Data",registryKey:"HKCU\\Software\\Google\\Chrome\\Extensions",binaryRel:"Google/Chrome/Application/chrome.exe",progIds:["chromehtml"],processNames:["chrome.exe"]},{id:"edge",label:"Microsoft Edge",store:"edge",userData:"Microsoft/Edge/User Data",registryKey:"HKCU\\Software\\Microsoft\\Edge\\Extensions",binaryRel:"Microsoft/Edge/Application/msedge.exe",progIds:["msedgehtm"],processNames:["msedge.exe"]},{id:"brave",label:"Brave",store:"chrome",userData:"BraveSoftware/Brave-Browser/User Data",registryKey:"HKCU\\Software\\BraveSoftware\\Brave-Browser\\Extensions",binaryRel:"BraveSoftware/Brave-Browser/Application/brave.exe",progIds:["bravehtml"],processNames:["brave.exe"]},{id:"chromium",label:"Chromium",store:"chrome",userData:"Chromium/User Data",registryKey:"HKCU\\Software\\Chromium\\Extensions",binaryRel:"Chromium/Application/chrome.exe",progIds:["chromiumhtm"],processNames:[]},{id:"vivaldi",label:"Vivaldi",store:"chrome",userData:"Vivaldi/User Data",registryKey:null,externalExtensions:false,binaryRel:"Vivaldi/Application/vivaldi.exe",progIds:["vivaldihtm"],processNames:["vivaldi.exe"]},{id:"whale",label:"Naver Whale",store:"chrome",userData:"Naver/Naver Whale/User Data",registryKey:null,externalExtensions:false,binaryRel:"Naver/Naver Whale/Application/whale.exe",progIds:["whalehtml"],processNames:["whale.exe"]}];var BROWSER_IDS=Object.freeze([...new Set([...MAC,...LINUX,...WINDOWS].map((b)=>b.id))]);function macRow(b,home,exists){const apps=[path10.join("/Applications",`${b.app}.app`),path10.join(home,"Applications",`${b.app}.app`)];const appPath=apps.find((p)=>exists(p))??null;const userDataDir=path10.join(home,b.userData);return{id:b.id,label:b.label,store:b.store,userDataDir,binary:path10.join(appPath??apps[0],"Contents","MacOS",b.app),bundleId:b.bundleId,processNames:apps.map((a)=>path10.join(a,"Contents","MacOS",b.app)),defaultIds:[b.bundleId.toLowerCase()],externalExtensions:b.externalExtensions!==false,installed:appPath!==null||exists(userDataDir),hasProfile:exists(userDataDir)}}function linuxRow(b,home,exists){const userDataDir=path10.join(home,b.userData);const binary=b.binaries.find((p)=>exists(p))??null;return{id:b.id,label:b.label,store:b.store,userDataDir,binary,externalDir:b.externalDir,userExternalDir:b.userExternalDir,processNames:b.processNames,defaultIds:b.desktopIds.map((d)=>d.toLowerCase()),externalExtensions:b.externalExtensions!==false,installed:binary!==null||exists(userDataDir),hasProfile:exists(userDataDir)}}function windowsRow(b,env,home,exists){const localAppData=env.LOCALAPPDATA??path10.join(home,"AppData","Local");const programFiles=[localAppData,env.PROGRAMFILES,env["PROGRAMFILES(X86)"],"C:\\Program Files","C:\\Program Files (x86)"].filter(Boolean);const userDataDir=path10.join(localAppData,b.userData);const binary=programFiles.map((root)=>path10.join(root,b.binaryRel)).find((p)=>exists(p))??null;return{id:b.id,label:b.label,store:b.store,userDataDir,registryKey:b.registryKey,binary,processNames:b.processNames,defaultIds:b.progIds,externalExtensions:b.externalExtensions!==false,installed:binary!==null||exists(userDataDir),hasProfile:exists(userDataDir)}}function catalogBrowsers({platform=process.platform,home=homedir3(),env=process.env,exists=existsSync3}={}){if(platform==="darwin")return MAC.map((b)=>macRow(b,home,exists));if(platform==="linux")return LINUX.map((b)=>linuxRow(b,home,exists));if(platform==="win32")return WINDOWS.map((b)=>windowsRow(b,env,home,exists));return[]}function detectBrowsers(options={}){return catalogBrowsers(options).filter((b)=>b.installed)}var ENABLE_STEP=(browser)=>`Quit ${browser} completely and open it again; a dialog offers to enable "BrowserSkill" — click Enable.`;var BADGE_STEP=(browser)=>`In ${browser}, open the menu (the badge on the toolbar) and enable "BrowserSkill" when prompted; no restart is needed.`;var storeStep=(browser,label)=>`Open ${STORE_PAGE_URLS[browser.store]} in ${label} and click the "Add" button.`;function externalExtensionEntry({platform=process.platform,browser}){const id=BROWSERSKILL_EXTENSION_IDS[browser.store];const updateUrl=STORE_UPDATE_URLS[browser.store];const label=browser.label??browser.id.charAt(0).toUpperCase()+browser.id.slice(1);if(browser.externalExtensions===false){return{kind:"store",needsRestart:false,storeUrl:STORE_PAGE_URLS[browser.store],humanStep:storeStep(browser,label)}}if(platform==="win32"){const key=`${browser.registryKey}\\${id}`;return{kind:"registry",key,needsRestart:false,storeUrl:STORE_PAGE_URLS[browser.store],regAddArgs:["add",key,"/v","update_url","/t","REG_SZ","/d",updateUrl,"/f"],regDeleteArgs:["delete",key,"/f"],humanStep:BADGE_STEP(label)}}const content=JSON.stringify({external_update_url:updateUrl},null,2)+`
|
|
1534
|
+
`;if(platform==="linux"&&!browser.userExternalDir){return{kind:"file",path:path11.join(browser.externalDir,`${id}.json`),content,needsRestart:true,storeUrl:STORE_PAGE_URLS[browser.store],humanStep:`Quit ${label} completely and open it again; the extension installs without a prompt.`}}return{kind:"file",path:path11.join(browser.userDataDir,"External Extensions",`${id}.json`),content,needsRestart:true,storeUrl:STORE_PAGE_URLS[browser.store],humanStep:platform==="linux"?`Quit ${label} completely and open it again; the extension installs without a prompt.`:ENABLE_STEP(label)}}function isBlocklisted(browser,id,{readFile=readFileSync4}={}){if(!browser.userDataDir)return false;for(const profile of["Default","Profile 1","Profile 2","Profile 3"]){const file=path11.join(browser.userDataDir,profile,"Preferences");let prefs;try{prefs=JSON.parse(readFile(file,"utf8"))}catch{continue}if(Array.isArray(prefs?.extensions?.external_uninstalls)&&prefs.extensions.external_uninstalls.includes(id))return true}return false}function runRegDefault(args){return new Promise((resolve)=>{const child=spawn4("reg",args,{stdio:["ignore","ignore","pipe"],windowsHide:true});let stderr="";child.stderr.on("data",(c)=>{stderr+=c});child.on("error",(error)=>resolve({code:-1,stderr:error.message}));child.on("exit",(code)=>resolve({code,stderr}))})}async function registerExternalExtension({platform=process.platform,browser,writeFile=writeFileSync2,readFile=readFileSync4,runReg=runRegDefault}={}){const entry=externalExtensionEntry({platform,browser});const id=BROWSERSKILL_EXTENSION_IDS[browser.store];const label=browser.label??browser.id;const storeStep=`Open ${entry.storeUrl} in ${label} and click the "Add" button.`;if(entry.kind==="store")return{...entry,registered:false,alreadyPresent:false,reason:"store_only"};if(isBlocklisted(browser,id,{readFile})){return{...entry,registered:false,alreadyPresent:false,reason:"blocklisted",humanStep:`The extension was removed from ${label} before, so external registration is ignored. ${storeStep}`}}if(entry.kind==="registry"){const result=await runReg(entry.regAddArgs);if(result.code!==0)return{...entry,registered:false,alreadyPresent:false,reason:"reg_failed",detail:result.stderr,humanStep:storeStep};return{...entry,registered:true,alreadyPresent:false}}let alreadyPresent=false;try{alreadyPresent=readFile(entry.path,"utf8")===entry.content}catch{}if(alreadyPresent)return{...entry,registered:true,alreadyPresent:true};try{mkdirSync2(path11.dirname(entry.path),{recursive:true});writeFile(entry.path,entry.content)}catch(error){if(error.code==="EACCES"||error.code==="EPERM"||error.code==="EROFS"){return{...entry,registered:false,alreadyPresent:false,reason:"not_writable",humanStep:`${entry.path} is not writable without administrator rights. ${storeStep}`}}throw error}return{...entry,registered:true,alreadyPresent:false}}async function unregisterExternalExtension({platform=process.platform,browser,runReg=runRegDefault}={}){const entry=externalExtensionEntry({platform,browser});if(entry.kind==="store")return{...entry,removed:false};if(entry.kind==="registry"){const result=await runReg(entry.regDeleteArgs);return{...entry,removed:result.code===0,detail:result.stderr}}const present=existsSync4(entry.path);if(present)rmSync2(entry.path,{force:true});return{...entry,removed:present}}import{execFile}from"node:child_process";import{statSync}from"node:fs";import{homedir as homedir4}from"node:os";import path12 from"node:path";var PROBE_TIMEOUT_MS=3000;function runDefault(command,args){return new Promise((resolve)=>{execFile(command,args,{timeout:PROBE_TIMEOUT_MS,windowsHide:true,maxBuffer:8*1024*1024},(error,stdout)=>{resolve(error?null:String(stdout))})})}function parseMacDefaultBrowser(plistJson){let handlers;try{handlers=JSON.parse(plistJson)?.LSHandlers}catch{return null}if(!Array.isArray(handlers))return null;const pick=(scheme)=>handlers.find((h)=>h?.LSHandlerURLScheme===scheme&&typeof h.LSHandlerRoleAll==="string");const handler=pick("https")??pick("http");return handler?handler.LSHandlerRoleAll.toLowerCase():"com.apple.safari"}function parseWindowsProgId(regOutput){const match=/ProgId\s+REG_SZ\s+(\S+)/i.exec(regOutput??"");return match?match[1].toLowerCase():null}function parseProcessNames(platform,output){const names=new Set;for(const raw of String(output??"").split(/\r?\n/)){const line=raw.trim();if(!line)continue;if(platform==="win32"){const image=/^"([^"]+)"/.exec(line)?.[1];if(image)names.add(image.toLowerCase())}else if(platform==="darwin"){if(/\.app\/Contents\/MacOS\/[^/]+$/.test(line))names.add(line)}else{names.add(path12.basename(line))}}return[...names]}async function probeDefault({platform,home,run}){if(platform==="darwin"){const plist=path12.join(home,"Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist");const json=await run("plutil",["-convert","json","-o","-",plist]);return json===null?null:parseMacDefaultBrowser(json)}if(platform==="linux"){const out=await run("xdg-settings",["get","default-web-browser"]);return out?.trim()?out.trim().toLowerCase():null}if(platform==="win32"){const key="HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\https\\UserChoice";return parseWindowsProgId(await run("reg",["query",key,"/v","ProgId"]))}return null}async function probeRunning({platform,run}){const out=platform==="win32"?await run("tasklist",["/fo","csv","/nh"]):await run("ps",platform==="darwin"?["-axo","comm="]:["-eo","comm="]);return out===null?null:parseProcessNames(platform,out)}function lastUsedAt(browser,stat){let latest=null;for(const rel of["Local State",path12.join("Default","History"),path12.join("Default","Preferences")]){try{const mtime=stat(path12.join(browser.userDataDir,rel)).mtimeMs;if(latest===null||mtime>latest)latest=mtime}catch{}}return latest}async function probeBrowserSignals({platform=process.platform,home=homedir4(),browsers=[],run=runDefault,stat=statSync}={}){const[defaultBrowser,running]=await Promise.all([probeDefault({platform,home,run}),probeRunning({platform,run})]);const lastUsed=Object.fromEntries(browsers.map((b)=>[b.id,lastUsedAt(b,stat)]));return{defaultBrowser,running,lastUsed}}var RECENT_USE_MS=7*24*60*60*1000;function matchesDefault(browser,defaultId){if(!defaultId)return false;return browser.defaultIds.some((id)=>defaultId===id||defaultId.startsWith(id))}function describeDefault(defaultId,catalog){if(defaultId===null||defaultId===undefined)return{raw:null,id:null,label:null,supported:null};const hit=catalog.find((b)=>matchesDefault(b,defaultId));if(hit)return{raw:defaultId,id:hit.id,label:hit.label,supported:true};const other=NON_CHROMIUM_DEFAULTS.find((b)=>b.match.some((m)=>defaultId===m||defaultId.startsWith(m)));return other?{raw:defaultId,id:other.id,label:other.label,supported:false}:{raw:defaultId,id:null,label:defaultId,supported:false}}function candidateRow(browser,{defaultBrowser,running,lastUsed},now){const isDefault=defaultBrowser.id===browser.id;const isRunning=Array.isArray(running)?browser.processNames.some((n)=>running.includes(n)||running.includes(n.toLowerCase())):null;const last=lastUsed?.[browser.id]??null;const recentlyUsed=last!==null&&now-last<=RECENT_USE_MS;const signals=[isDefault&&"default browser",isRunning&&"running now",recentlyUsed&&"used in the last 7 days"].filter(Boolean);return{id:browser.id,label:browser.label,installed:browser.installed,isDefault,running:isRunning,lastUsedAt:last===null?null:new Date(last).toISOString(),recentlyUsed,signals,browser}}function choose(candidates,primary,confidence,reason,defaultBrowser){return{primary:primary.browser,primaryId:primary.id,confidence,needsChoice:false,reason,defaultBrowser,candidates:candidates.map(({browser,...row})=>row)}}function ask(candidates,reason,defaultBrowser,suggested=null){return{primary:null,primaryId:null,confidence:null,needsChoice:true,reason,suggested,defaultBrowser,candidates:candidates.map(({browser,...row})=>row)}}function identifyBrowser({catalog,signals={},explicit=null,now=Date.now()}){const defaultBrowser=describeDefault(signals.defaultBrowser??null,catalog);const installed=catalog.filter((b)=>b.installed||b.id===explicit);const candidates=installed.map((b)=>candidateRow(b,{defaultBrowser,running:signals.running??null,lastUsed:signals.lastUsed},now));if(explicit){const hit=candidates.find((c)=>c.id===explicit);if(hit)return choose(candidates,hit,"explicit",`${hit.label} was chosen explicitly`,defaultBrowser);return ask(candidates,`"${explicit}" is not a Chromium-family browser this library knows; pick one of the candidates`,defaultBrowser)}if(candidates.length===0)return ask(candidates,"no Chromium-family browser is installed",defaultBrowser);const inUse=candidates.filter((c)=>c.running||c.recentlyUsed);const def=candidates.find((c)=>c.isDefault);if(def&&(def.running||def.recentlyUsed))return choose(candidates,def,"default-and-in-use",`${def.label} is the default browser and ${def.signals.slice(1).join(", ")}`,defaultBrowser);if(def&&inUse.length===0)return choose(candidates,def,"default",`${def.label} is the default browser`,defaultBrowser);if(def)return ask(candidates,`${def.label} is the default browser, but ${inUse.map((c)=>c.label).join(" and ")} ${inUse.length===1?"is":"are"} the one in use`,defaultBrowser);if(defaultBrowser.supported===false){const suggested=inUse.length===1?inUse[0].id:null;return ask(candidates,`the default browser is ${defaultBrowser.label}, which BrowserSkill cannot drive; the user has to name the Chromium browser to use`,defaultBrowser,suggested)}const runningNow=inUse.filter((c)=>c.running);if(inUse.length===1)return choose(candidates,inUse[0],"only-in-use",`${inUse[0].label} is the only browser ${inUse[0].signals.join(", ")}`,defaultBrowser);if(runningNow.length===1)return choose(candidates,runningNow[0],"only-running",`${runningNow[0].label} is the only browser running now`,defaultBrowser);if(inUse.length===0&&candidates.length===1)return choose(candidates,candidates[0],"only-installed",`${candidates[0].label} is the only Chromium-family browser installed`,defaultBrowser);return ask(candidates,inUse.length>1?`several browsers are in use (${inUse.map((c)=>c.label).join(", ")})`:"no browser shows recent use",defaultBrowser)}import{existsSync as existsSync5,readFileSync as readFileSync5,rmSync as rmSync3,writeFileSync as writeFileSync3}from"node:fs";import{homedir as homedir5}from"node:os";import path13 from"node:path";import{spawn as spawn5}from"node:child_process";var INSTALL_SH="https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.sh";var INSTALL_PS1="https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.ps1";var RC_FILES=[".zshrc",".bashrc",".profile"];function cliInstallCommand({platform=process.platform,installDir,version}={}){const env={BSK_INSTALL_DIR:installDir};if(version)env.BSK_VERSION=version;if(platform==="win32"){return{command:"powershell",args:["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${INSTALL_PS1} | iex`],env}}return{command:"sh",args:["-c",`curl -fsSL ${INSTALL_SH} | sh`],env}}function runDefault2(command,args,env){return new Promise((resolve)=>{const child=spawn5(command,args,{env:{...process.env,...env},stdio:["ignore","pipe","pipe"],windowsHide:true});let stdout="",stderr="";child.stdout.on("data",(c)=>{stdout=(stdout+c).slice(-8192)});child.stderr.on("data",(c)=>{stderr=(stderr+c).slice(-8192)});child.on("error",(error)=>resolve({code:-1,stdout,stderr:error.message}));child.on("exit",(code)=>resolve({code,stdout,stderr}))})}function snapshotRcFiles(home){const snapshot=new Map;for(const name of RC_FILES){const file=path13.join(home,name);snapshot.set(file,existsSync5(file)?readFileSync5(file):null)}return snapshot}function restoreRcFiles(snapshot){const restored=[];for(const[file,before]of snapshot){const after=existsSync5(file)?readFileSync5(file):null;if(before===null&&after===null)continue;if(before!==null&&after!==null&&before.equals(after))continue;if(before===null)rmSync3(file,{force:true});else writeFileSync3(file,before);restored.push(file)}return restored}async function installBskCli({platform=process.platform,home=homedir5(),installDir=path13.join(home,".local","bin"),version,run=runDefault2}={}){const spec=cliInstallCommand({platform,installDir,version});const rcBefore=platform==="win32"?new Map:snapshotRcFiles(home);const result=await run(spec.command,spec.args,spec.env);const restoredRcFiles=restoreRcFiles(rcBefore);const bskBin=path13.join(installDir,platform==="win32"?"bsk.exe":"bsk");const installed=result.code===0&&existsSync5(bskBin);return{installed,bskBin:installed?bskBin:null,code:result.code,stdout:result.stdout,stderr:result.stderr,restoredRcFiles}}function cliVersionDefault(bskBin){return new Promise((resolve)=>{const child=spawn5(bskBin,["--version"],{stdio:["ignore","pipe","ignore"],windowsHide:true});let out="";child.stdout.on("data",(c)=>{out+=c});child.on("error",()=>resolve(null));child.on("exit",(code)=>resolve(code===0?out.trim():null))})}import{homedir as homedir6}from"node:os";import{existsSync as existsSync6,readFileSync as readFileSync6}from"node:fs";var DEFAULT_WAIT_TOTAL_MS=180000;function resolveBskBin(bskBin,env){if(bskBin===null)return null;return bskBin??findBskBinary(env)}async function cliReport({bskBin,env,cliVersion}){const bin=resolveBskBin(bskBin,env);if(!bin)return{installed:false,bskBin:null,version:null};const raw=await cliVersion(bin);return raw?{installed:true,bskBin:bin,version:raw.replace(/^bsk\s+/,"")}:{installed:false,bskBin:bin,version:null}}async function daemonReport(client,waitForBrowserMs){try{const status=await client.call("system.status",waitForBrowserMs>0?{wait_for_browser_ms:waitForBrowserMs}:{},{idPrefix:"status"});return{running:true,version:status.daemon_version,protocolVersion:status.protocol_version,browsers:status.browsers??[],sessions:status.sessions??[]}}catch(error){return{running:false,error:error.message,code:error.code,browsers:[],sessions:[]}}}var NO_BROWSER_STEP=`No Chromium-family browser was found. Install one (Chrome, Edge, Brave, Arc, ...), then add the extension from ${STORE_PAGE_URLS.chrome}.`;function withRegistration(platform,browser){const entry=externalExtensionEntry({platform,browser});const extensionRegistered=entry.kind==="file"&&existsSync6(entry.path)&&readFileSync6(entry.path,"utf8")===entry.content;return{...browser,registration:entry,extensionRegistered}}async function identify({platform,home,env,exists,browser,signals,probeSignals,now}){const catalog=catalogBrowsers({platform,home,env,exists}).map((b)=>withRegistration(platform,b));const observed=signals??await probeSignals({platform,home,browsers:catalog.filter((b)=>b.hasProfile)});const explicit=browser??env.OMOWRIGHT_BROWSER??null;const{primary,...identification}=identifyBrowser({catalog,signals:observed,explicit:explicit||null,now});const browsers=catalog.filter((b)=>b.installed);const registeredElsewhere=browsers.filter((b)=>b.extensionRegistered&&b.id!==identification.primaryId).map((b)=>b.id);return{browsers,identification:{...identification,registeredElsewhere},primary}}function choiceStep(identification){const listed=identification.candidates.map((c)=>`${c.label} [${c.id}]${c.signals.length?` — ${c.signals.join(", ")}`:""}`).join("; ");const hint=identification.suggested?` Likely ${identification.suggested}, but confirm first.`:"";return`Ask the user which browser they actually use (${identification.reason}). Candidates: ${listed}.${hint} Then re-run with browser: "<id>"; register nothing until they answer.`}function nextStepFor({cli,daemon,browsers,browsersConnected,identification,primary}){if(browsersConnected.length>0)return null;if(!cli.installed)return"Install the bsk CLI (bskOnboard() runs the official installer).";if(!daemon.running)return"Start the BrowserSkill daemon: run `bsk status` once, or `bsk daemon start` in the environment that owns it.";if(browsers.length===0&&!primary)return NO_BROWSER_STEP;if(identification.needsChoice)return choiceStep(identification);if(!primary.extensionRegistered&&primary.registration.kind!=="store")return`Register the BrowserSkill extension for ${primary.label} (bskOnboard() does this), then let the user enable it.`;return primary.registration.humanStep}async function bskDoctor({platform=process.platform,home=homedir6(),env=process.env,client,bskBin,cliVersion=cliVersionDefault,waitForBrowserMs=0,exists=existsSync6,browser,signals,probeSignals=probeBrowserSignals,now=Date.now()}={}){const cli=await cliReport({bskBin,env,cliVersion});const ipc=client??new BskIpcClient({env,bskBin:cli.bskBin??undefined,autoStart:false});const daemon=await daemonReport(ipc,waitForBrowserMs);const{browsers,identification,primary}=await identify({platform,home,env,exists,browser,signals,probeSignals,now});const browsersConnected=daemon.browsers;const report={cli,daemon,browsers,primary:primary??null,identification,browsersConnected,ready:browsersConnected.length>0};report.nextStep=nextStepFor(report);return report}async function bskOnboard({platform=process.platform,home=homedir6(),env=process.env,client,bskBin,installDir,installCli=installBskCli,cliVersion=cliVersionDefault,onHumanStep=()=>{},waitForBrowserMs=15000,waitTotalMs=DEFAULT_WAIT_TOTAL_MS,exists=existsSync6,browser,signals,probeSignals=probeBrowserSignals,now=Date.now()}={}){let cli=await cliReport({bskBin,env,cliVersion});let install=null;if(!cli.installed){install=await installCli({platform,home,installDir});cli=install.installed?await cliReport({bskBin:install.bskBin,env,cliVersion}):cli}const ipc=client??new BskIpcClient({env,bskBin:cli.bskBin??undefined,autoStart:true});let daemon=await daemonReport(ipc,0);const{browsers,identification,primary}=await identify({platform,home,env,exists,browser,signals,probeSignals,now});const registrations=[];let humanStep=null;let needsChoice=false;if(daemon.browsers.length===0){if(browsers.length===0&&!primary){humanStep=NO_BROWSER_STEP}else if(identification.needsChoice){needsChoice=true;humanStep=choiceStep(identification)}else{const registration=await registerExternalExtension({platform,browser:primary});registrations.push({browser:primary.id,...registration});humanStep=registration.humanStep;onHumanStep({browser:primary.id,step:registration.humanStep,registered:registration.registered,needsRestart:registration.needsRestart})}}const deadline=Date.now()+waitTotalMs;let browsersConnected=daemon.browsers;while(!needsChoice&&browsersConnected.length===0&&daemon.running&&Date.now()<deadline){browsersConnected=await listBrowsers(ipc,{waitForBrowserMs});if(waitForBrowserMs===0)break}daemon={...daemon,browsers:browsersConnected};const ready=browsersConnected.length>0;return{cli,install,daemon,browsers,primary:primary??null,identification,needsChoice,registrations,humanStep:ready?null:humanStep,browsersConnected,ready}}export{AgentTabManager,BROWSERSKILL_EXTENSION_IDS,BROWSER_EVENT_NAMES,BridgeProtocolError,BridgeUnavailableError,BrowserCdpCommandError,BrowserConnection,BskIpcClient,BskRpcError,BskSession,CdpClient,CommandSchema,DEFAULT_AGENT_VIEWPORT,DEVICE_PRESETS,ElementHandle,EventSchema,ExtensionHelloSchema,FrameLocator,FrameManager,HostHelloSchema,Locator,ModifierState,OmOKeyboard,OmOMouse,OmOPage,PipeCdpClient,ResponseSchema,STORE_PAGE_URLS,SessionManager,TabRepository,UnsupportedOperationError,bskDoctor,bskOnboard,bskSnapshot,buildCloakBrowserArgs,buildSnapshotExpression,catalogBrowsers,collectWhileScrolling,compactSnapshot,connect,connectBrowserSkill,connectCloakProfile,connectPipe,createAgentTabs,createBridgeClient,createCaptcha,createChromeApi2 as createChromeApi,createCua,createEvents,createNativeMessagingHost,createNetworkSnoop,createRoutes,createTrace,decodeFrames,describeLayers,detectBrowsers,emulate,encodeFrame,externalExtensionEntry,findCloakBrowserPath,identifyBrowser,injectCookies,installBskCli,installNativeMessagingHost,layersHeader,listBrowsers,macOSVisionOcr,normalizeDialogPolicy,pageBundle,probeBrowserSignals,readDaemonInfo,reconcileFrames,registerExternalExtension,repinViewport,requestHuman,resolveBskHome,resolveCloakProfile,resolveDialogAction,sanitizeCookies,snapshotTokens,snapshotWithFrames,snapshotWithLayers,takeSnapshot,toHar,toolSchemas,unregisterExternalExtension};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.0.1",
|
|
3
|
-
"sourceDigest": "
|
|
3
|
+
"sourceDigest": "167dcc331041e909a54c6e9695ea8d09bbb96bc351d62333d7ac628f780b83f6",
|
|
4
4
|
"files": {
|
|
5
|
-
"index.js": "
|
|
5
|
+
"index.js": "b6b064fab277031c6c51f5a58b84b31040f9960bf767bf646adc0540c1d25c1b",
|
|
6
6
|
"page-bundle.js": "bfd51e8383cf47200d57387bbbed258bce5a3a3d00c38fc108034d2888e23f0c"
|
|
7
7
|
},
|
|
8
|
-
"stagedAtUtc": "2026-09-
|
|
8
|
+
"stagedAtUtc": "2026-09-24T23:43:38.269Z"
|
|
9
9
|
}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { loadOmowright } from "./omowright.mjs"
|
|
3
3
|
|
|
4
4
|
const { entry, omowright } = await loadOmowright()
|
|
5
|
-
const
|
|
5
|
+
const browserArg = process.argv.find((arg) => arg.startsWith("--browser="))
|
|
6
|
+
const report = await omowright.bskDoctor({ waitForBrowserMs: 0, browser: browserArg ? browserArg.slice("--browser=".length) : undefined })
|
|
6
7
|
|
|
7
8
|
const state = report.ready
|
|
8
9
|
? "ready"
|
|
@@ -10,15 +11,18 @@ const state = report.ready
|
|
|
10
11
|
? "no-cli"
|
|
11
12
|
: !report.daemon.running
|
|
12
13
|
? "no-daemon"
|
|
13
|
-
: report.browsers.length === 0
|
|
14
|
+
: report.browsers.length === 0 && !report.primary
|
|
14
15
|
? "no-browser-support"
|
|
15
|
-
:
|
|
16
|
+
: report.identification.needsChoice
|
|
17
|
+
? "choose-browser"
|
|
18
|
+
: "no-extension"
|
|
16
19
|
|
|
17
20
|
const REMEDIES = {
|
|
18
21
|
ready: "Attached engine is live: const { connectBrowserSkill } = await import(omowrightEntry); const session = await connectBrowserSkill({ name: \"<task>\", focused: false })",
|
|
19
22
|
"no-cli": "Run node \"<skill-root>/scripts/browser-install.mjs\" — it installs the CLI, starts the daemon and registers the extension; then tell the user the single step it prints.",
|
|
20
23
|
"no-daemon": "Run node \"<skill-root>/scripts/browser-install.mjs\" (it starts the daemon through `bsk status`), then re-run this doctor.",
|
|
21
24
|
"no-extension": report.nextStep ?? "Register the extension with browser-install.mjs, then relay its human step to the user and re-run this doctor.",
|
|
25
|
+
"choose-browser": `Do not install anything yet. First check your memory for the browser this user works in; if it names one of the candidates, re-run with --browser=<id>. Otherwise ask the user which browser they actually use (${report.identification.reason}), record the answer in memory, then run node "<skill-root>/scripts/browser-install.mjs" --browser=<id>.`,
|
|
22
26
|
"no-browser-support": "No Chromium-family browser profile was found on this machine. Say so and stop; do not substitute another engine.",
|
|
23
27
|
}
|
|
24
28
|
|
|
@@ -27,6 +31,10 @@ const summary = {
|
|
|
27
31
|
omowright: entry,
|
|
28
32
|
cli: report.cli,
|
|
29
33
|
daemon: { running: report.daemon.running, version: report.daemon.version ?? null, protocolVersion: report.daemon.protocolVersion ?? null, error: report.daemon.error ?? null },
|
|
34
|
+
browser: report.primary ? { id: report.primary.id, label: report.primary.label, confidence: report.identification.confidence, reason: report.identification.reason } : null,
|
|
35
|
+
candidates: report.identification.candidates.map((c) => ({ id: c.id, label: c.label, signals: c.signals })),
|
|
36
|
+
defaultBrowser: report.identification.defaultBrowser,
|
|
37
|
+
registeredElsewhere: report.identification.registeredElsewhere,
|
|
30
38
|
browsersDetected: report.browsers.map((browser) => ({ id: browser.id, userDataDir: browser.userDataDir, extensionRegistered: browser.extensionRegistered })),
|
|
31
39
|
browsersConnected: report.browsersConnected.map((browser) => ({ instanceId: browser.instance_id, name: browser.browser_name, version: browser.browser_version })),
|
|
32
40
|
nextStep: report.nextStep,
|
|
@@ -40,6 +48,9 @@ if (process.argv.includes("--json")) {
|
|
|
40
48
|
console.log(`omowright: ${entry}`)
|
|
41
49
|
console.log(`cli: ${report.cli.installed ? `${report.cli.bskBin} (${report.cli.version})` : "not installed"}`)
|
|
42
50
|
console.log(`daemon: ${report.daemon.running ? `running (${report.daemon.version}, protocol ${report.daemon.protocolVersion})` : `not running${report.daemon.error ? ` — ${report.daemon.error}` : ""}`}`)
|
|
51
|
+
console.log(`browser the user uses: ${summary.browser ? `${summary.browser.label} [${summary.browser.id}] (${summary.browser.reason})` : `not identified (${report.identification.reason})`}`)
|
|
52
|
+
console.log(`candidates: ${summary.candidates.map((c) => `${c.id}${c.signals.length ? ` (${c.signals.join(", ")})` : ""}`).join(", ") || "none"}`)
|
|
53
|
+
if (summary.registeredElsewhere.length > 0) console.log(`extension entries left in other browsers: ${summary.registeredElsewhere.join(", ")} (not removed automatically)`)
|
|
43
54
|
console.log(`browsers detected: ${summary.browsersDetected.map((b) => `${b.id}${b.extensionRegistered ? " (extension registered)" : ""}`).join(", ") || "none"}`)
|
|
44
55
|
console.log(`browsers connected: ${summary.browsersConnected.map((b) => `${b.name} ${b.version} [${b.instanceId}]`).join(", ") || "none"}`)
|
|
45
56
|
console.log(`\n${REMEDIES[state]}`)
|
|
@@ -4,10 +4,13 @@ import { loadOmowright } from "./omowright.mjs"
|
|
|
4
4
|
const json = process.argv.includes("--json")
|
|
5
5
|
const waitArg = process.argv.find((arg) => arg.startsWith("--wait-ms="))
|
|
6
6
|
const waitTotalMs = waitArg ? Number(waitArg.slice("--wait-ms=".length)) : 0
|
|
7
|
+
const browserArg = process.argv.find((arg) => arg.startsWith("--browser="))
|
|
8
|
+
const browser = browserArg ? browserArg.slice("--browser=".length) : undefined
|
|
7
9
|
|
|
8
10
|
const { omowright } = await loadOmowright()
|
|
9
11
|
const steps = []
|
|
10
12
|
const result = await omowright.bskOnboard({
|
|
13
|
+
browser,
|
|
11
14
|
onHumanStep: (step) => steps.push(step),
|
|
12
15
|
waitForBrowserMs: waitTotalMs > 0 ? Math.min(15_000, waitTotalMs) : 0,
|
|
13
16
|
waitTotalMs,
|
|
@@ -18,6 +21,10 @@ const summary = {
|
|
|
18
21
|
cli: result.cli,
|
|
19
22
|
installerRan: result.install !== null,
|
|
20
23
|
daemon: { running: result.daemon.running, version: result.daemon.version ?? null, error: result.daemon.error ?? null },
|
|
24
|
+
browser: result.primary ? { id: result.primary.id, label: result.primary.label, confidence: result.identification.confidence, reason: result.identification.reason } : null,
|
|
25
|
+
needsChoice: result.needsChoice,
|
|
26
|
+
candidates: result.identification.candidates.map((c) => ({ id: c.id, label: c.label, signals: c.signals })),
|
|
27
|
+
registeredElsewhere: result.identification.registeredElsewhere,
|
|
21
28
|
registrations: result.registrations.map((r) => ({ browser: r.browser, registered: r.registered, alreadyPresent: r.alreadyPresent ?? false, reason: r.reason ?? null, needsRestart: r.needsRestart ?? null, humanStep: r.humanStep ?? null })),
|
|
22
29
|
browsersConnected: result.browsersConnected.map((b) => ({ instanceId: b.instance_id, name: b.browser_name, version: b.browser_version })),
|
|
23
30
|
humanStep: result.humanStep,
|
|
@@ -30,9 +37,14 @@ if (json) {
|
|
|
30
37
|
} else {
|
|
31
38
|
console.log(`cli: ${result.cli.installed ? `${result.cli.bskBin} (${result.cli.version})` : "install failed"}`)
|
|
32
39
|
console.log(`daemon: ${result.daemon.running ? "running" : `not running${result.daemon.error ? ` — ${result.daemon.error}` : ""}`}`)
|
|
40
|
+
console.log(summary.browser ? `browser: ${summary.browser.label} [${summary.browser.id}] (${summary.browser.reason})` : `browser: not identified (${result.identification.reason})`)
|
|
33
41
|
for (const r of summary.registrations) {
|
|
34
42
|
console.log(`extension for ${r.browser}: ${r.registered ? (r.alreadyPresent ? "already registered" : "registered") : `not registered (${r.reason})`}`)
|
|
35
43
|
}
|
|
36
|
-
|
|
44
|
+
if (result.needsChoice) {
|
|
45
|
+
console.log(`\nNothing was registered. ${result.humanStep}\nRe-run: node "<skill-root>/scripts/browser-install.mjs" --browser=<id>`)
|
|
46
|
+
} else {
|
|
47
|
+
console.log(`\nTell the user exactly this, then re-run browser-doctor.mjs:\n ${result.humanStep}`)
|
|
48
|
+
}
|
|
37
49
|
}
|
|
38
50
|
process.exitCode = result.ready ? 0 : 2
|