lazycodex-ai 5.1.63 → 5.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/cli/index.js +98 -60
  2. package/dist/cli/service-auth/closed-device-login.d.ts +16 -0
  3. package/dist/cli/service-auth/commands.d.ts +9 -2
  4. package/dist/cli/service-auth/session.d.ts +12 -0
  5. package/dist/cli-node/index.js +98 -60
  6. package/package.json +1 -1
  7. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  8. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +19 -0
  9. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  10. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  11. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  12. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  13. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  14. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  15. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  16. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  17. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  18. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  19. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  20. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  21. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  22. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  23. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  25. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  27. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  31. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  32. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  33. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  34. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  35. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  36. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  37. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  38. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  39. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  40. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  41. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  42. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  43. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  53. package/packages/omo-codex/plugin/package-lock.json +12 -12
  54. package/packages/omo-codex/plugin/package.json +1 -1
  55. package/packages/omo-codex/plugin/skills/browser/SKILL.md +3 -1
  56. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +232 -341
  57. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +5 -5
  58. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/page-bundle.js +1586 -1394
  59. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor-report.mjs +68 -0
  60. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +8 -43
  61. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +7 -1
  62. package/packages/omo-codex/scripts/install-dist/install-local.mjs +21 -2
  63. package/packages/shared-skills/skills/browser/SKILL.md +3 -1
  64. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +232 -341
  65. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +5 -5
  66. package/packages/shared-skills/skills/browser/runtime/omowright/page-bundle.js +1586 -1394
  67. package/packages/shared-skills/skills/browser/scripts/browser-doctor-report.mjs +68 -0
  68. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +8 -43
  69. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +7 -1
@@ -0,0 +1,68 @@
1
+ // The browser doctor's report: one bskDoctor run turned into the `state` the browser skill routes on, its remedy, and a
2
+ // summary. browser-doctor.mjs is the CLI over it; `doctorOptions` reach bskDoctor unchanged (the CLI passes none).
3
+
4
+ // BrowserSkill extension 0.4.0 put every task tab into a native "BrowserSkill" tab group that the browser saves and
5
+ // syncs, so each task left a group in the user's own browser (upstream removed the grouping in 0.4.1).
6
+ const TAB_GROUPING_EXTENSION_VERSION = "0.4.0"
7
+
8
+ function stateOf(report, outdated) {
9
+ if (report.browsersConnected.length > outdated.length) return "ready"
10
+ if (outdated.length > 0) return "outdated-extension"
11
+ if (!report.cli.installed) return "no-cli"
12
+ if (!report.daemon.running) return "no-daemon"
13
+ if (report.browsers.length === 0 && !report.primary) return "no-browser-support"
14
+ return report.identification.needsChoice ? "choose-browser" : "no-extension"
15
+ }
16
+
17
+ const named = (browsers) => browsers.map((browser) => `${browser.browser_name} [${browser.instance_id}]`).join(", ")
18
+
19
+ // With a 0.4.0 browser connected beside an up-to-date one, a session started without `browser` may land on the 0.4.0
20
+ // one (the daemon picks), so the remedy names the up-to-date browser's instance and lists the browsers to avoid.
21
+ function readyRemedy(report, outdated) {
22
+ const live = "Attached engine is live: const { connectBrowserSkill } = await import(omowrightEntry); "
23
+ if (outdated.length === 0) return `${live}const session = await connectBrowserSkill({ name: "<task>", focused: false })`
24
+ const usable = report.browsersConnected.filter((connected) => !outdated.includes(connected))
25
+ const others = usable.length > 1 ? ` (or another up-to-date browser: ${named(usable.slice(1))})` : ""
26
+ return `${live}const session = await connectBrowserSkill({ name: "<task>", focused: false, browser: "${usable[0].instance_id}" })${others}. Always pass browser: the BrowserSkill extension in ${named(outdated)} is 0.4.0, which leaves a "BrowserSkill" tab group in the user's browser after every task; never start a session there, and ask the user to update it to 0.4.1 or later and delete any saved "BrowserSkill" tab groups by hand.`
27
+ }
28
+
29
+ function remedyFor(state, report, outdated) {
30
+ switch (state) {
31
+ case "ready":
32
+ return readyRemedy(report, outdated)
33
+ case "outdated-extension":
34
+ return `The connected BrowserSkill extension is 0.4.0 (${named(outdated)}), which leaves a "BrowserSkill" tab group in the user's browser after every task. Do not start a session. Ask the user to update the extension to 0.4.1 or later (chrome://extensions, Developer mode, Update) and to delete any saved "BrowserSkill" tab groups by hand, then re-run this doctor.`
35
+ case "no-cli":
36
+ return "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."
37
+ case "no-daemon":
38
+ return "Run node \"<skill-root>/scripts/browser-install.mjs\" (it starts the daemon through `bsk status`), then re-run this doctor."
39
+ case "no-extension":
40
+ return report.nextStep ?? "Register the extension with browser-install.mjs, then relay its human step to the user and re-run this doctor."
41
+ case "choose-browser":
42
+ return `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>.`
43
+ case "no-browser-support":
44
+ return "No Chromium-family browser profile was found on this machine. Say so and stop; do not substitute another engine."
45
+ }
46
+ }
47
+
48
+ /** @param {{ omowright: any, entry: string | undefined, browser?: string, doctorOptions?: Record<string, unknown> }} options */
49
+ export async function runBrowserDoctor({ omowright, entry, browser, doctorOptions = {} }) {
50
+ const report = await omowright.bskDoctor({ waitForBrowserMs: 0, browser, ...doctorOptions })
51
+ const outdated = report.browsersConnected.filter((connected) => connected.extension_version === TAB_GROUPING_EXTENSION_VERSION)
52
+ const state = stateOf(report, outdated)
53
+ return {
54
+ state,
55
+ omowright: entry,
56
+ cli: report.cli,
57
+ daemon: { running: report.daemon.running, version: report.daemon.version ?? null, protocolVersion: report.daemon.protocolVersion ?? null, error: report.daemon.error ?? null },
58
+ browser: report.primary ? { id: report.primary.id, label: report.primary.label, confidence: report.identification.confidence, reason: report.identification.reason } : null,
59
+ identificationReason: report.identification.reason,
60
+ candidates: report.identification.candidates.map((c) => ({ id: c.id, label: c.label, signals: c.signals })),
61
+ defaultBrowser: report.identification.defaultBrowser,
62
+ registeredElsewhere: report.identification.registeredElsewhere,
63
+ browsersDetected: report.browsers.map((detected) => ({ id: detected.id, userDataDir: detected.userDataDir, extensionRegistered: detected.extensionRegistered })),
64
+ browsersConnected: report.browsersConnected.map((connected) => ({ instanceId: connected.instance_id, name: connected.browser_name, version: connected.browser_version, extensionVersion: connected.extension_version ?? null })),
65
+ nextStep: report.nextStep,
66
+ remedy: remedyFor(state, report, outdated),
67
+ }
68
+ }
@@ -1,57 +1,22 @@
1
1
  #!/usr/bin/env node
2
+ import { runBrowserDoctor } from "./browser-doctor-report.mjs"
2
3
  import { loadOmowright } from "./omowright.mjs"
3
4
 
4
5
  const { entry, omowright } = await loadOmowright()
5
6
  const browserArg = process.argv.find((arg) => arg.startsWith("--browser="))
6
- const report = await omowright.bskDoctor({ waitForBrowserMs: 0, browser: browserArg ? browserArg.slice("--browser=".length) : undefined })
7
-
8
- const state = report.ready
9
- ? "ready"
10
- : !report.cli.installed
11
- ? "no-cli"
12
- : !report.daemon.running
13
- ? "no-daemon"
14
- : report.browsers.length === 0 && !report.primary
15
- ? "no-browser-support"
16
- : report.identification.needsChoice
17
- ? "choose-browser"
18
- : "no-extension"
19
-
20
- const REMEDIES = {
21
- ready: "Attached engine is live: const { connectBrowserSkill } = await import(omowrightEntry); const session = await connectBrowserSkill({ name: \"<task>\", focused: false })",
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.",
23
- "no-daemon": "Run node \"<skill-root>/scripts/browser-install.mjs\" (it starts the daemon through `bsk status`), then re-run this doctor.",
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>.`,
26
- "no-browser-support": "No Chromium-family browser profile was found on this machine. Say so and stop; do not substitute another engine.",
27
- }
28
-
29
- const summary = {
30
- state,
31
- omowright: entry,
32
- cli: report.cli,
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,
38
- browsersDetected: report.browsers.map((browser) => ({ id: browser.id, userDataDir: browser.userDataDir, extensionRegistered: browser.extensionRegistered })),
39
- browsersConnected: report.browsersConnected.map((browser) => ({ instanceId: browser.instance_id, name: browser.browser_name, version: browser.browser_version })),
40
- nextStep: report.nextStep,
41
- remedy: REMEDIES[state],
42
- }
7
+ const { identificationReason, ...summary } = await runBrowserDoctor({ omowright, entry, browser: browserArg ? browserArg.slice("--browser=".length) : undefined })
43
8
 
44
9
  if (process.argv.includes("--json")) {
45
10
  console.log(JSON.stringify(summary, null, 2))
46
11
  } else {
47
- console.log(`state: ${state}`)
12
+ console.log(`state: ${summary.state}`)
48
13
  console.log(`omowright: ${entry}`)
49
- console.log(`cli: ${report.cli.installed ? `${report.cli.bskBin} (${report.cli.version})` : "not installed"}`)
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})`}`)
14
+ console.log(`cli: ${summary.cli.installed ? `${summary.cli.bskBin} (${summary.cli.version})` : "not installed"}`)
15
+ console.log(`daemon: ${summary.daemon.running ? `running (${summary.daemon.version}, protocol ${summary.daemon.protocolVersion})` : `not running${summary.daemon.error ? ` - ${summary.daemon.error}` : ""}`}`)
16
+ console.log(`browser the user uses: ${summary.browser ? `${summary.browser.label} [${summary.browser.id}] (${summary.browser.reason})` : `not identified (${identificationReason})`}`)
52
17
  console.log(`candidates: ${summary.candidates.map((c) => `${c.id}${c.signals.length ? ` (${c.signals.join(", ")})` : ""}`).join(", ") || "none"}`)
53
18
  if (summary.registeredElsewhere.length > 0) console.log(`extension entries left in other browsers: ${summary.registeredElsewhere.join(", ")} (not removed automatically)`)
54
19
  console.log(`browsers detected: ${summary.browsersDetected.map((b) => `${b.id}${b.extensionRegistered ? " (extension registered)" : ""}`).join(", ") || "none"}`)
55
- console.log(`browsers connected: ${summary.browsersConnected.map((b) => `${b.name} ${b.version} [${b.instanceId}]`).join(", ") || "none"}`)
56
- console.log(`\n${REMEDIES[state]}`)
20
+ console.log(`browsers connected: ${summary.browsersConnected.map((b) => `${b.name} ${b.version} [${b.instanceId}]${b.extensionVersion ? ` extension ${b.extensionVersion}` : ""}`).join(", ") || "none"}`)
21
+ console.log(`\n${summary.remedy}`)
57
22
  }
@@ -9,10 +9,16 @@ const scriptDir = dirname(fileURLToPath(import.meta.url))
9
9
  const skillRoot = dirname(scriptDir)
10
10
 
11
11
  export function resolveOmowrightEntry(env = process.env) {
12
+ const packageRoot = join(skillRoot, "..", "..", "..", "..", "node_modules", "omowright")
13
+ // Same order as stage-omowright-runtime.mjs: sources before the build, `.ts` before `.js`. A git
14
+ // install carries the sources (TypeScript since omowright's strict port, which only Bun imports);
15
+ // a package built for its `exports` carries `dist/` only.
12
16
  const candidates = [
13
17
  env.OMOWRIGHT_ROOT ? join(env.OMOWRIGHT_ROOT, "index.js") : undefined,
14
18
  join(skillRoot, "runtime", "omowright", "index.js"),
15
- join(skillRoot, "..", "..", "..", "..", "node_modules", "omowright", "src", "index.js"),
19
+ join(packageRoot, "src", "index.ts"),
20
+ join(packageRoot, "src", "index.js"),
21
+ join(packageRoot, "dist", "index.js"),
16
22
  ].filter((candidate) => candidate !== undefined)
17
23
  return candidates.find((candidate) => existsSync(candidate))
18
24
  }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // omo-codex-install:ebe09a4bde119ce98f2acce7f1f2bcec3085e797964a5e3cf176873e4c1a81d7:c88063ed768fc19cb863c26d6e6592a599b331f0e45cd3c27fcc278e4c9bc51a
2
+ // omo-codex-install:adc0c9ae0db7b2199d87a87956f2a065f91ef403e2c0816a4fe17111125c47b1:6fec9dd74fa6bb69f9064c703c94e024377de335a2c86ac93c5bd141b1290e69
3
3
  var __esm = (fn, res, err) => () => {
4
4
  if (fn)
5
5
  try {
@@ -10205,7 +10205,7 @@ var package_default;
10205
10205
  var init_package = __esm(() => {
10206
10206
  package_default = {
10207
10207
  name: "@oh-my-opencode/omo-codex",
10208
- version: "5.1.63",
10208
+ version: "5.1.65",
10209
10209
  type: "module",
10210
10210
  private: true,
10211
10211
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -19902,6 +19902,22 @@ var OmoMemoryProjectionLayerSchema = object({
19902
19902
  max_entries_per_directory: number2().int().min(0).optional(),
19903
19903
  max_bytes: number2().int().min(0).optional()
19904
19904
  }).strict();
19905
+ var OmoMemoryRuntimeSchema = object({
19906
+ retention_days: number2().int().min(1).default(7),
19907
+ abandoned_journal_days: number2().int().min(1).default(14),
19908
+ completions_days: number2().int().min(1).default(30),
19909
+ pass_budget_ms: number2().int().min(1).default(60000),
19910
+ discard_unreflected_journals: boolean2().default(false),
19911
+ max_bytes: number2().int().min(0).default(2 * 1024 * 1024 * 1024)
19912
+ }).strict();
19913
+ var OmoMemoryRuntimeLayerSchema = object({
19914
+ retention_days: number2().int().min(1).optional(),
19915
+ abandoned_journal_days: number2().int().min(1).optional(),
19916
+ completions_days: number2().int().min(1).optional(),
19917
+ pass_budget_ms: number2().int().min(1).optional(),
19918
+ discard_unreflected_journals: boolean2().optional(),
19919
+ max_bytes: number2().int().min(0).optional()
19920
+ }).strict();
19905
19921
  var OmoMemoryAgentOverridesSchema = object({
19906
19922
  enabled: boolean2().optional(),
19907
19923
  agent: string2().min(1).optional(),
@@ -19917,6 +19933,7 @@ var OmoMemoryAgentOverridesSchema = object({
19917
19933
  search: OmoMemorySearchLayerSchema.optional(),
19918
19934
  recall: OmoMemoryRecallLayerSchema.optional(),
19919
19935
  projection: OmoMemoryProjectionLayerSchema.optional(),
19936
+ runtime: OmoMemoryRuntimeLayerSchema.optional(),
19920
19937
  compile_warn_tokens: number2().int().positive().optional()
19921
19938
  }).strict();
19922
19939
  var OmoMemoryAutoIdentitySchema = _enum(["path", "git"]);
@@ -19961,6 +19978,7 @@ var OmoMemorySettingsSchema = object({
19961
19978
  }),
19962
19979
  project_scope: OmoMemoryProjectScopeSchema.default({ nudge: true, recall: true }),
19963
19980
  projection: OmoMemoryProjectionSchema.default({ max_entries_per_directory: 0, max_bytes: 40960 }),
19981
+ runtime: OmoMemoryRuntimeSchema.default({ retention_days: 7, abandoned_journal_days: 14, completions_days: 30, pass_budget_ms: 60000, discard_unreflected_journals: false, max_bytes: 2 * 1024 * 1024 * 1024 }),
19964
19982
  compile_warn_tokens: number2().int().positive().default(30000),
19965
19983
  agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
19966
19984
  }).strict();
@@ -19981,6 +19999,7 @@ var OmoMemorySettingsLayerSchema = object({
19981
19999
  recall: OmoMemoryRecallLayerSchema.optional(),
19982
20000
  project_scope: OmoMemoryProjectScopeLayerSchema.optional(),
19983
20001
  projection: OmoMemoryProjectionLayerSchema.optional(),
20002
+ runtime: OmoMemoryRuntimeLayerSchema.optional(),
19984
20003
  compile_warn_tokens: number2().int().positive().optional(),
19985
20004
  agents: record(string2(), OmoMemoryAgentOverridesSchema).optional()
19986
20005
  }).strict();
@@ -14,7 +14,8 @@ One library, two engines. omowright ships inside this skill; choose the engine b
14
14
  | A 403/WAF host the attached engine cannot open, a platform with a native reader, an archive snapshot | neither | the `ultimate-browsing` skill |
15
15
 
16
16
  **Attached is the default,** because it is the only engine carrying the user's logins and the only
17
- one where a human is a single call away. Never substitute one engine for the other silently: if
17
+ one where a human is a single call away. It works in an Agent Window inside the user's own browser profile, never in
18
+ a copy of that profile, and exists only where the user installed and enabled the BrowserSkill extension. Never substitute one engine for the other silently: if
18
19
  the attached engine is not set up, run the onboarding script and tell the user its one remaining
19
20
  step.
20
21
 
@@ -58,6 +59,7 @@ node "<skill-root>/scripts/browser-doctor.mjs" --json
58
59
  | `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 |
59
60
  | `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>` |
60
61
  | `no-browser-support` | no Chromium-family profile on this machine | say so and stop |
62
+ | `outdated-extension` | the only connected extension is BrowserSkill 0.4.0, which leaves a "BrowserSkill" tab group in the user's browser after every task | start no session; relay the doctor's remedy (update the extension to 0.4.1 or later, delete saved "BrowserSkill" groups by hand), then re-run the doctor |
61
63
 
62
64
  **Install into the browser the user actually uses, never into whatever happens to be on disk.** Before
63
65
  installing, check your memory for the user's browser; otherwise read the doctor's `browser` (picked