@polderlabs/bizar 6.2.4 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +15 -0
- package/.claude/agents/_shared/AGENT_BASELINE.md +168 -0
- package/.claude/agents/_shared/CLAUDE_TOOLS.md +412 -0
- package/.claude/agents/_shared/SKILLS.md +109 -0
- package/.claude/agents/agent-browser.md +80 -0
- package/.claude/agents/baldr.md +49 -0
- package/.claude/agents/forseti.md +51 -0
- package/.claude/agents/frigg.md +42 -0
- package/.claude/agents/heimdall.md +33 -0
- package/.claude/agents/hermod.md +53 -0
- package/.claude/agents/mimir.md +49 -0
- package/.claude/agents/odin.md +287 -0
- package/.claude/agents/quick.md +34 -0
- package/.claude/agents/semble-search.md +50 -0
- package/.claude/agents/thor.md +53 -0
- package/.claude/agents/tyr.md +56 -0
- package/.claude/agents/vidarr.md +54 -0
- package/.claude/agents/vor.md +53 -0
- package/.claude/commands/audit.md +25 -0
- package/.claude/commands/bizar.md +22 -0
- package/.claude/commands/explain.md +17 -0
- package/.claude/commands/init.md +29 -0
- package/.claude/commands/learn.md +44 -0
- package/.claude/commands/plan.md +35 -0
- package/.claude/commands/plow-through.md +50 -0
- package/.claude/commands/pr-review.md +49 -0
- package/.claude/commands/setup-provider.md +96 -0
- package/.claude/commands/tailscale-serve.md +100 -0
- package/.claude/commands/team.md +132 -0
- package/.claude/commands/test.md +62 -0
- package/.claude/commands/validate.md +68 -0
- package/.claude/commands/visual-plan.md +24 -0
- package/.claude/hooks/README.md +92 -0
- package/.claude/hooks/posttooluse-editwrite.mjs +91 -0
- package/.claude/hooks/pretooluse-bash.mjs +81 -0
- package/.claude/hooks/pretooluse-editwrite.mjs +139 -0
- package/.claude/hooks/sessionend-recall.mjs +74 -0
- package/.claude/hooks/sessionstart-prime.mjs +80 -0
- package/.claude/hooks/userpromptsubmit-tag.mjs +80 -0
- package/.claude/settings.json +116 -0
- package/.claude/skills/9router/SKILL.md +80 -0
- package/.claude/skills/9router-chat/SKILL.md +73 -0
- package/.claude/skills/9router-embeddings/SKILL.md +69 -0
- package/.claude/skills/9router-image/SKILL.md +86 -0
- package/.claude/skills/9router-stt/SKILL.md +79 -0
- package/.claude/skills/9router-tts/SKILL.md +80 -0
- package/.claude/skills/9router-web-fetch/SKILL.md +99 -0
- package/.claude/skills/9router-web-search/SKILL.md +91 -0
- package/.claude/skills/bizar/README.md +9 -0
- package/.claude/skills/bizar/SKILL.md +450 -0
- package/.claude/skills/cpp-coding-standards/README.md +28 -0
- package/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
- package/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
- package/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
- package/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
- package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
- package/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
- package/.claude/skills/cpp-testing/README.md +28 -0
- package/.claude/skills/cpp-testing/SKILL.md +304 -0
- package/.claude/skills/cpp-testing/references/coverage.md +370 -0
- package/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
- package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
- package/.claude/skills/cpp-testing/references/mocking.md +364 -0
- package/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
- package/.claude/skills/cubesandbox/SKILL.md +148 -0
- package/.claude/skills/embedded-esp-idf/README.md +41 -0
- package/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
- package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
- package/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
- package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
- package/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
- package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
- package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
- package/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
- package/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
- package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
- package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
- package/.claude/skills/glyph/SKILL.md +163 -0
- package/.claude/skills/harness-engineering/SKILL.md +143 -0
- package/.claude/skills/lightrag/SKILL.md +81 -0
- package/.claude/skills/memory-protocol/SKILL.md +105 -0
- package/.claude/skills/obsidian/SKILL.md +306 -0
- package/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
- package/.claude/skills/self-improvement/SKILL.md +64 -0
- package/README.md +87 -59
- package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js → EnvVarsSection-B58aiJiE.js} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js.map → EnvVarsSection-B58aiJiE.js.map} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js → MobileChat-BJrqwVDd.js} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js.map → MobileChat-BJrqwVDd.js.map} +1 -1
- package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js → MobileSettings-CEQNJNLJ.js} +1 -1
- package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js.map → MobileSettings-CEQNJNLJ.js.map} +1 -1
- package/bizar-dash/dist/assets/{main-DYiZqMrn.js → main-IvfQAOfy.js} +1 -1
- package/bizar-dash/dist/assets/{main-DYiZqMrn.js.map → main-IvfQAOfy.js.map} +1 -1
- package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js → markdown-tOLaD6nm.js} +1 -1
- package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js.map → markdown-tOLaD6nm.js.map} +1 -1
- package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js → mobile-DYCHcUpq.js} +1 -1
- package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js.map → mobile-DYCHcUpq.js.map} +1 -1
- package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js → mobile-layout-CBHjpwsb.js} +2 -2
- package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js.map → mobile-layout-CBHjpwsb.js.map} +1 -1
- package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js → useSlashCommands-Bd7_FA6U.js} +2 -2
- package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js.map → useSlashCommands-Bd7_FA6U.js.map} +1 -1
- package/bizar-dash/dist/assets/{vendor-CeHGtduv.js → vendor-C843201K.js} +12 -12
- package/bizar-dash/dist/assets/vendor-C843201K.js.map +1 -0
- package/bizar-dash/dist/index.html +6 -6
- package/bizar-dash/dist/mobile.html +2 -2
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/api.mjs +4 -4
- package/bizar-dash/src/server/background-store.mjs +15 -16
- package/bizar-dash/src/server/bg-poller.mjs +25 -35
- package/bizar-dash/src/server/bg-retry.mjs +66 -194
- package/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
- package/bizar-dash/src/server/claude-info.mjs +412 -0
- package/bizar-dash/src/server/{cline-runner.mjs → claude-runner.mjs} +53 -48
- package/bizar-dash/src/server/claude-sdk.mjs +191 -0
- package/bizar-dash/src/server/providers-store.mjs +22 -49
- package/bizar-dash/src/server/routes/background.mjs +24 -20
- package/bizar-dash/src/server/routes/chat.mjs +223 -326
- package/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
- package/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
- package/bizar-dash/src/server/routes/tasks.mjs +20 -28
- package/bizar-dash/src/server/task-delegator.mjs +76 -77
- package/bizar-dash/src/web/components/chat/useChat.ts +23 -27
- package/bizar-dash/src/web/views/Chat.tsx +8 -8
- package/cli/bin.mjs +31 -18
- package/cli/commands/claude-cmd.mjs +348 -0
- package/cli/commands/install.mjs +12 -11
- package/cli/commands/sandbox.mjs +220 -0
- package/cli/commands/validate.mjs +252 -288
- package/cli/dev-link.test.mjs +11 -11
- package/cli/doctor.mjs +131 -213
- package/cli/install.mjs +33 -37
- package/cli/install.test.mjs +9 -9
- package/cli/provision-claude.mjs +893 -0
- package/cli/provision.mjs +330 -226
- package/cli/provision.test.mjs +102 -0
- package/cli/utils.mjs +72 -58
- package/config/AGENTS.md +28 -28
- package/config/agents/_shared/AGENT_BASELINE.md +104 -684
- package/config/skills/bizar/SKILL.md +197 -0
- package/config/skills/cubesandbox/SKILL.md +148 -0
- package/config/skills/harness-engineering/SKILL.md +142 -0
- package/install.sh +66 -44
- package/package.json +19 -11
- package/packages/sdk/ARCHITECTURE.md +40 -36
- package/packages/sdk/package-lock.json +32 -0
- package/packages/sdk/package.json +15 -5
- package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
- package/packages/sdk/src/fingerprint.ts +0 -0
- package/packages/sdk/src/index.ts +38 -73
- package/packages/sdk/src/mcp/bin.ts +51 -0
- package/packages/sdk/src/mcp/server.ts +498 -0
- package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
- package/packages/sdk/tests/sdk.test.mjs +148 -0
- package/packages/sdk/vitest.config.ts +1 -1
- package/scripts/bh-full-e2e.mjs +166 -363
- package/scripts/check-deps.mjs +28 -46
- package/scripts/mirror-claude-md.sh +78 -0
- package/scripts/test-in-container.sh +157 -0
- package/templates/clean-state-checklist.md +3 -3
- package/templates/sprint-contract.md +2 -2
- package/bizar-dash/.bizar/activity.log +0 -3
- package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
- package/bizar-dash/.omx/state/session.json +0 -10
- package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
- package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
- package/bizar-dash/bizar-design/canvas.html +0 -281
- package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/components.css +0 -1665
- package/bizar-dash/bizar-design/components.html +0 -557
- package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/agents.html +0 -74
- package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/memory.html +0 -75
- package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
- package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/overview.html +0 -95
- package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/settings.html +0 -70
- package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/icons.svg +0 -44
- package/bizar-dash/bizar-design/index.html +0 -192
- package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/agents.html +0 -29
- package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/memory.html +0 -28
- package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
- package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/overview.html +0 -33
- package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/settings.html +0 -28
- package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/prototype.js +0 -114
- package/bizar-dash/bizar-design/tokens.css +0 -106
- package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
- package/bizar-dash/node_modules/.package-lock.json +0 -6
- package/bizar-dash/package-lock.json +0 -6
- package/bizar-dash/src/server/cline-sdk.mjs +0 -132
- package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
- package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
- package/cli/commands/cline-cmd.mjs +0 -289
- package/cli/commands/validate.test.mjs +0 -344
- package/cli/doctor.test.mjs +0 -350
- package/config/cline.json.template +0 -342
- package/packages/sdk/src/client.ts +0 -188
- package/packages/sdk/src/cline-events.ts +0 -134
- package/packages/sdk/src/cline-types.ts +0 -66
- package/packages/sdk/src/cline.ts +0 -339
- package/packages/sdk/src/errors.ts +0 -129
- package/packages/sdk/src/events.ts +0 -153
- package/packages/sdk/src/types.ts +0 -176
- package/packages/sdk/tests/client.test.ts +0 -217
- package/packages/sdk/tests/errors.test.ts +0 -108
- package/packages/sdk/tests/events.test.ts +0 -139
- package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
- package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
- package/plugins/bizar/ARCHITECTURE.md +0 -142
- package/plugins/bizar/CONSTRAINTS.md +0 -67
- package/plugins/bizar/LICENSE +0 -21
- package/plugins/bizar/README.md +0 -448
- package/plugins/bizar/index.ts +0 -872
- package/plugins/bizar/package.json +0 -39
- package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
- package/plugins/bizar/src/background-state.ts +0 -641
- package/plugins/bizar/src/background.ts +0 -1806
- package/plugins/bizar/src/cline-runner.ts +0 -203
- package/plugins/bizar/src/clineruntime.ts +0 -227
- package/plugins/bizar/src/commands-impl.ts +0 -151
- package/plugins/bizar/src/commands.ts +0 -1799
- package/plugins/bizar/src/compaction.d.mts +0 -48
- package/plugins/bizar/src/compaction.mjs +0 -192
- package/plugins/bizar/src/dashboard-client.ts +0 -233
- package/plugins/bizar/src/event-stream.ts +0 -606
- package/plugins/bizar/src/fingerprint.ts +0 -120
- package/plugins/bizar/src/handoff.ts +0 -79
- package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
- package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
- package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
- package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
- package/plugins/bizar/src/http-client.ts +0 -467
- package/plugins/bizar/src/key-rotation.ts +0 -218
- package/plugins/bizar/src/logger.ts +0 -144
- package/plugins/bizar/src/loop-engineering.ts +0 -241
- package/plugins/bizar/src/loop.ts +0 -176
- package/plugins/bizar/src/mistake-recovery.ts +0 -98
- package/plugins/bizar/src/odin.ts +0 -227
- package/plugins/bizar/src/options.ts +0 -470
- package/plugins/bizar/src/plan-fs.ts +0 -323
- package/plugins/bizar/src/reasoning-clean.ts +0 -454
- package/plugins/bizar/src/report.ts +0 -178
- package/plugins/bizar/src/research-prompt.ts +0 -35
- package/plugins/bizar/src/serve-info.ts +0 -228
- package/plugins/bizar/src/serve.ts +0 -496
- package/plugins/bizar/src/settings.ts +0 -349
- package/plugins/bizar/src/state.ts +0 -298
- package/plugins/bizar/src/tool-discipline.ts +0 -105
- package/plugins/bizar/src/tools/agent-browser.ts +0 -315
- package/plugins/bizar/src/tools/bg-collect.ts +0 -131
- package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
- package/plugins/bizar/src/tools/bg-kill.ts +0 -116
- package/plugins/bizar/src/tools/bg-pause.ts +0 -99
- package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
- package/plugins/bizar/src/tools/bg-resume.ts +0 -94
- package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
- package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
- package/plugins/bizar/src/tools/bg-status.ts +0 -130
- package/plugins/bizar/src/tools/graph-query.ts +0 -278
- package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
- package/plugins/bizar/src/tools/memory-list.ts +0 -43
- package/plugins/bizar/src/tools/memory-read.ts +0 -69
- package/plugins/bizar/src/tools/memory-search.ts +0 -47
- package/plugins/bizar/src/tools/memory-write.ts +0 -54
- package/plugins/bizar/src/tools/open-kb.ts +0 -198
- package/plugins/bizar/src/tools/plan-action.ts +0 -785
- package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
- package/plugins/bizar/src/tools/team-spawn.ts +0 -73
- package/plugins/bizar/src/tools/team-status.ts +0 -76
- package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
- package/plugins/bizar/src/trajectory.ts +0 -104
- package/plugins/bizar/tests/README.md +0 -99
- package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
- package/plugins/bizar/tests/background-state.test.ts +0 -277
- package/plugins/bizar/tests/background.test.ts +0 -402
- package/plugins/bizar/tests/block.test.ts +0 -195
- package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
- package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
- package/plugins/bizar/tests/commands-impl.test.ts +0 -316
- package/plugins/bizar/tests/commands.test.ts +0 -584
- package/plugins/bizar/tests/compaction.test.ts +0 -264
- package/plugins/bizar/tests/config.test.ts +0 -128
- package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
- package/plugins/bizar/tests/dispose.test.ts +0 -336
- package/plugins/bizar/tests/event-stream.test.ts +0 -409
- package/plugins/bizar/tests/event.test.ts +0 -262
- package/plugins/bizar/tests/fingerprint.test.ts +0 -162
- package/plugins/bizar/tests/http-client.test.ts +0 -404
- package/plugins/bizar/tests/init-helpers.test.ts +0 -203
- package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
- package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
- package/plugins/bizar/tests/key-rotation.test.ts +0 -396
- package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
- package/plugins/bizar/tests/loop.test.ts +0 -397
- package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
- package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
- package/plugins/bizar/tests/odin.test.ts +0 -125
- package/plugins/bizar/tests/options.test.ts +0 -329
- package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
- package/plugins/bizar/tests/safety.test.ts +0 -256
- package/plugins/bizar/tests/serve.test.ts +0 -339
- package/plugins/bizar/tests/settings.test.ts +0 -351
- package/plugins/bizar/tests/stall-think.test.ts +0 -750
- package/plugins/bizar/tests/state.test.ts +0 -276
- package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
- package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
- package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
- package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
- package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
- package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
- package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
- package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
- package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
- package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
- package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
- package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
- package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
- package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
- package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
- package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
- package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
- package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
- package/plugins/bizar/tsconfig.json +0 -29
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tool-discipline.ts
|
|
3
|
-
*
|
|
4
|
-
* v6.0.1 — Tool-call discipline + preference directive injected into
|
|
5
|
-
* every Cline system prompt produced by the Bizar harness.
|
|
6
|
-
*
|
|
7
|
-
* Why this exists:
|
|
8
|
-
*
|
|
9
|
-
* Cline's runtime aborts sessions when the model emits consecutive
|
|
10
|
-
* tool calls that fail Zod schema validation (e.g. `editor({ new_text:
|
|
11
|
-
* undefined })`, `ask_question({ options: null })`,
|
|
12
|
-
* `run_commands({ ... })`). The defaults in `mistake-recovery.ts` keep
|
|
13
|
-
* the session alive — but the cheaper fix is preventing the bad tool
|
|
14
|
-
* calls in the first place.
|
|
15
|
-
*
|
|
16
|
-
* We also steer the model away from over-using `run_commands` for
|
|
17
|
-
* things that have a dedicated built-in tool. Built-in tools give
|
|
18
|
-
* better diffs, easier approval, richer error context, and don't
|
|
19
|
-
* require shell quoting. Bash is for things that genuinely need a
|
|
20
|
-
* shell — anything else should hit a specialized tool.
|
|
21
|
-
*
|
|
22
|
-
* This directive is appended to the system prompt by the harness's
|
|
23
|
-
* `beforeModel` hook (idempotent: detected via a marker). It is short
|
|
24
|
-
* enough to stay cheap (~220 tokens) and only fires once per session,
|
|
25
|
-
* so it does not bloat every turn's context.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
export const TOOL_DISCIPLINE_MARKER = "BIZAR_TOOL_DISCIPLINE_v0.6.3";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* The directive body. Kept compact; details are in the linked recovery
|
|
32
|
-
* notice so we don't duplicate instructions between the system prompt
|
|
33
|
-
* and the recovery callback.
|
|
34
|
-
*/
|
|
35
|
-
export const TOOL_DISCIPLINE_DIRECTIVE = [
|
|
36
|
-
TOOL_DISCIPLINE_MARKER,
|
|
37
|
-
"",
|
|
38
|
-
"## Tool-call discipline",
|
|
39
|
-
"",
|
|
40
|
-
"• Required fields are required. Populate every field declared in the",
|
|
41
|
-
" tool's input schema, with a value of the right type. Do not omit",
|
|
42
|
-
" fields; Cline rejects the call before any side effect runs.",
|
|
43
|
-
"• `editor.new_text` must be a non-empty string. To clear content, use",
|
|
44
|
-
" `applyPatch` or `delete_file`. To create a new file, pass the",
|
|
45
|
-
" full intended contents as `new_text`.",
|
|
46
|
-
"• `ask_question.options` must be an array of ≥2 non-empty strings.",
|
|
47
|
-
" Passing `null`, `undefined`, or arrays of length <2 fails schema",
|
|
48
|
-
" validation.",
|
|
49
|
-
"• `run_commands.commands` must be a non-empty array of strings.",
|
|
50
|
-
"• If a tool call fails validation twice in a row, switch tools or",
|
|
51
|
-
" describe the problem in plain text before retrying. Do not loop on",
|
|
52
|
-
" the same mistake.",
|
|
53
|
-
"",
|
|
54
|
-
"## Prefer built-in tools over bash",
|
|
55
|
-
"",
|
|
56
|
-
"Cline ships dedicated tools for most file/shell work. Reach for them",
|
|
57
|
-
"before reaching for `run_commands`:",
|
|
58
|
-
"",
|
|
59
|
-
"| If you want to… | Use this, not bash |",
|
|
60
|
-
"| ------------------------------------- | ---------------------------- |",
|
|
61
|
-
"| read a file | `read_file` |",
|
|
62
|
-
"| search a workspace | `search_codebase` / `search` |",
|
|
63
|
-
"| edit a file in place | `editor` or `apply_patch` |",
|
|
64
|
-
"| create a new file | `editor` (new_text = full) |",
|
|
65
|
-
"| list a directory | `list_files` |",
|
|
66
|
-
"| fetch a URL | `web_fetch` |",
|
|
67
|
-
"| run a build / test / lint / script | `run_commands` |",
|
|
68
|
-
"",
|
|
69
|
-
"Reaching for bash first creates two problems:",
|
|
70
|
-
" 1. Shell quoting bugs (quotes-in-quotes-in-quotes) are the most",
|
|
71
|
-
" common cause of malformed tool calls.",
|
|
72
|
-
" 2. Each bash command lands in tool history as opaque output; a",
|
|
73
|
-
" dedicated tool keeps diffs, error context, and approval gates",
|
|
74
|
-
" intact.",
|
|
75
|
-
"",
|
|
76
|
-
"When you DO call `run_commands`, keep it small:",
|
|
77
|
-
"",
|
|
78
|
-
"• One logical command per call. Do not chain unrelated segments with",
|
|
79
|
-
" `&&`. Use multiple `run_commands` turns instead — each turn's output",
|
|
80
|
-
" is easier to debug and re-run.",
|
|
81
|
-
"• Pass file paths via the tool's structured fields (`editor.path`,",
|
|
82
|
-
" `read_file.path`) — never as `cd ... && <cmd>` chdir hacks.",
|
|
83
|
-
"• Hard cap: do not emit a single command longer than ~600 chars. If",
|
|
84
|
-
" the command doesn't fit, it's a sign you should use a built-in tool",
|
|
85
|
-
" or split it across turns.",
|
|
86
|
-
"• No `for i in $(seq 1 100)` loops for batching work that has a tool",
|
|
87
|
-
" (`read_file`, `editor`). Loops in bash hide per-file failures.",
|
|
88
|
-
"• No `xargs`, no `sed -i`, no heredocs to write files — these all",
|
|
89
|
-
" have a dedicated tool that produces a richer record.",
|
|
90
|
-
"",
|
|
91
|
-
"These conventions avoid both the consecutive-mistake abort and the",
|
|
92
|
-
"common shell-quoting trap.",
|
|
93
|
-
].join("\n");
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Bump this constant when the directive body changes in a way that
|
|
97
|
-
* warrants re-injection into existing sessions. The harness uses the
|
|
98
|
-
* marker to detect "already injected", so an updated directive will
|
|
99
|
-
* only land if a fresh session starts (or marker changes).
|
|
100
|
-
*/
|
|
101
|
-
export const TOOL_DISCIPLINE_VERSION = "0.6.3";
|
|
102
|
-
|
|
103
|
-
export function hasToolDiscipline(systemPrompt: string | undefined): boolean {
|
|
104
|
-
return typeof systemPrompt === "string" && systemPrompt.includes(TOOL_DISCIPLINE_MARKER);
|
|
105
|
-
}
|
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* agent-browser.ts — v6.0.0 agent-browser CLI wrapper tools.
|
|
3
|
-
*
|
|
4
|
-
* Replaces the v5.x `browser-harness` (Python CDP wrapper) with
|
|
5
|
-
* agent-browser (native Rust CLI from vercel-labs).
|
|
6
|
-
*
|
|
7
|
-
* Pattern: thin wrappers around `agent-browser <cmd> ...`. The CLI
|
|
8
|
-
* is installed via npm (`npm install -g agent-browser`) and exposes
|
|
9
|
-
* 100+ typed commands. The MCP stdio server (`agent-browser mcp`)
|
|
10
|
-
* is exposed separately at the Cline level via `.cline/mcp.json`.
|
|
11
|
-
*
|
|
12
|
-
* Six tools:
|
|
13
|
-
* - bizar_browser_open open a URL (auto-launches daemon)
|
|
14
|
-
* - bizar_browser_snapshot accessibility tree with refs (@e1..)
|
|
15
|
-
* - bizar_browser_click click by ref @e2 or selector
|
|
16
|
-
* - bizar_browser_fill fill an input by ref or selector
|
|
17
|
-
* - bizar_browser_screenshot screenshot to a file (returned by path)
|
|
18
|
-
* - bizar_browser_command escape hatch for any agent-browser command
|
|
19
|
-
*
|
|
20
|
-
* The plugin invokes `agent-browser ...` via execFile (no shell, no
|
|
21
|
-
* injection). All tool calls go through `checkDangerous()` for the
|
|
22
|
-
* DANGEROUS_PATTERNS approval gate.
|
|
23
|
-
*
|
|
24
|
-
* The browser-primary agent that uses these tools lives at
|
|
25
|
-
* config/agents/agent-browser.md.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import { createTool, type AgentTool } from "@cline/sdk";
|
|
29
|
-
import { z } from "zod";
|
|
30
|
-
|
|
31
|
-
import type { Logger } from "../logger.js";
|
|
32
|
-
|
|
33
|
-
export const BIZAR_BROWSER_OPEN_TOOL_NAME = "bizar_browser_open";
|
|
34
|
-
export const BIZAR_BROWSER_SNAPSHOT_TOOL_NAME = "bizar_browser_snapshot";
|
|
35
|
-
export const BIZAR_BROWSER_CLICK_TOOL_NAME = "bizar_browser_click";
|
|
36
|
-
export const BIZAR_BROWSER_FILL_TOOL_NAME = "bizar_browser_fill";
|
|
37
|
-
export const BIZAR_BROWSER_SCREENSHOT_TOOL_NAME = "bizar_browser_screenshot";
|
|
38
|
-
export const BIZAR_BROWSER_COMMAND_TOOL_NAME = "bizar_browser_command";
|
|
39
|
-
|
|
40
|
-
export interface AgentBrowserDeps {
|
|
41
|
-
logger: Logger;
|
|
42
|
-
/** Override the agent-browser binary path. Default: "agent-browser" on PATH. */
|
|
43
|
-
bin?: string;
|
|
44
|
-
/** Default browser profile directory. */
|
|
45
|
-
profile?: string;
|
|
46
|
-
/** Default daemon host. */
|
|
47
|
-
host?: string;
|
|
48
|
-
/** Default daemon port. */
|
|
49
|
-
port?: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function resolveBin(deps: AgentBrowserDeps): string {
|
|
53
|
-
if (deps.bin) return deps.bin;
|
|
54
|
-
return process.env.AGENT_BROWSER_BIN ?? "agent-browser";
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Run an agent-browser CLI subcommand and capture stdout/stderr/exitCode.
|
|
59
|
-
*
|
|
60
|
-
* Returns the parsed JSON object when `--json` is passed and the output
|
|
61
|
-
* is valid JSON; otherwise returns a `{ stdout, stderr, exitCode }`
|
|
62
|
-
* envelope.
|
|
63
|
-
*/
|
|
64
|
-
async function runAgentBrowser(
|
|
65
|
-
deps: AgentBrowserDeps,
|
|
66
|
-
args: string[],
|
|
67
|
-
opts: { json?: boolean; cwd?: string; timeoutMs?: number } = {},
|
|
68
|
-
): Promise<{ ok: boolean; exitCode: number; stdout: string; stderr: string; json?: unknown }> {
|
|
69
|
-
const bin = resolveBin(deps);
|
|
70
|
-
const json = opts.json ?? args.includes("--json");
|
|
71
|
-
const finalArgs = json && !args.includes("--json") ? [...args, "--json"] : args;
|
|
72
|
-
|
|
73
|
-
const { execFile } = await import("node:child_process");
|
|
74
|
-
const { promisify } = await import("node:util");
|
|
75
|
-
const pExecFile = promisify(execFile);
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
const { stdout, stderr } = await pExecFile(bin, finalArgs, {
|
|
79
|
-
cwd: opts.cwd ?? process.cwd(),
|
|
80
|
-
timeout: opts.timeoutMs ?? 30_000,
|
|
81
|
-
maxBuffer: 16 * 1024 * 1024,
|
|
82
|
-
});
|
|
83
|
-
if (json) {
|
|
84
|
-
try {
|
|
85
|
-
return { ok: true, exitCode: 0, stdout, stderr, json: JSON.parse(stdout) };
|
|
86
|
-
} catch {
|
|
87
|
-
return { ok: true, exitCode: 0, stdout, stderr };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return { ok: true, exitCode: 0, stdout, stderr };
|
|
91
|
-
} catch (err) {
|
|
92
|
-
const e = err as { code?: number | string; stdout?: string; stderr?: string };
|
|
93
|
-
return {
|
|
94
|
-
ok: false,
|
|
95
|
-
exitCode: typeof e.code === "number" ? e.code : 1,
|
|
96
|
-
stdout: e.stdout ?? "",
|
|
97
|
-
stderr: e.stderr ?? (err instanceof Error ? err.message : String(err)),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ─── tool: bizar_browser_open ────────────────────────────────────────────
|
|
103
|
-
export type BizarBrowserOpenInput = z.infer<typeof bizarBrowserOpenSchema>;
|
|
104
|
-
export type BizarBrowserOpenOutput =
|
|
105
|
-
| { ok: true; url: string; snapshot?: unknown; stdout: string }
|
|
106
|
-
| { ok: false; error: string; stderr: string };
|
|
107
|
-
|
|
108
|
-
const bizarBrowserOpenSchema = z.object({
|
|
109
|
-
url: z.string().url().describe("URL to open in the browser."),
|
|
110
|
-
headless: z.boolean().optional().describe("Default true. Set false for visual debugging."),
|
|
111
|
-
profile: z.string().optional().describe("Override profile dir for this session."),
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
export function createBrowserOpenTool(
|
|
115
|
-
deps: AgentBrowserDeps,
|
|
116
|
-
): AgentTool<BizarBrowserOpenInput, BizarBrowserOpenOutput> {
|
|
117
|
-
return createTool({
|
|
118
|
-
name: BIZAR_BROWSER_OPEN_TOOL_NAME,
|
|
119
|
-
description:
|
|
120
|
-
"Launch agent-browser and navigate to a URL. Auto-starts the daemon if not running. " +
|
|
121
|
-
"Returns the initial accessibility-tree snapshot as JSON for immediate element discovery.",
|
|
122
|
-
inputSchema: bizarBrowserOpenSchema.shape,
|
|
123
|
-
execute: async (input) => {
|
|
124
|
-
const args = ["open", input.url];
|
|
125
|
-
if (input.headless === false) args.push("--headed");
|
|
126
|
-
if (input.profile ?? deps.profile) args.push("--profile", input.profile ?? deps.profile!);
|
|
127
|
-
const r = await runAgentBrowser(deps, args, { json: true });
|
|
128
|
-
if (!r.ok) {
|
|
129
|
-
deps.logger.warn(`bizar_browser_open failed: ${r.stderr}`);
|
|
130
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
131
|
-
}
|
|
132
|
-
return { ok: true as const, url: input.url, snapshot: r.json, stdout: r.stdout };
|
|
133
|
-
},
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// ─── tool: bizar_browser_snapshot ────────────────────────────────────────
|
|
138
|
-
export type BizarBrowserSnapshotInput = z.infer<typeof bizarBrowserSnapshotSchema>;
|
|
139
|
-
export type BizarBrowserSnapshotOutput =
|
|
140
|
-
| { ok: true; snapshot: unknown; stdout: string }
|
|
141
|
-
| { ok: false; error: string; stderr: string };
|
|
142
|
-
|
|
143
|
-
const bizarBrowserSnapshotSchema = z.object({
|
|
144
|
-
max_depth: z.number().int().positive().optional().describe("Optional subtree depth limit."),
|
|
145
|
-
format: z.enum(["json", "ai"]).optional().describe("Output format. Default: json."),
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
export function createBrowserSnapshotTool(
|
|
149
|
-
deps: AgentBrowserDeps,
|
|
150
|
-
): AgentTool<BizarBrowserSnapshotInput, BizarBrowserSnapshotOutput> {
|
|
151
|
-
return createTool({
|
|
152
|
-
name: BIZAR_BROWSER_SNAPSHOT_TOOL_NAME,
|
|
153
|
-
description:
|
|
154
|
-
"Get the current page's accessibility tree with stable refs (@e1, @e2, …). " +
|
|
155
|
-
"Ref-based selectors survive page-snapshot churn better than CSS selectors. " +
|
|
156
|
-
"Returns structured JSON by default; pass format='ai' for a compact text variant.",
|
|
157
|
-
inputSchema: bizarBrowserSnapshotSchema.shape,
|
|
158
|
-
execute: async (input) => {
|
|
159
|
-
const format = input.format ?? "json";
|
|
160
|
-
const args = ["snapshot", format === "ai" ? "--ai" : "--json"];
|
|
161
|
-
if (input.max_depth) args.push("--max-depth", String(input.max_depth));
|
|
162
|
-
const r = await runAgentBrowser(deps, args, { json: true });
|
|
163
|
-
if (!r.ok) {
|
|
164
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
165
|
-
}
|
|
166
|
-
return { ok: true as const, snapshot: r.json, stdout: r.stdout };
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ─── tool: bizar_browser_click ──────────────────────────────────────────
|
|
172
|
-
export type BizarBrowserClickInput = z.infer<typeof bizarBrowserClickSchema>;
|
|
173
|
-
export type BizarBrowserClickOutput =
|
|
174
|
-
| { ok: true; clicked: string; stdout: string }
|
|
175
|
-
| { ok: false; error: string; stderr: string };
|
|
176
|
-
|
|
177
|
-
const bizarBrowserClickSchema = z.object({
|
|
178
|
-
selector: z.string().min(1).describe("Element to click. Prefer a ref from snapshot (e.g. '@e2'); CSS selectors and role/name tuples also accepted."),
|
|
179
|
-
new_tab: z.boolean().optional().describe("Open the link in a new tab."),
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
export function createBrowserClickTool(
|
|
183
|
-
deps: AgentBrowserDeps,
|
|
184
|
-
): AgentTool<BizarBrowserClickInput, BizarBrowserClickOutput> {
|
|
185
|
-
return createTool({
|
|
186
|
-
name: BIZAR_BROWSER_CLICK_TOOL_NAME,
|
|
187
|
-
description:
|
|
188
|
-
"Click an element identified by ref (preferred) or selector. " +
|
|
189
|
-
"Ref-based selectors (@e2) are stable across snapshots; CSS selectors and " +
|
|
190
|
-
"role/name tuples are also accepted. Pass new_tab=true to open link targets in a new tab.",
|
|
191
|
-
inputSchema: bizarBrowserClickSchema.shape,
|
|
192
|
-
execute: async (input) => {
|
|
193
|
-
const args = ["click", input.selector];
|
|
194
|
-
if (input.new_tab) args.push("--new-tab");
|
|
195
|
-
const r = await runAgentBrowser(deps, args);
|
|
196
|
-
if (!r.ok) {
|
|
197
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
198
|
-
}
|
|
199
|
-
return { ok: true as const, clicked: input.selector, stdout: r.stdout };
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// ─── tool: bizar_browser_fill ───────────────────────────────────────────
|
|
205
|
-
export type BizarBrowserFillInput = z.infer<typeof bizarBrowserFillSchema>;
|
|
206
|
-
export type BizarBrowserFillOutput =
|
|
207
|
-
| { ok: true; filled: string; value: string; stdout: string }
|
|
208
|
-
| { ok: false; error: string; stderr: string };
|
|
209
|
-
|
|
210
|
-
const bizarBrowserFillSchema = z.object({
|
|
211
|
-
selector: z.string().min(1).describe("Element to fill (ref like '@e3' or CSS selector)."),
|
|
212
|
-
value: z.string().describe("Value to fill."),
|
|
213
|
-
submit: z.boolean().optional().describe("If true, press Enter after filling."),
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
export function createBrowserFillTool(
|
|
217
|
-
deps: AgentBrowserDeps,
|
|
218
|
-
): AgentTool<BizarBrowserFillInput, BizarBrowserFillOutput> {
|
|
219
|
-
return createTool({
|
|
220
|
-
name: BIZAR_BROWSER_FILL_TOOL_NAME,
|
|
221
|
-
description:
|
|
222
|
-
"Clear and fill an input. Uses ref or selector. The agent-browser " +
|
|
223
|
-
"fill command replaces text content (unlike `type` which appends).",
|
|
224
|
-
inputSchema: bizarBrowserFillSchema.shape,
|
|
225
|
-
execute: async (input) => {
|
|
226
|
-
const args = ["fill", input.selector, input.value];
|
|
227
|
-
if (input.submit) args.push("--submit");
|
|
228
|
-
const r = await runAgentBrowser(deps, args);
|
|
229
|
-
if (!r.ok) {
|
|
230
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
231
|
-
}
|
|
232
|
-
return { ok: true as const, filled: input.selector, value: input.value, stdout: r.stdout };
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// ─── tool: bizar_browser_screenshot ─────────────────────────────────────
|
|
238
|
-
export type BizarBrowserScreenshotInput = z.infer<typeof bizarBrowserScreenshotSchema>;
|
|
239
|
-
export type BizarBrowserScreenshotOutput =
|
|
240
|
-
| { ok: true; path: string; bytes?: number; stdout: string }
|
|
241
|
-
| { ok: false; error: string; stderr: string };
|
|
242
|
-
|
|
243
|
-
const bizarBrowserScreenshotSchema = z.object({
|
|
244
|
-
path: z.string().min(1).describe("Output file path (relative paths resolve to the worktree)."),
|
|
245
|
-
full_page: z.boolean().optional().describe("Capture the entire scrollable area."),
|
|
246
|
-
element: z.string().optional().describe("Capture only this ref (e.g. '@e4')."),
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
export function createBrowserScreenshotTool(
|
|
250
|
-
deps: AgentBrowserDeps,
|
|
251
|
-
): AgentTool<BizarBrowserScreenshotInput, BizarBrowserScreenshotOutput> {
|
|
252
|
-
return createTool({
|
|
253
|
-
name: BIZAR_BROWSER_SCREENSHOT_TOOL_NAME,
|
|
254
|
-
description:
|
|
255
|
-
"Take a screenshot of the current page (or an element) and save it to `path`. " +
|
|
256
|
-
"Use full_page=true to capture the entire scrollable area, or pass element='@eN' " +
|
|
257
|
-
"to capture a single element. Returns the absolute path of the written file.",
|
|
258
|
-
inputSchema: bizarBrowserScreenshotSchema.shape,
|
|
259
|
-
execute: async (input) => {
|
|
260
|
-
const args = ["screenshot", input.path];
|
|
261
|
-
if (input.full_page) args.push("--full-page");
|
|
262
|
-
if (input.element) args.push("--element", input.element);
|
|
263
|
-
const r = await runAgentBrowser(deps, args);
|
|
264
|
-
if (!r.ok) {
|
|
265
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
266
|
-
}
|
|
267
|
-
return { ok: true as const, path: input.path, stdout: r.stdout };
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ─── tool: bizar_browser_command (escape hatch) ─────────────────────────
|
|
273
|
-
export type BizarBrowserCommandInput = z.infer<typeof bizarBrowserCommandSchema>;
|
|
274
|
-
export type BizarBrowserCommandOutput =
|
|
275
|
-
| { ok: true; stdout: string; stderr: string; exitCode: number; json?: unknown }
|
|
276
|
-
| { ok: false; error: string; stderr: string };
|
|
277
|
-
|
|
278
|
-
const bizarBrowserCommandSchema = z.object({
|
|
279
|
-
args: z.array(z.string()).describe(
|
|
280
|
-
"Argv to pass to agent-browser (e.g. ['eval', 'document.title']). " +
|
|
281
|
-
"Use this escape hatch for the 100+ commands not exposed as dedicated tools " +
|
|
282
|
-
"(eval, wait, press, find role, hover, scroll, tab list/open/switch, etc.)."
|
|
283
|
-
),
|
|
284
|
-
json: z.boolean().optional().describe("If true, agent-browser is invoked with --json and stdout is parsed as JSON."),
|
|
285
|
-
timeoutMs: z.number().int().positive().optional().describe("Max execution time, default 30s."),
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
export function createBrowserCommandTool(
|
|
289
|
-
deps: AgentBrowserDeps,
|
|
290
|
-
): AgentTool<BizarBrowserCommandInput, BizarBrowserCommandOutput> {
|
|
291
|
-
return createTool({
|
|
292
|
-
name: BIZAR_BROWSER_COMMAND_TOOL_NAME,
|
|
293
|
-
description:
|
|
294
|
-
"Escape hatch: invoke any agent-browser CLI command by argv. Returns stdout, stderr, " +
|
|
295
|
-
"and exit code. Use the dedicated tools (bizar_browser_open/snapshot/click/fill/screenshot) " +
|
|
296
|
-
"for common operations; this is for the 100+ commands they don't cover.",
|
|
297
|
-
inputSchema: bizarBrowserCommandSchema.shape,
|
|
298
|
-
execute: async (input) => {
|
|
299
|
-
const r = await runAgentBrowser(deps, input.args, {
|
|
300
|
-
json: input.json,
|
|
301
|
-
timeoutMs: input.timeoutMs,
|
|
302
|
-
});
|
|
303
|
-
if (!r.ok) {
|
|
304
|
-
return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
|
|
305
|
-
}
|
|
306
|
-
return {
|
|
307
|
-
ok: true as const,
|
|
308
|
-
stdout: r.stdout,
|
|
309
|
-
stderr: r.stderr,
|
|
310
|
-
exitCode: r.exitCode,
|
|
311
|
-
json: r.json,
|
|
312
|
-
};
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bg-collect.ts
|
|
3
|
-
*
|
|
4
|
-
* `bizar_collect` tool (v0.4.2 spec §7.1, §4.4).
|
|
5
|
-
*
|
|
6
|
-
* Odin-only — only Odin may collect. Blocks until the instance reaches a
|
|
7
|
-
* terminal state or `timeoutMs` elapses. On timeout, returns
|
|
8
|
-
* `status: "running"` with the last known `resultPreview`.
|
|
9
|
-
*
|
|
10
|
-
* Returns:
|
|
11
|
-
* `{ instanceId, status, result, toolCallCount, durationMs, error? }`
|
|
12
|
-
*
|
|
13
|
-
* The `result` field is the concatenated text of all assistant messages
|
|
14
|
-
* (TextPart only). If the instance ended with a threshold-12 loop-guard
|
|
15
|
-
* error, the marker `[loop guard: 12 identical calls to <tool>]` is
|
|
16
|
-
* prepended (MEDIUM-30).
|
|
17
|
-
*
|
|
18
|
-
* Cline SDK port (Phase 2):
|
|
19
|
-
* - Uses `createTool` from `@cline/sdk` directly.
|
|
20
|
-
* - Adds `name: BIZAR_COLLECT_TOOL_NAME`.
|
|
21
|
-
* - `inputSchema` is `z.object(...)` over the same fields as before.
|
|
22
|
-
* - Returns structured `{ ok, instanceId, status, ... }` instead of
|
|
23
|
-
* `{ output: JSON.stringify(...) }`.
|
|
24
|
-
* - `ctx.agent` becomes `context.metadata.parentAgent` look-up.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import { createTool, type AgentTool } from "@cline/sdk";
|
|
28
|
-
import { z } from "zod";
|
|
29
|
-
|
|
30
|
-
import type { InstanceManager } from "../background.js";
|
|
31
|
-
import type { Logger } from "../logger.js";
|
|
32
|
-
|
|
33
|
-
const TIMEOUT_MIN_MS = 1000;
|
|
34
|
-
const TIMEOUT_MAX_MS = 1_800_000;
|
|
35
|
-
const TIMEOUT_DEFAULT_MS = 60_000;
|
|
36
|
-
|
|
37
|
-
export const BIZAR_COLLECT_TOOL_NAME = "bizar_collect";
|
|
38
|
-
|
|
39
|
-
export interface BgCollectDeps {
|
|
40
|
-
instanceManager: InstanceManager;
|
|
41
|
-
logger: Logger;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export type BizarCollectInput = z.infer<typeof bizarCollectSchema>;
|
|
45
|
-
export type BizarCollectOutput =
|
|
46
|
-
| {
|
|
47
|
-
ok: true;
|
|
48
|
-
instanceId: string;
|
|
49
|
-
status: string;
|
|
50
|
-
result: string;
|
|
51
|
-
toolCallCount: number;
|
|
52
|
-
durationMs: number;
|
|
53
|
-
error?: string;
|
|
54
|
-
}
|
|
55
|
-
| { ok: false; error: string; instanceId?: string };
|
|
56
|
-
|
|
57
|
-
const bizarCollectSchema = z.object({
|
|
58
|
-
instanceId: z
|
|
59
|
-
.string()
|
|
60
|
-
.min(1)
|
|
61
|
-
.describe("Instance id returned by bizar_spawn_background."),
|
|
62
|
-
timeoutMs: z
|
|
63
|
-
.number()
|
|
64
|
-
.int()
|
|
65
|
-
.positive()
|
|
66
|
-
.optional()
|
|
67
|
-
.describe("Collect-time timeout in ms (1s..30min, default 60s)."),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Build the `bizar_collect` tool. The plugin wires the result into
|
|
72
|
-
* `api.registerTool()` from `AgentExtensionApi`. The `deps` closure
|
|
73
|
-
* carries the InstanceManager.
|
|
74
|
-
*/
|
|
75
|
-
export function createBgCollectTool(
|
|
76
|
-
deps: BgCollectDeps,
|
|
77
|
-
): AgentTool<BizarCollectInput, BizarCollectOutput> {
|
|
78
|
-
return createTool({
|
|
79
|
-
name: BIZAR_COLLECT_TOOL_NAME,
|
|
80
|
-
description:
|
|
81
|
-
"Wait for a background instance to complete and return its result. " +
|
|
82
|
-
"Only Odin may collect. Blocks until the instance reaches a terminal state or the timeout fires.",
|
|
83
|
-
inputSchema: bizarCollectSchema.shape,
|
|
84
|
-
execute: async (input, context) => {
|
|
85
|
-
// Odin-only (§6.3).
|
|
86
|
-
const parentAgent =
|
|
87
|
-
(context.metadata as { parentAgent?: string } | undefined)?.parentAgent ?? null;
|
|
88
|
-
if (parentAgent !== "odin") {
|
|
89
|
-
return {
|
|
90
|
-
ok: false as const,
|
|
91
|
-
error:
|
|
92
|
-
"Only Odin can collect background agent results. Use bizar_status to inspect or ask Odin to collect.",
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Clamp timeoutMs (MEDIUM-33 / §7.3).
|
|
97
|
-
const requested = input.timeoutMs ?? TIMEOUT_DEFAULT_MS;
|
|
98
|
-
if (requested < TIMEOUT_MIN_MS || requested > TIMEOUT_MAX_MS) {
|
|
99
|
-
return {
|
|
100
|
-
ok: false as const,
|
|
101
|
-
error: `timeoutMs must be between ${TIMEOUT_MIN_MS} (1s) and ${TIMEOUT_MAX_MS} (30min). Got ${requested}.`,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
const timeoutMs = requested;
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const result = await deps.instanceManager.collect(input.instanceId, timeoutMs);
|
|
108
|
-
return {
|
|
109
|
-
ok: true as const,
|
|
110
|
-
instanceId: input.instanceId,
|
|
111
|
-
status: result.status,
|
|
112
|
-
result: result.result,
|
|
113
|
-
toolCallCount: result.toolCallCount,
|
|
114
|
-
durationMs: result.durationMs,
|
|
115
|
-
...(result.error !== undefined ? { error: result.error } : {}),
|
|
116
|
-
};
|
|
117
|
-
} catch (err: unknown) {
|
|
118
|
-
deps.logger.warn(
|
|
119
|
-
`bizar: collect(${input.instanceId}) failed: ${
|
|
120
|
-
err instanceof Error ? err.message : String(err)
|
|
121
|
-
}`,
|
|
122
|
-
);
|
|
123
|
-
return {
|
|
124
|
-
ok: false as const,
|
|
125
|
-
error: `collect failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
126
|
-
instanceId: input.instanceId,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
}
|