lazycodex-ai 5.0.0-beta.82 → 5.0.0-beta.84
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 +2 -2
- package/README.ko.md +2 -2
- package/README.md +4 -4
- package/README.ru.md +2 -2
- package/README.zh-cn.md +2 -2
- package/dist/cli/index.js +707 -146
- package/dist/cli/install-native/index.d.ts +4 -0
- package/dist/cli/install-native/plan.d.ts +11 -0
- package/dist/cli/install-native/run-native-install.d.ts +23 -0
- package/dist/cli/install-native-dev/index.d.ts +4 -0
- package/dist/cli/native-dev-platform-flag.d.ts +5 -0
- package/dist/cli/native-edition-hint.d.ts +10 -0
- package/dist/cli/types.d.ts +3 -2
- package/dist/cli-node/index.js +707 -146
- package/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +84 -11
- 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/lcx/skills/lcx-contribute-bug-fix/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +3 -3
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/SKILL.md +5 -5
- 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/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/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +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/dist/cli.js +24 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +8 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +21 -4
- 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/components/ulw-loop/src/spawn-guard.ts +10 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +24 -6
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard-native-reviewer.test.ts +207 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +6 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +43 -4
- 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/skills/browser/ATTRIBUTION.md +25 -0
- package/packages/omo-codex/plugin/skills/browser/SKILL.md +89 -0
- package/packages/omo-codex/plugin/skills/browser/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/browser/references/commands.md +90 -0
- package/packages/omo-codex/plugin/skills/browser/references/install.md +71 -0
- package/packages/omo-codex/plugin/skills/browser/references/owned-engine/README.md +42 -0
- package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +39 -0
- package/packages/omo-codex/plugin/skills/browser/references/owned-engine/ladder.md +59 -0
- package/packages/omo-codex/plugin/skills/browser/references/owned-engine/network.md +42 -0
- package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +59 -0
- package/packages/omo-codex/plugin/skills/browser/references/remote.md +24 -0
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +41 -0
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-env.mjs +41 -0
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +51 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +5 -5
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +90 -17
- package/packages/shared-skills/skills/browser/ATTRIBUTION.md +25 -0
- package/packages/shared-skills/skills/browser/SKILL.md +89 -0
- package/packages/shared-skills/skills/browser/references/commands.md +90 -0
- package/packages/shared-skills/skills/browser/references/install.md +71 -0
- package/packages/shared-skills/skills/browser/references/owned-engine/README.md +42 -0
- package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +39 -0
- package/packages/shared-skills/skills/browser/references/owned-engine/ladder.md +59 -0
- package/packages/shared-skills/skills/browser/references/owned-engine/network.md +42 -0
- package/packages/shared-skills/skills/browser/references/recipes/1password.md +59 -0
- package/packages/shared-skills/skills/browser/references/remote.md +24 -0
- package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +41 -0
- package/packages/shared-skills/skills/browser/scripts/browser-env.mjs +41 -0
- package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +51 -0
- package/dist/cli/install-senpi/index.d.ts +0 -1
- package/dist/cli/senpi-edition-hint.d.ts +0 -10
- package/dist/cli/senpi-platform-flag.d.ts +0 -4
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Read the network, not the DOM
|
|
2
|
+
|
|
3
|
+
When a page renders a list, a table, or search results, the data almost always arrived as JSON one
|
|
4
|
+
request earlier. That JSON is complete, typed, free of markup, and immune to the layout changing
|
|
5
|
+
next week. Watching traffic costs nothing on a target you own, and the page cannot observe it.
|
|
6
|
+
|
|
7
|
+
**Snoop before you scrape.** Scroll-and-parse is the fallback, not the default.
|
|
8
|
+
|
|
9
|
+
## Wait for a request, never for a clock
|
|
10
|
+
|
|
11
|
+
A fixed sleep is a guess that fails on a slower machine and wastes time on a faster one. Subscribe
|
|
12
|
+
to the response you expect **before** triggering the action, then await that signal with a bounded
|
|
13
|
+
timeout. This is the same rule that governs test code, for the same reason.
|
|
14
|
+
|
|
15
|
+
## Collecting through infinite scroll
|
|
16
|
+
|
|
17
|
+
Drive scroll and extraction as a generator: scroll, collect what is new, stop on a target count or
|
|
18
|
+
a scroll ceiling. Bound both, so a page that keeps producing cannot run forever.
|
|
19
|
+
|
|
20
|
+
## Flight traces
|
|
21
|
+
|
|
22
|
+
For QA evidence, record a trace: one entry per step with before/after screenshots, the network
|
|
23
|
+
log, and console output, written as a line-delimited log plus an HAR. That triple is what makes a
|
|
24
|
+
failure reconstructable afterwards instead of re-runnable-in-theory.
|
|
25
|
+
|
|
26
|
+
Cap recorded body sizes. An untrimmed trace of a media-heavy page is mostly bytes nobody reads.
|
|
27
|
+
|
|
28
|
+
## Request interception
|
|
29
|
+
|
|
30
|
+
Route matching by glob, regular expression, or predicate lets you stub an endpoint, fail one
|
|
31
|
+
request to test an error path, or block third-party noise. Enable interception on the first route
|
|
32
|
+
and disable it on dispose — leaving it on slows every later navigation.
|
|
33
|
+
|
|
34
|
+
## Cookies
|
|
35
|
+
|
|
36
|
+
Injecting a cookie export into your own profile is legitimate for ordinary sessions and useless
|
|
37
|
+
for the ones you most want: accounts whose risk engines bind a session to a device will invalidate
|
|
38
|
+
it, and a password manager's session is tab-bound and never portable. Sanitize what you do inject
|
|
39
|
+
(drop expired entries, keep host-prefixed cookies secure and root-scoped).
|
|
40
|
+
|
|
41
|
+
**Never copy a session out of the user's real browser profile.** If you need their login, that is
|
|
42
|
+
the attached engine's job.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Reading a 1Password vault the user has unlocked
|
|
2
|
+
|
|
3
|
+
Scope: reading an item out of a vault **the user has already unlocked in their browser**. Signing
|
|
4
|
+
in is the user's job; see "Not in scope" below.
|
|
5
|
+
|
|
6
|
+
## The fact that shapes everything
|
|
7
|
+
|
|
8
|
+
1Password web is zero-knowledge. The unlocked vault key lives in **one tab's `sessionStorage`**,
|
|
9
|
+
not in a cookie. So:
|
|
10
|
+
|
|
11
|
+
- A **new** tab pointed at the vault redirects to the sign-in page even while a signed-in tab sits
|
|
12
|
+
right beside it. Opening your own tab does not work and never will.
|
|
13
|
+
- Navigating the authenticated tab away, or closing it, **destroys the session** until a human
|
|
14
|
+
signs in again.
|
|
15
|
+
|
|
16
|
+
Therefore: borrow the existing tab, read, return it. Do not open, do not navigate away, do not
|
|
17
|
+
"refresh to fix" anything.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bsk tab list --scope user # find the already-signed-in tab
|
|
21
|
+
bsk tab borrow <tab-id>
|
|
22
|
+
# ... read ...
|
|
23
|
+
bsk tab return <tab-id>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Check liveness by URL, never by title
|
|
27
|
+
|
|
28
|
+
The app mutates its URL hash without updating the document title, so a signed-in vault can still
|
|
29
|
+
report a sign-in title. A live session's `location.href` contains the app path and never the
|
|
30
|
+
sign-in path. Read the URL.
|
|
31
|
+
|
|
32
|
+
## The browser may be shared
|
|
33
|
+
|
|
34
|
+
Other automation may be driving the same window.
|
|
35
|
+
|
|
36
|
+
- **Clear the search box before typing.** It often holds someone else's query, and typing alone
|
|
37
|
+
appends to it, returning confident results for the wrong search.
|
|
38
|
+
- **Read the autocomplete listbox, not the results grid.** The grid holds whatever query was last
|
|
39
|
+
committed, possibly by another actor. Scraping every option on the page silently merges two
|
|
40
|
+
different searches.
|
|
41
|
+
- **Leave the tab on the item list** when you are done, so the next actor starts clean.
|
|
42
|
+
|
|
43
|
+
## If it is locked
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bsk request-help --session <id> --prompt "Please unlock 1Password in this tab, then continue."
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then observe again.
|
|
50
|
+
|
|
51
|
+
## Not in scope
|
|
52
|
+
|
|
53
|
+
- **Do not type a master password, and do not automate the sign-in form.** Only the account owner
|
|
54
|
+
signs in. If the vault is locked, hand it to them.
|
|
55
|
+
- **Do not extract secrets through the page** beyond the single value the user asked for, and
|
|
56
|
+
report it masked (`abcd…9fb0 (len 37)`) unless they asked for the exact string.
|
|
57
|
+
- **Do not copy, inject, or reuse session cookies.** The session is device- and tab-bound; cookie
|
|
58
|
+
reuse cannot work and trips account protections.
|
|
59
|
+
- Clear the clipboard if you ever populate it.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Agent here, browser there
|
|
2
|
+
|
|
3
|
+
The agent and the browser do not have to be the same machine. Upstream supports this directly;
|
|
4
|
+
nothing in this package needs to bridge it.
|
|
5
|
+
|
|
6
|
+
Shape:
|
|
7
|
+
|
|
8
|
+
- The **browser machine** needs only the extension.
|
|
9
|
+
- The **agent machine** runs the `bsk` CLI and this skill.
|
|
10
|
+
- They are joined by a daemon in server mode plus a pairing link.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bsk daemon start --mode server # on the machine the agent runs on
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then follow upstream's pairing guide, which owns the current flag surface and the TLS
|
|
17
|
+
prerequisites: https://github.com/Tencent/BrowserSkill/blob/main/docs/remote-extension-connection.md
|
|
18
|
+
|
|
19
|
+
Once paired, every command in `commands.md` behaves identically; `--out` paths still resolve on
|
|
20
|
+
the machine that ran the command.
|
|
21
|
+
|
|
22
|
+
If pairing is not configured, say so and ask. Do not substitute a browser on the agent machine:
|
|
23
|
+
the point of the attached engine is the sessions that live in the user's browser, and a local
|
|
24
|
+
browser has none of them.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { platform } from "node:os"
|
|
3
|
+
import { connectedBrowsers, readStatus, resolveCli, STORE_LISTINGS, SUPPORTED_PLATFORMS } from "./browser-env.mjs"
|
|
4
|
+
|
|
5
|
+
const REMEDIES = {
|
|
6
|
+
ready: "Start a session: bsk session start --json --no-focus --name \"<task>\"",
|
|
7
|
+
"no-extension": `Ask the user to install and enable the extension, then re-run this doctor.\n Chrome: ${STORE_LISTINGS.chrome}\n Edge: ${STORE_LISTINGS.edge}`,
|
|
8
|
+
"no-cli": "Install the CLI: node \"<skill-root>/scripts/browser-install.mjs\", then re-run this doctor.",
|
|
9
|
+
"no-browser-support": "This platform has no supported browser. Say so and stop; do not substitute another engine.",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function diagnose() {
|
|
13
|
+
if (!SUPPORTED_PLATFORMS.has(platform())) {
|
|
14
|
+
return { state: "no-browser-support", platform: platform() }
|
|
15
|
+
}
|
|
16
|
+
const cli = await resolveCli()
|
|
17
|
+
if (cli === undefined) return { state: "no-cli", platform: platform() }
|
|
18
|
+
|
|
19
|
+
let status
|
|
20
|
+
try {
|
|
21
|
+
status = await readStatus(cli)
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return { state: "no-extension", platform: platform(), cli, detail: `status failed: ${error.message}` }
|
|
24
|
+
}
|
|
25
|
+
const browsers = connectedBrowsers(status)
|
|
26
|
+
if (browsers.length === 0) return { state: "no-extension", platform: platform(), cli }
|
|
27
|
+
return { state: "ready", platform: platform(), cli, browsers: browsers.length }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const report = await diagnose()
|
|
31
|
+
const json = process.argv.includes("--json")
|
|
32
|
+
if (json) {
|
|
33
|
+
console.log(JSON.stringify({ ...report, remedy: REMEDIES[report.state] }, null, 2))
|
|
34
|
+
} else {
|
|
35
|
+
console.log(`state: ${report.state}`)
|
|
36
|
+
if (report.cli) console.log(`cli: ${report.cli}`)
|
|
37
|
+
if (report.browsers) console.log(`browsers connected: ${report.browsers}`)
|
|
38
|
+
if (report.detail) console.log(`detail: ${report.detail}`)
|
|
39
|
+
console.log(`\n${REMEDIES[report.state]}`)
|
|
40
|
+
}
|
|
41
|
+
process.exit(report.state === "ready" ? 0 : 1)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { execFile } from "node:child_process"
|
|
2
|
+
import { existsSync } from "node:fs"
|
|
3
|
+
import { homedir, platform } from "node:os"
|
|
4
|
+
import { join } from "node:path"
|
|
5
|
+
import { promisify } from "node:util"
|
|
6
|
+
|
|
7
|
+
const run = promisify(execFile)
|
|
8
|
+
|
|
9
|
+
export const STORE_LISTINGS = {
|
|
10
|
+
chrome: "https://chromewebstore.google.com/detail/hhcmgoofomhgciiibhipgmgkgnoenaoi",
|
|
11
|
+
edge: "https://microsoftedge.microsoft.com/addons/detail/browserskill/emacgiaaaiojkkpkddmmdfhmokgmnikg",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const SUPPORTED_PLATFORMS = new Set(["darwin", "linux", "win32"])
|
|
15
|
+
|
|
16
|
+
export function localBinCandidates() {
|
|
17
|
+
const bin = join(homedir(), ".local", "bin")
|
|
18
|
+
return platform() === "win32" ? [join(bin, "bsk.exe"), join(bin, "bsk")] : [join(bin, "bsk")]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function resolveCli() {
|
|
22
|
+
for (const candidate of localBinCandidates()) {
|
|
23
|
+
if (existsSync(candidate)) return candidate
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
await run("bsk", ["--version"], { timeout: 15000, windowsHide: true })
|
|
27
|
+
return "bsk"
|
|
28
|
+
} catch {
|
|
29
|
+
return undefined
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function readStatus(cli) {
|
|
34
|
+
const { stdout } = await run(cli, ["status", "--json"], { timeout: 30000, windowsHide: true })
|
|
35
|
+
return JSON.parse(stdout)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function connectedBrowsers(status) {
|
|
39
|
+
const browsers = status?.browsers
|
|
40
|
+
return Array.isArray(browsers) ? browsers : []
|
|
41
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process"
|
|
3
|
+
import { platform } from "node:os"
|
|
4
|
+
import { resolveCli, STORE_LISTINGS, SUPPORTED_PLATFORMS } from "./browser-env.mjs"
|
|
5
|
+
|
|
6
|
+
const UNIX_INSTALL = "curl -fsSL https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.sh | sh"
|
|
7
|
+
const WINDOWS_INSTALL = "irm https://raw.githubusercontent.com/Tencent/BrowserSkill/main/install.ps1 | iex"
|
|
8
|
+
|
|
9
|
+
function installCommand() {
|
|
10
|
+
return platform() === "win32"
|
|
11
|
+
? { file: "powershell", args: ["-NoProfile", "-Command", WINDOWS_INSTALL], display: WINDOWS_INSTALL }
|
|
12
|
+
: { file: "sh", args: ["-c", UNIX_INSTALL], display: UNIX_INSTALL }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function spawnInstaller({ file, args }) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
const child = spawn(file, args, { stdio: "inherit", windowsHide: true })
|
|
18
|
+
child.on("error", () => resolve(1))
|
|
19
|
+
child.on("close", (code) => resolve(code ?? 1))
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!SUPPORTED_PLATFORMS.has(platform())) {
|
|
24
|
+
console.error(`unsupported platform: ${platform()}. macOS, Linux and Windows x64 only.`)
|
|
25
|
+
process.exit(1)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (await resolveCli()) {
|
|
29
|
+
console.log("bsk is already installed; run browser-doctor.mjs to check the extension.")
|
|
30
|
+
process.exit(0)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const command = installCommand()
|
|
34
|
+
console.log(`installing the bsk CLI with the upstream installer:\n ${command.display}\n`)
|
|
35
|
+
const code = await spawnInstaller(command)
|
|
36
|
+
if (code !== 0) {
|
|
37
|
+
console.error(`\ninstaller exited ${code}. Report this instead of retrying blindly.`)
|
|
38
|
+
process.exit(code)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log([
|
|
42
|
+
"",
|
|
43
|
+
"CLI installed. Two things remain, and only the user can do the first:",
|
|
44
|
+
"",
|
|
45
|
+
"1. Install the browser extension from the store, then enable it:",
|
|
46
|
+
` Chrome: ${STORE_LISTINGS.chrome}`,
|
|
47
|
+
` Edge: ${STORE_LISTINGS.edge}`,
|
|
48
|
+
"2. Re-run: node \"<skill-root>/scripts/browser-doctor.mjs\"",
|
|
49
|
+
"",
|
|
50
|
+
"If PATH does not pick up the CLI in this shell, use its absolute path under ~/.local/bin.",
|
|
51
|
+
].join("\n"))
|
|
@@ -84,7 +84,7 @@ sync_latest_source() {
|
|
|
84
84
|
git -C "$DEST" checkout -B "$DEFAULT_BRANCH" FETCH_HEAD
|
|
85
85
|
}
|
|
86
86
|
sync_latest_source code-yeongyu/lazycodex "$LAZYCODEX_SOURCE_ROOT/lazycodex-source"
|
|
87
|
-
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/
|
|
87
|
+
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source"
|
|
88
88
|
```
|
|
89
89
|
4. Create a fresh temporary clone and branch under `${TMPDIR:-/tmp}`. Do not modify the user's current repository for the target fix unless the current repository is itself the requested target and the user explicitly asked for local edits.
|
|
90
90
|
|
|
@@ -58,7 +58,7 @@ sync_latest_source() {
|
|
|
58
58
|
git -C "$DEST" checkout -B "$DEFAULT_BRANCH" FETCH_HEAD
|
|
59
59
|
}
|
|
60
60
|
sync_latest_source code-yeongyu/lazycodex "$LAZYCODEX_SOURCE_ROOT/lazycodex-source"
|
|
61
|
-
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/
|
|
61
|
+
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source"
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
2. Inventory the installed surface. Resolve `CODEX_HOME` (default `~/.codex`), then collect:
|
|
@@ -102,7 +102,7 @@ sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/openai-codex-source"
|
|
|
102
102
|
| Plugin payload wiring | PASS/WARN/FAIL | [evidence] |
|
|
103
103
|
| Bin links / aliases | PASS/WARN/FAIL | [evidence] |
|
|
104
104
|
| Runtime probe | PASS/WARN/FAIL | [evidence] |
|
|
105
|
-
| Drift vs latest source | PASS/WARN/FAIL | [evidence, citing `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` or `$LAZYCODEX_SOURCE_ROOT/
|
|
105
|
+
| Drift vs latest source | PASS/WARN/FAIL | [evidence, citing `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` or `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source` paths] |
|
|
106
106
|
|
|
107
107
|
### Remediations
|
|
108
108
|
1. [Most important fix first: exact command or config edit, and what it resolves. When Astra readiness is WARN: upgrade Codex to 0.153.1 or newer and relaunch it once so `models_cache.json` picks up `gpt-6-astra`.]
|
|
@@ -124,7 +124,7 @@ Do not:
|
|
|
124
124
|
|
|
125
125
|
- mutate config, installs, or repositories during diagnosis
|
|
126
126
|
- report a verdict without captured evidence
|
|
127
|
-
- compare against remembered source layout instead of `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/
|
|
127
|
+
- compare against remembered source layout instead of `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source`
|
|
128
128
|
- require retired payload paths that the current `.codex-plugin/plugin.json` does not declare
|
|
129
129
|
- force a runtime-probe model unless the user explicitly passed one
|
|
130
130
|
- declare healthy while any probe output was never captured
|
|
@@ -78,14 +78,14 @@ sync_latest_source() {
|
|
|
78
78
|
git -C "$DEST" checkout -B "$DEFAULT_BRANCH" FETCH_HEAD
|
|
79
79
|
}
|
|
80
80
|
sync_latest_source code-yeongyu/lazycodex "$LAZYCODEX_SOURCE_ROOT/lazycodex-source"
|
|
81
|
-
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/
|
|
81
|
+
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source"
|
|
82
82
|
```
|
|
83
83
|
4. Follow the debugging skill far enough to gather runtime evidence:
|
|
84
84
|
- form at least three plausible hypotheses
|
|
85
85
|
- run the smallest reproduction that exercises the real surface
|
|
86
86
|
- confirm the root cause by observing the failing state
|
|
87
87
|
- identify the minimal fix path or maintainer action
|
|
88
|
-
5. Compare runtime evidence with both `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/
|
|
88
|
+
5. Compare runtime evidence with both `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source` before choosing the target repo. Cite exact files, commands, logs, or source paths that support the routing decision.
|
|
89
89
|
6. Choose the target repo:
|
|
90
90
|
- Use `code-yeongyu/lazycodex` when the bug is in LazyCodex integration, distribution, bundled plugin code, skills, hooks, MCP wiring, installer behavior, aliases, marketplace sync, docs, or any behavior that disappears in clean upstream Codex.
|
|
91
91
|
- Use `openai/codex` when the bug reproduces in clean upstream Codex without LazyCodex, or the failing behavior comes from Codex CLI core, plugin API contracts, sandboxing, approvals, config loading, or built-in tool behavior.
|
|
@@ -142,7 +142,7 @@ Write the issue body in English and keep it direct:
|
|
|
142
142
|
- Target repository:
|
|
143
143
|
- Why this belongs there:
|
|
144
144
|
- LazyCodex evidence (runtime + `$LAZYCODEX_SOURCE_ROOT/lazycodex-source`):
|
|
145
|
-
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/
|
|
145
|
+
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source`:
|
|
146
146
|
|
|
147
147
|
## Reproduction
|
|
148
148
|
1. [Exact command or UI action]
|
|
@@ -186,7 +186,7 @@ Use this only when a PR is the right artifact, which is only ever for `openai/co
|
|
|
186
186
|
- Target repository:
|
|
187
187
|
- Why this belongs there:
|
|
188
188
|
- LazyCodex evidence (runtime + `$LAZYCODEX_SOURCE_ROOT/lazycodex-source`):
|
|
189
|
-
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/
|
|
189
|
+
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source`:
|
|
190
190
|
|
|
191
191
|
## Root Cause
|
|
192
192
|
[Confirmed cause. Cite runtime evidence and source paths.]
|
|
@@ -263,6 +263,6 @@ Do not file:
|
|
|
263
263
|
- a vague issue without reproduction steps
|
|
264
264
|
- an issue that claims a root cause not supported by runtime evidence
|
|
265
265
|
- a duplicate when commenting on an existing issue is enough
|
|
266
|
-
- an issue without checking the latest `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/
|
|
266
|
+
- an issue without checking the latest `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/chatgpt-subscription-source` checkouts
|
|
267
267
|
- a LazyCodex issue when the bug is proven to reproduce in clean upstream Codex
|
|
268
268
|
- a fix PR without a concrete branch, implemented fix, and verification result
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// omo-codex-install:
|
|
2
|
+
// omo-codex-install:b1e0dfcae282bb92472824778dcf95a71e63338e183d024d83d0bf18fa3ca376:26f3e8d24b70718930a9e6c72473ecc49b02f7d7ad950f64a5622bf51679d9ea
|
|
3
3
|
var __esm = (fn, res, err) => () => {
|
|
4
4
|
if (fn)
|
|
5
5
|
try {
|
|
@@ -316,7 +316,7 @@ function shouldRetainLine(line, cutoffMs) {
|
|
|
316
316
|
function parseDiagnosticLine(line) {
|
|
317
317
|
try {
|
|
318
318
|
const parsed = JSON.parse(line);
|
|
319
|
-
if (!
|
|
319
|
+
if (!isRecord10(parsed)) {
|
|
320
320
|
return null;
|
|
321
321
|
}
|
|
322
322
|
return parsed;
|
|
@@ -327,7 +327,7 @@ function parseDiagnosticLine(line) {
|
|
|
327
327
|
throw error;
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
|
-
function
|
|
330
|
+
function isRecord10(value) {
|
|
331
331
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
332
332
|
}
|
|
333
333
|
function trimToMaxBytes(lines) {
|
|
@@ -7817,7 +7817,7 @@ function coerceBool(value) {
|
|
|
7817
7817
|
function coerceString(value) {
|
|
7818
7818
|
return typeof value == "string" ? value : undefined;
|
|
7819
7819
|
}
|
|
7820
|
-
function
|
|
7820
|
+
function isRecord11(value) {
|
|
7821
7821
|
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
7822
7822
|
}
|
|
7823
7823
|
function toRfc3339(timestamp) {
|
|
@@ -7839,7 +7839,7 @@ function relocateInto(properties, key, value) {
|
|
|
7839
7839
|
properties[key] = value;
|
|
7840
7840
|
}
|
|
7841
7841
|
function buildV1Event(message) {
|
|
7842
|
-
const sourceProperties =
|
|
7842
|
+
const sourceProperties = isRecord11(message.properties) ? message.properties : {};
|
|
7843
7843
|
const properties = {
|
|
7844
7844
|
...sourceProperties
|
|
7845
7845
|
};
|
|
@@ -9984,7 +9984,7 @@ var package_default;
|
|
|
9984
9984
|
var init_package = __esm(() => {
|
|
9985
9985
|
package_default = {
|
|
9986
9986
|
name: "@oh-my-opencode/omo-codex",
|
|
9987
|
-
version: "5.0.0-beta.
|
|
9987
|
+
version: "5.0.0-beta.84",
|
|
9988
9988
|
type: "module",
|
|
9989
9989
|
private: true,
|
|
9990
9990
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -16515,8 +16515,10 @@ var OmoGitMasterSettingsSchema = OmoGitMasterSettingsLayerSchema.extend({
|
|
|
16515
16515
|
|
|
16516
16516
|
// packages/omo-config-core/src/schema/harness.ts
|
|
16517
16517
|
var HARNESS_IDS = ["codex", "opencode", "omo"];
|
|
16518
|
-
var OMO_CONFIG_HARNESS_IDS = ["opencode", "
|
|
16518
|
+
var OMO_CONFIG_HARNESS_IDS = ["opencode", "native", "codex"];
|
|
16519
16519
|
var OmoHarnessIdSchema = _enum(OMO_CONFIG_HARNESS_IDS);
|
|
16520
|
+
var OMO_CONFIG_LEGACY_HARNESS_ALIASES = { senpi: "native" };
|
|
16521
|
+
var OMO_CONFIG_LEGACY_HARNESS_IDS = Object.keys(OMO_CONFIG_LEGACY_HARNESS_ALIASES);
|
|
16520
16522
|
|
|
16521
16523
|
// packages/omo-config-core/src/schema/memory.ts
|
|
16522
16524
|
var OmoMemoryReflectionTriggerSchema = object({
|
|
@@ -16975,6 +16977,7 @@ var OmoConfigProfileSchema = object({
|
|
|
16975
16977
|
telemetry: OmoTelemetrySettingsLayerSchema.optional(),
|
|
16976
16978
|
disabled_skills: OmoDisabledSkillsSchema.optional(),
|
|
16977
16979
|
"[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
|
|
16980
|
+
"[native]": OmoTypedHarnessConfigSchema.optional(),
|
|
16978
16981
|
"[senpi]": OmoTypedHarnessConfigSchema.optional(),
|
|
16979
16982
|
"[codex]": OmoTypedHarnessConfigSchema.optional()
|
|
16980
16983
|
}).strict();
|
|
@@ -16993,6 +16996,7 @@ var OmoConfigSchema = object({
|
|
|
16993
16996
|
telemetry: OmoTelemetrySettingsSchema.optional(),
|
|
16994
16997
|
disabled_skills: OmoDisabledSkillsSchema.optional(),
|
|
16995
16998
|
"[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
|
|
16999
|
+
"[native]": OmoTypedHarnessConfigSchema.optional(),
|
|
16996
17000
|
"[senpi]": OmoTypedHarnessConfigSchema.optional(),
|
|
16997
17001
|
"[codex]": OmoTypedHarnessConfigSchema.optional(),
|
|
16998
17002
|
profiles: record(string2(), OmoConfigProfileSchema).default({}),
|
|
@@ -17014,6 +17018,7 @@ var OmoConfigLayerSchema = object({
|
|
|
17014
17018
|
telemetry: OmoTelemetrySettingsLayerSchema.optional(),
|
|
17015
17019
|
disabled_skills: OmoDisabledSkillsSchema.optional(),
|
|
17016
17020
|
"[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
|
|
17021
|
+
"[native]": OmoTypedHarnessConfigSchema.optional(),
|
|
17017
17022
|
"[senpi]": OmoTypedHarnessConfigSchema.optional(),
|
|
17018
17023
|
"[codex]": OmoTypedHarnessConfigSchema.optional(),
|
|
17019
17024
|
profiles: record(string2(), OmoConfigProfileSchema).optional(),
|
|
@@ -17077,6 +17082,54 @@ function canonicalizeLegacyCategoryNames(document) {
|
|
|
17077
17082
|
return { document: canonicalized, renames };
|
|
17078
17083
|
}
|
|
17079
17084
|
|
|
17085
|
+
// packages/omo-config-core/src/schema/legacy-harness-names.ts
|
|
17086
|
+
function canonicalHarnessName(name) {
|
|
17087
|
+
return Object.hasOwn(OMO_CONFIG_LEGACY_HARNESS_ALIASES, name) ? OMO_CONFIG_LEGACY_HARNESS_ALIASES[name] : name;
|
|
17088
|
+
}
|
|
17089
|
+
function harnessBlockKey(harness) {
|
|
17090
|
+
return `[${harness}]`;
|
|
17091
|
+
}
|
|
17092
|
+
function legacyHarnessOfBlockKey(key) {
|
|
17093
|
+
if (!key.startsWith("[") || !key.endsWith("]"))
|
|
17094
|
+
return;
|
|
17095
|
+
const harness = key.slice(1, -1);
|
|
17096
|
+
return Object.hasOwn(OMO_CONFIG_LEGACY_HARNESS_ALIASES, harness) ? harness : undefined;
|
|
17097
|
+
}
|
|
17098
|
+
function isRecord7(value) {
|
|
17099
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17100
|
+
}
|
|
17101
|
+
function canonicalizeBlocksIn(container, path, renames) {
|
|
17102
|
+
const result = {};
|
|
17103
|
+
for (const [key, value] of Object.entries(container)) {
|
|
17104
|
+
const legacyHarness = legacyHarnessOfBlockKey(key);
|
|
17105
|
+
if (legacyHarness === undefined) {
|
|
17106
|
+
result[key] = value;
|
|
17107
|
+
continue;
|
|
17108
|
+
}
|
|
17109
|
+
const canonical = harnessBlockKey(canonicalHarnessName(legacyHarness));
|
|
17110
|
+
const dropped = Object.hasOwn(container, canonical);
|
|
17111
|
+
renames.push({ canonical, dropped, legacy: key, path: [...path, key].join(".") });
|
|
17112
|
+
if (!dropped)
|
|
17113
|
+
result[canonical] = value;
|
|
17114
|
+
}
|
|
17115
|
+
return result;
|
|
17116
|
+
}
|
|
17117
|
+
function canonicalizeLegacyHarnessBlocks(document) {
|
|
17118
|
+
if (!isRecord7(document))
|
|
17119
|
+
return { document: {}, renames: [] };
|
|
17120
|
+
const renames = [];
|
|
17121
|
+
const canonicalized = canonicalizeBlocksIn(document, [], renames);
|
|
17122
|
+
const profiles = canonicalized["profiles"];
|
|
17123
|
+
if (isRecord7(profiles)) {
|
|
17124
|
+
const canonicalProfiles = {};
|
|
17125
|
+
for (const [name, profile] of Object.entries(profiles)) {
|
|
17126
|
+
canonicalProfiles[name] = isRecord7(profile) ? canonicalizeBlocksIn(profile, ["profiles", name], renames) : profile;
|
|
17127
|
+
}
|
|
17128
|
+
canonicalized["profiles"] = canonicalProfiles;
|
|
17129
|
+
}
|
|
17130
|
+
return { document: canonicalized, renames };
|
|
17131
|
+
}
|
|
17132
|
+
|
|
17080
17133
|
// node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
17081
17134
|
function createScanner(text, ignoreTrivia = false) {
|
|
17082
17135
|
const len = text.length;
|
|
@@ -18052,7 +18105,7 @@ function resolveOmoConfigPaths(options) {
|
|
|
18052
18105
|
}
|
|
18053
18106
|
|
|
18054
18107
|
// packages/omo-config-core/src/loader/resolution.ts
|
|
18055
|
-
var HARNESS_KEYS = [...new Set([...HARNESS_IDS, ...OMO_CONFIG_HARNESS_IDS])].map((harness) =>
|
|
18108
|
+
var HARNESS_KEYS = [...new Set([...HARNESS_IDS, ...OMO_CONFIG_HARNESS_IDS, ...OMO_CONFIG_LEGACY_HARNESS_IDS])].map((harness) => harnessBlockKey(harness));
|
|
18056
18109
|
function profileName(value) {
|
|
18057
18110
|
return value === "" ? undefined : value;
|
|
18058
18111
|
}
|
|
@@ -18081,7 +18134,13 @@ function withoutControlKeys(config) {
|
|
|
18081
18134
|
function harnessLayer(config, harness) {
|
|
18082
18135
|
if (harness === undefined)
|
|
18083
18136
|
return {};
|
|
18084
|
-
|
|
18137
|
+
const canonical = canonicalHarnessName(harness);
|
|
18138
|
+
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
18139
|
+
let layer = {};
|
|
18140
|
+
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
18141
|
+
layer = mergeOmoConfigRecords(layer, toRecord(config[key]) ?? {});
|
|
18142
|
+
}
|
|
18143
|
+
return layer;
|
|
18085
18144
|
}
|
|
18086
18145
|
function resolveOmoConfigView(options) {
|
|
18087
18146
|
const profiles = toRecord(options.config["profiles"]);
|
|
@@ -18132,6 +18191,7 @@ var DEFAULT_RAW_CONFIG = {
|
|
|
18132
18191
|
function stripResolutionControlKeys(config) {
|
|
18133
18192
|
const {
|
|
18134
18193
|
"[codex]": _codex,
|
|
18194
|
+
"[native]": _native,
|
|
18135
18195
|
"[opencode]": _opencode,
|
|
18136
18196
|
"[senpi]": _senpi,
|
|
18137
18197
|
profiles: _profiles,
|
|
@@ -18157,21 +18217,21 @@ function hasUnsafeUnrecognizedKey(issues) {
|
|
|
18157
18217
|
function hasTamperedPrototype(value) {
|
|
18158
18218
|
if (Array.isArray(value))
|
|
18159
18219
|
return value.some((entry) => hasTamperedPrototype(entry));
|
|
18160
|
-
if (!
|
|
18220
|
+
if (!isRecord8(value))
|
|
18161
18221
|
return false;
|
|
18162
18222
|
const prototype = Object.getPrototypeOf(value);
|
|
18163
18223
|
if (prototype !== Object.prototype && prototype !== null)
|
|
18164
18224
|
return true;
|
|
18165
18225
|
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
18166
18226
|
}
|
|
18167
|
-
function
|
|
18227
|
+
function isRecord8(value) {
|
|
18168
18228
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18169
18229
|
}
|
|
18170
18230
|
function containerAt(record, path) {
|
|
18171
18231
|
let container = record;
|
|
18172
18232
|
for (const segment of path) {
|
|
18173
18233
|
const next = container[segment];
|
|
18174
|
-
if (!
|
|
18234
|
+
if (!isRecord8(next))
|
|
18175
18235
|
return null;
|
|
18176
18236
|
container = next;
|
|
18177
18237
|
}
|
|
@@ -18282,6 +18342,15 @@ function legacyCategoryDiagnostic(path, renames) {
|
|
|
18282
18342
|
issuePaths: renames.map((rename) => rename.path)
|
|
18283
18343
|
};
|
|
18284
18344
|
}
|
|
18345
|
+
function legacyHarnessDiagnostic(path, renames) {
|
|
18346
|
+
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
18347
|
+
return {
|
|
18348
|
+
kind: "deprecated-keys",
|
|
18349
|
+
message: `Deprecated harness block in ${path}: ${detail}. Rename it; the alias is removed in a future release.`,
|
|
18350
|
+
path,
|
|
18351
|
+
issuePaths: renames.map((rename) => rename.path)
|
|
18352
|
+
};
|
|
18353
|
+
}
|
|
18285
18354
|
function loadOmoConfig(options = {}) {
|
|
18286
18355
|
const fileSystem = options.fileSystem ?? DEFAULT_READ_FILE_SYSTEM;
|
|
18287
18356
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -18304,8 +18373,12 @@ function loadOmoConfig(options = {}) {
|
|
|
18304
18373
|
if (canonicalized.renames.length > 0) {
|
|
18305
18374
|
diagnostics.push(legacyCategoryDiagnostic(candidate.path, canonicalized.renames));
|
|
18306
18375
|
}
|
|
18307
|
-
|
|
18308
|
-
|
|
18376
|
+
const harnessCanonicalized = canonicalizeLegacyHarnessBlocks(canonicalized.document);
|
|
18377
|
+
if (harnessCanonicalized.renames.length > 0) {
|
|
18378
|
+
diagnostics.push(legacyHarnessDiagnostic(candidate.path, harnessCanonicalized.renames));
|
|
18379
|
+
}
|
|
18380
|
+
layers.push({ config: harnessCanonicalized.document, source: loaded.source });
|
|
18381
|
+
merged = mergeOmoConfigRecords(merged, harnessCanonicalized.document);
|
|
18309
18382
|
}
|
|
18310
18383
|
}
|
|
18311
18384
|
const requestedProfile = resolveOmoProfileName({
|
|
@@ -20905,10 +20978,10 @@ function readCatalogMultiAgentVersion(model, cachePath) {
|
|
|
20905
20978
|
} catch {
|
|
20906
20979
|
return null;
|
|
20907
20980
|
}
|
|
20908
|
-
if (!
|
|
20981
|
+
if (!isRecord9(cache) || !Array.isArray(cache.models))
|
|
20909
20982
|
return null;
|
|
20910
20983
|
for (const entry of cache.models) {
|
|
20911
|
-
if (!
|
|
20984
|
+
if (!isRecord9(entry))
|
|
20912
20985
|
continue;
|
|
20913
20986
|
if (entry.slug !== model && entry.id !== model)
|
|
20914
20987
|
continue;
|
|
@@ -20933,7 +21006,7 @@ function readRootModelCatalogPath(config) {
|
|
|
20933
21006
|
const single = config.match(/^\s*model_catalog_json\s*=\s*'([^']+)'/m);
|
|
20934
21007
|
return single?.[1] ?? null;
|
|
20935
21008
|
}
|
|
20936
|
-
function
|
|
21009
|
+
function isRecord9(value) {
|
|
20937
21010
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20938
21011
|
}
|
|
20939
21012
|
function removeFeatureFlagSetting(config, featureName) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ATTRIBUTION / NOTICE
|
|
2
|
+
|
|
3
|
+
This skill (`browser`, part of `@oh-my-opencode/shared-skills`) is project-original documentation.
|
|
4
|
+
It drives a third-party tool that it does **not** redistribute.
|
|
5
|
+
|
|
6
|
+
## BrowserSkill — driven, not vendored
|
|
7
|
+
|
|
8
|
+
The attached engine this skill documents is **BrowserSkill** by Tencent.
|
|
9
|
+
|
|
10
|
+
- Upstream: https://github.com/Tencent/BrowserSkill
|
|
11
|
+
- License: MIT
|
|
12
|
+
- What ships here: documentation and two local helper scripts, authored by this project.
|
|
13
|
+
- What does NOT ship here: the `bsk` CLI, the daemon, the browser extension, or any upstream
|
|
14
|
+
source. The user installs those from upstream's own installer and from the Chrome Web Store /
|
|
15
|
+
Edge Add-ons listings. This package never bundles a browser binary or an extension payload.
|
|
16
|
+
|
|
17
|
+
MIT permits redistribution; we simply have no reason to, because upstream publishes signed
|
|
18
|
+
per-platform releases and store builds that stay current on their own.
|
|
19
|
+
|
|
20
|
+
## Owned-engine references
|
|
21
|
+
|
|
22
|
+
`references/owned-engine/` documents a *contract* for a code-driven browser — the escalation
|
|
23
|
+
ladder, viewport pinning, reading the network instead of the DOM, overlay and cross-origin
|
|
24
|
+
handling — not any particular package. The techniques are generic CDP practice. No third-party
|
|
25
|
+
source is reproduced.
|