lazycodex-ai 5.1.64 → 5.1.66
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/dist/cli/index.js +99 -60
- package/dist/cli/service-auth/closed-device-login.d.ts +16 -0
- package/dist/cli/service-auth/commands.d.ts +9 -2
- package/dist/cli/service-auth/session.d.ts +12 -0
- package/dist/cli-node/index.js +99 -60
- 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 +19 -0
- 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/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/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/skills/browser/SKILL.md +24 -7
- package/packages/omo-codex/plugin/skills/browser/references/commands.md +41 -4
- package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +15 -4
- package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +4 -2
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +232 -341
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +5 -5
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/page-bundle.js +1586 -1394
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor-report.mjs +68 -0
- package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +8 -43
- package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +7 -1
- package/packages/omo-codex/plugin/skills/debugging/references/tools/browser-qa.md +4 -3
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/ulw-research/references/research-collection.md +2 -2
- package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +5 -4
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +21 -2
- package/packages/shared-skills/skills/browser/SKILL.md +24 -7
- package/packages/shared-skills/skills/browser/references/commands.md +41 -4
- package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +15 -4
- package/packages/shared-skills/skills/browser/references/recipes/1password.md +4 -2
- package/packages/shared-skills/skills/browser/runtime/omowright/index.js +232 -341
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +5 -5
- package/packages/shared-skills/skills/browser/runtime/omowright/page-bundle.js +1586 -1394
- package/packages/shared-skills/skills/browser/scripts/browser-doctor-report.mjs +68 -0
- package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +8 -43
- package/packages/shared-skills/skills/browser/scripts/omowright.mjs +7 -1
- package/packages/shared-skills/skills/debugging/references/tools/browser-qa.md +4 -3
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +1 -1
- package/packages/shared-skills/skills/ulw-research/SKILL.md +6 -6
- package/packages/shared-skills/skills/ulw-research/references/research-collection.md +2 -2
- package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +5 -4
|
@@ -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
|
|
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: ${
|
|
50
|
-
console.log(`daemon: ${
|
|
51
|
-
console.log(`browser the user uses: ${summary.browser ? `${summary.browser.label} [${summary.browser.id}] (${summary.browser.reason})` : `not identified (${
|
|
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${
|
|
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(
|
|
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
|
}
|
|
@@ -62,10 +62,11 @@ When the bug only happens signed in:
|
|
|
62
62
|
|
|
63
63
|
```js
|
|
64
64
|
const session = await omowright.connectBrowserSkill({ name: "debug repro", focused: false })
|
|
65
|
+
const sync = async () => (await session.cooperate("sync")).context_id // BrowserSkill 0.4: one context per page action
|
|
65
66
|
try {
|
|
66
|
-
await session.navigate(url)
|
|
67
|
-
const { tree, css } = await omowright.bskSnapshot(session, { interactive: true })
|
|
68
|
-
await session.click({ selector: css.e7 })
|
|
67
|
+
await session.navigate(url, { context: await sync() })
|
|
68
|
+
const { tree, css } = await omowright.bskSnapshot(session, { interactive: true, context: await sync() })
|
|
69
|
+
await session.click({ selector: css.e7 }, { context: await sync() })
|
|
69
70
|
const errors = await session.console({ since: 0 })
|
|
70
71
|
const shot = await session.screenshot()
|
|
71
72
|
} finally {
|
|
@@ -111,7 +111,7 @@ The rest of the surface (CUA coordinates, captcha solving, routes, traces, frame
|
|
|
111
111
|
|
|
112
112
|
### Tier 2b — attached engine (the user's account on a blocked host)
|
|
113
113
|
|
|
114
|
-
When the blocked flow needs the user's account, drive the browser they are already signed into instead of cloning their profile: `connectBrowserSkill()` → `session.navigate` → `bskSnapshot(session)` / `session.observe()` → `session.click` → `session.stop()
|
|
114
|
+
When the blocked flow needs the user's account, drive the browser they are already signed into instead of cloning their profile: `connectBrowserSkill()` → `session.navigate` → `bskSnapshot(session)` / `session.observe()` → `session.click` → `session.stop()`, each page action carrying `{ context }` from a fresh `session.cooperate("sync")` (BrowserSkill 0.4 refuses it otherwise). NEVER launch against or clear cookies/cache/site data from the user's live profile, and never fall back to the owned engine for an authenticated criterion: if no extension is connected, run the `browser` skill's onboarding script and relay its one human step. The full loop is the `browser` skill.
|
|
115
115
|
|
|
116
116
|
### Cookie login (cross-platform)
|
|
117
117
|
|
|
@@ -29,7 +29,7 @@ When translating `load_skills=[...]`, include the requested skill names in the s
|
|
|
29
29
|
|
|
30
30
|
# ULW-RESEARCH — Maximum-Saturation Research
|
|
31
31
|
|
|
32
|
-
You are the research orchestrator. The user has explicitly ordered exhaustive research: fan parallel worker swarms out over every relevant source, chase every lead they surface until the leads run dry, prove
|
|
32
|
+
You are the research orchestrator. The user has explicitly ordered exhaustive research: fan parallel worker swarms out over every relevant source, chase every lead they surface until the leads run dry, prove every conclusion by probing a source, reading the file, or running a tool before asserting it, and deliver a synthesis in which every claim carries a citation or a proof. Exhaustive coverage is the assignment, not a risk to manage.
|
|
33
33
|
|
|
34
34
|
## Activation
|
|
35
35
|
|
|
@@ -51,7 +51,7 @@ The research is done when all of these hold:
|
|
|
51
51
|
|
|
52
52
|
- Every axis from Phase 0 was covered by at least one dedicated worker.
|
|
53
53
|
- Every EXPAND lead was investigated or explicitly closed as a duplicate or dead end, and convergence was reached under the Phase 2 rules.
|
|
54
|
-
-
|
|
54
|
+
- Data came first: every conclusion was proven by probing a source, reading the file, or running a tool before it was asserted, never by plausibility, recall, or the shape of the code; contested, undocumented, and performance-shaped claims were additionally proven or refuted by executed code.
|
|
55
55
|
- Every claim in the deliverable cites a source or a verification artifact.
|
|
56
56
|
- Every asserted claim is represented in the claim graph, tied to an intent-vs-reality diff when an expected truth exists, and backed by observation manifest entries from independent observation groups or a documented single-source exception; convergence or exception status is explicit.
|
|
57
57
|
- The deliverable lane and format were derived from the destination or asked through the empty-info interview without blocking collection, recorded in `brief.md` with `answered_by`, and the final materials match that record.
|
|
@@ -72,7 +72,7 @@ Saturation is not just more searching; it is a knowledge-production protocol. Th
|
|
|
72
72
|
- `verification-economics.md` — one row per proof decision. Required fields: claim, risk, error cost, verification cost/time, chosen verification path, defer/verify decision, outcome, and residual risk.
|
|
73
73
|
- `cause-disappearance.md` — one row per causal finding. Required fields: cause id, expected truth, previous observation, `last_seen`, disconfirming observation, replacement cause if any, current status, and whether the violation is no longer observed.
|
|
74
74
|
|
|
75
|
-
Observation candidates and claim candidates travel back from workers as message text. The orchestrator writes the instrumentation artifacts, links candidates into the intent diff and claim graph, and records where each observation entered the synthesis. A
|
|
75
|
+
Observation candidates and claim candidates travel back from workers as message text. **Every conclusion stands on an observation a tool produced** — a page read, a file read, a command run — recorded in `observation-manifest.md`: a claim candidate, a DEAD END, a convergence call, and your own judgment that a topic is settled alike. What you or a worker knows from memory is a LEAD to probe, never evidence. The orchestrator writes the instrumentation artifacts, links candidates into the intent diff and claim graph, and records where each observation entered the synthesis. A claim is not ready for final materials until its expected truth/reality diff is closed or marked unknown, its claim node exists, and its independent-observation convergence status is supported or explicitly excepted.
|
|
76
76
|
|
|
77
77
|
## Run the swarm as a cooperating team
|
|
78
78
|
|
|
@@ -105,15 +105,15 @@ Every research spawn message contains, in order:
|
|
|
105
105
|
2. The budget lift: "This is an explicit exhaustive-research assignment. Your default retrieval budget and stop-when-answered rules do not apply — run the full protocol below and report every lead."
|
|
106
106
|
3. Scope — the axis, the sources to hit, and what a complete answer contains.
|
|
107
107
|
4. The role protocol (Phase 1).
|
|
108
|
-
5. The reply tail. EXPAND markers, observation candidates, and claim candidates travel back as message text, never as files. Every worker ends the reply with:
|
|
108
|
+
5. The reply tail. EXPAND markers, observation candidates, and claim candidates travel back as message text, never as files. Each claim candidate carries `OBSERVED: <URL read | file:line | command and its output>`; a claim the worker only remembers goes into the tail as a LEAD. Every worker ends the reply with:
|
|
109
109
|
|
|
110
110
|
```
|
|
111
111
|
## EXPAND
|
|
112
112
|
- LEAD: <discovery not yet investigated> — WHY: <why it matters> — ANGLE: <suggested search>
|
|
113
|
-
- DEAD END: <lead explored to exhaustion>
|
|
113
|
+
- DEAD END: <lead explored to exhaustion> — PROBED: <the searches, reads, or commands that exhausted it>
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
A worker with nothing to expand writes `## EXPAND` followed by `none — <one-line reason>`. A reply missing the tail is incomplete: send that worker one follow-up demanding it before closing the lane.
|
|
116
|
+
A worker with nothing to expand writes `## EXPAND` followed by `none — <one-line reason>`. A reply missing the tail, or a claim or DEAD END missing its `OBSERVED:`/`PROBED:` line, is incomplete: send that worker one follow-up demanding it before closing the lane.
|
|
117
117
|
|
|
118
118
|
## Execution references
|
|
119
119
|
|
|
@@ -139,7 +139,7 @@ task(subagent_type="explore", run_in_background=true, prompt="TASK: act as a cod
|
|
|
139
139
|
This is an explicit exhaustive-research assignment. Your default retrieval budget and stop-when-answered rules do not apply — run the full protocol below and report every lead.
|
|
140
140
|
SCOPE: find everything in this codebase related to <angle>: <what complete looks like>.
|
|
141
141
|
PROTOCOL: grep 3+ keyword variations; structural search; LSP references; globs; git history (-S and --grep). Cross-validate across tools. Report absolute paths and file:line patterns.
|
|
142
|
-
End your reply with the ## EXPAND tail: '- LEAD: <discovery> — WHY: <why> — ANGLE: <search>' per lead, or 'none — <reason>'.")
|
|
142
|
+
Tag every claim OBSERVED: <URL | file:line | command>. End your reply with the ## EXPAND tail: '- LEAD: <discovery> — WHY: <why> — ANGLE: <search>' per lead, '- DEAD END: <lead> — PROBED: <what exhausted it>', or 'none — <reason>'.")
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
## Phase 2 — Expand until convergence
|
|
@@ -154,7 +154,7 @@ This loop is what makes the mode research rather than search. Collect returns as
|
|
|
154
154
|
task(category="deep-low", load_skills=["browser"], run_in_background=true, prompt="TASK: expansion wave <N> — investigate: <lead>.
|
|
155
155
|
PARENT: <which return surfaced it>. This is an explicit exhaustive-research assignment; budgets do not apply.
|
|
156
156
|
<role protocol for the lead's territory — web protocol for external leads, explore protocol for codebase leads>
|
|
157
|
-
End your reply with the ## EXPAND tail.")
|
|
157
|
+
Tag every claim OBSERVED: <URL | file:line | command>. End your reply with the ## EXPAND tail.")
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
### Excursions — dive deep on a new find, then surface back out
|
|
@@ -65,14 +65,15 @@ cloning its profile:
|
|
|
65
65
|
|
|
66
66
|
```js
|
|
67
67
|
const session = await omowright.connectBrowserSkill({ name: "visual-qa capture", focused: false })
|
|
68
|
+
const sync = async () => (await session.cooperate("sync")).context_id // BrowserSkill 0.4: one context per page action
|
|
68
69
|
try {
|
|
69
|
-
await session.navigate(url, { waitUntil: "load" })
|
|
70
|
-
await session.resize(1440, 900)
|
|
70
|
+
await session.navigate(url, { waitUntil: "load", context: await sync() })
|
|
71
|
+
await session.resize(1440, 900, { context: await sync() }) // desktop column of the matrix
|
|
71
72
|
await Bun.write(`${outDir}/${route}-1440-top.png`, (await session.screenshot()).buffer) // { buffer, width, height }
|
|
72
|
-
await session.emulate({ overrides: { width: 390, mobile: true } }) // phone column; `off: true` restores
|
|
73
|
+
await session.emulate({ overrides: { width: 390, mobile: true }, context: await sync() }) // phone column; `off: true` restores
|
|
73
74
|
await Bun.write(`${outDir}/${route}-390-top.png`, (await session.screenshot()).buffer)
|
|
74
75
|
} finally {
|
|
75
|
-
await session.emulate({ off: true })
|
|
76
|
+
await session.emulate({ off: true, context: await sync() })
|
|
76
77
|
await session.stop()
|
|
77
78
|
}
|
|
78
79
|
```
|