@polderlabs/bizar 3.23.1 → 4.2.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/README.md +83 -16
- package/bizar-dash/.bizar/activity.log +3 -0
- package/bizar-dash/.bizar/graph/.graphify_analysis.json +1540 -0
- package/bizar-dash/.bizar/graph/.graphify_labels.json +1 -0
- package/bizar-dash/.bizar/graph/GRAPH_REPORT.md +404 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/0661b816358db84dfdb7f10443db8a61152fd20b3fee950caf8fbf32920a1790.json +1 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/16da06d774142a6e5d74829ad982531286a6193ef798de8f593db029e123ec32.json +1 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/27e5697c01254c69c64c5a33896669073b40afb5ba88375102ae77fa5404136d.json +1 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/532997898027254aa4c0932243dc71d2f55888181232b65974961934997dc85b.json +1 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/84e3451a64c7f99f0cd6a88b0748d7426780486f53ab4935b7476b28c08f8293.json +1 -0
- package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/88e5ea5f3e78fa69353fe9e6a8d1a05391d54605e25600cb125531eb5a6432ff.json +1 -0
- package/bizar-dash/.bizar/graph/cache/stat-index.json +1 -0
- package/bizar-dash/.bizar/graph/graph.html +307 -0
- package/bizar-dash/.bizar/graph/graph.json +40267 -0
- package/bizar-dash/.bizar/graph/manifest.json +762 -0
- package/bizar-dash/.graphifyignore +40 -0
- package/bizar-dash/.obsidian/README.md +14 -0
- package/bizar-dash/.obsidian/daily/2026-06-25.md +9 -0
- package/bizar-dash/.obsidian/vault.json +7 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/SKILL.md +103 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/assets/template.html +338 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/example.html +81 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/open-design.json +172 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/references/checklist.md +44 -0
- package/bizar-dash/.od-skills/web-prototype-e1429c1737/references/layouts.md +247 -0
- package/bizar-dash/CHANGELOG.md +474 -0
- package/bizar-dash/DESIGN.md +136 -0
- package/bizar-dash/dist/assets/main-B3RgW6FS.js +331 -0
- package/bizar-dash/dist/assets/main-B3RgW6FS.js.map +1 -0
- package/bizar-dash/dist/assets/main-DlJ8wgLR.css +1 -0
- package/bizar-dash/dist/assets/mobile-CsZQAswA.css +1 -0
- package/bizar-dash/dist/assets/mobile-DbxIw8BG.js +2 -0
- package/bizar-dash/dist/assets/mobile-DbxIw8BG.js.map +1 -0
- package/bizar-dash/dist/assets/mobile-Dvq2d53Y.js +354 -0
- package/bizar-dash/dist/assets/mobile-Dvq2d53Y.js.map +1 -0
- package/bizar-dash/dist/index.html +40 -0
- package/bizar-dash/dist/mobile.html +22 -0
- package/bizar-dash/plans/debug-plan/comments.json +1 -0
- package/bizar-dash/plans/debug-plan/meta.json +10 -0
- package/bizar-dash/plans/debug-plan/plan.json +174 -0
- package/bizar-dash/scripts/smoke-bg-retry.mjs +246 -0
- package/bizar-dash/src/cli/dashboard-ports.mjs +488 -0
- package/bizar-dash/src/cli.mjs +522 -0
- package/bizar-dash/src/server/activity-log.mjs +174 -0
- package/bizar-dash/src/server/agents-store.mjs +465 -0
- package/bizar-dash/src/server/api.mjs +138 -0
- package/bizar-dash/src/server/artifact-template.html +810 -0
- package/bizar-dash/src/server/artifacts-store.mjs +733 -0
- package/bizar-dash/src/server/auth.mjs +381 -0
- package/bizar-dash/src/server/background-store.mjs +447 -0
- package/bizar-dash/src/server/bg-poller.mjs +305 -0
- package/bizar-dash/src/server/bg-retry.mjs +574 -0
- package/bizar-dash/src/server/browser.mjs +40 -0
- package/bizar-dash/src/server/diagnostics-store.mjs +148 -0
- package/bizar-dash/src/server/dialog-poller.mjs +105 -0
- package/bizar-dash/src/server/dialog-store.mjs +177 -0
- package/bizar-dash/src/server/glyphs/mdx-compiler.mjs +583 -0
- package/bizar-dash/src/server/lib/path-safe.mjs +283 -0
- package/bizar-dash/src/server/memory-git.mjs +329 -0
- package/bizar-dash/src/server/memory-lightrag.mjs +767 -0
- package/bizar-dash/src/server/memory-schema.mjs +145 -0
- package/bizar-dash/src/server/memory-secrets.mjs +84 -0
- package/bizar-dash/src/server/memory-store.mjs +471 -0
- package/bizar-dash/src/server/mod-security.mjs +398 -0
- package/bizar-dash/src/server/mods-loader.mjs +1067 -0
- package/bizar-dash/src/server/notifications-store.mjs +243 -0
- package/bizar-dash/src/server/obsidian-store.mjs +318 -0
- package/bizar-dash/src/server/opencode-runner.mjs +279 -0
- package/bizar-dash/src/server/pair-store.mjs +138 -0
- package/bizar-dash/src/server/projects-store.mjs +364 -0
- package/bizar-dash/src/server/providers-store.mjs +789 -0
- package/bizar-dash/src/server/routes/_shared.mjs +415 -0
- package/bizar-dash/src/server/routes/activity.mjs +110 -0
- package/bizar-dash/src/server/routes/agents.mjs +134 -0
- package/bizar-dash/src/server/routes/artifacts.mjs +279 -0
- package/bizar-dash/src/server/routes/auth.mjs +69 -0
- package/bizar-dash/src/server/routes/background.mjs +165 -0
- package/bizar-dash/src/server/routes/chat.mjs +485 -0
- package/bizar-dash/src/server/routes/config.mjs +129 -0
- package/bizar-dash/src/server/routes/diagnostics.mjs +50 -0
- package/bizar-dash/src/server/routes/dialogs.mjs +86 -0
- package/bizar-dash/src/server/routes/fs.mjs +429 -0
- package/bizar-dash/src/server/routes/history.mjs +78 -0
- package/bizar-dash/src/server/routes/memory.mjs +658 -0
- package/bizar-dash/src/server/routes/misc.mjs +89 -0
- package/bizar-dash/src/server/routes/mods.mjs +359 -0
- package/bizar-dash/src/server/routes/notifications.mjs +54 -0
- package/bizar-dash/src/server/routes/obsidian.mjs +239 -0
- package/bizar-dash/src/server/routes/opencode-sessions.mjs +55 -0
- package/bizar-dash/src/server/routes/overview.mjs +91 -0
- package/bizar-dash/src/server/routes/pair.mjs +67 -0
- package/bizar-dash/src/server/routes/projects.mjs +175 -0
- package/bizar-dash/src/server/routes/providers.mjs +47 -0
- package/bizar-dash/src/server/routes/schedules.mjs +104 -0
- package/bizar-dash/src/server/routes/settings.mjs +51 -0
- package/bizar-dash/src/server/routes/skills.mjs +76 -0
- package/bizar-dash/src/server/routes/tasks.mjs +468 -0
- package/bizar-dash/src/server/routes/themes.mjs +51 -0
- package/bizar-dash/src/server/routes-v2/auth.mjs +59 -0
- package/bizar-dash/src/server/routes-v2/events.mjs +107 -0
- package/bizar-dash/src/server/routes-v2/health.mjs +21 -0
- package/bizar-dash/src/server/routes-v2/index.mjs +90 -0
- package/bizar-dash/src/server/routes-v2/sessions.mjs +111 -0
- package/bizar-dash/src/server/schedules-runner.mjs +369 -0
- package/bizar-dash/src/server/schedules-store.mjs +268 -0
- package/bizar-dash/src/server/search-store.mjs +220 -0
- package/bizar-dash/src/server/serve-info.mjs +684 -0
- package/bizar-dash/src/server/server.mjs +796 -0
- package/bizar-dash/src/server/settings-store.mjs +45 -0
- package/bizar-dash/src/server/skills-store.mjs +300 -0
- package/bizar-dash/src/server/state.mjs +437 -0
- package/bizar-dash/src/server/tailscale-store.mjs +113 -0
- package/bizar-dash/src/server/task-delegator.mjs +824 -0
- package/bizar-dash/src/server/tasks-store.mjs +508 -0
- package/bizar-dash/src/server/tui.mjs +923 -0
- package/bizar-dash/src/server/update-store.mjs +168 -0
- package/bizar-dash/src/server/v2-auth-file.mjs +99 -0
- package/bizar-dash/src/server/v2-event-bus.mjs +128 -0
- package/bizar-dash/src/server/watcher.mjs +81 -0
- package/bizar-dash/src/server/yaml.mjs +238 -0
- package/bizar-dash/src/web/App.tsx +718 -0
- package/bizar-dash/src/web/MobileApp.tsx +408 -0
- package/bizar-dash/src/web/components/ArtifactCreateDialog.tsx +95 -0
- package/bizar-dash/src/web/components/ArtifactListDialog.tsx +55 -0
- package/bizar-dash/src/web/components/ArtifactViewer.tsx +143 -0
- package/bizar-dash/src/web/components/AuditDialog.tsx +79 -0
- package/bizar-dash/src/web/components/BgStatusBadge.tsx +32 -0
- package/bizar-dash/src/web/components/Button.tsx +56 -0
- package/bizar-dash/src/web/components/CanvasContextMenu.tsx +68 -0
- package/bizar-dash/src/web/components/Card.tsx +40 -0
- package/bizar-dash/src/web/components/CollapsibleSection.tsx +72 -0
- package/bizar-dash/src/web/components/CommandDialog.tsx +66 -0
- package/bizar-dash/src/web/components/EmptyState.tsx +30 -0
- package/bizar-dash/src/web/components/FileBrowser.tsx +633 -0
- package/bizar-dash/src/web/components/HelpDialog.tsx +55 -0
- package/bizar-dash/src/web/components/KillConfirmDialog.tsx +88 -0
- package/bizar-dash/src/web/components/Modal.tsx +215 -0
- package/bizar-dash/src/web/components/Notifications.tsx +241 -0
- package/bizar-dash/src/web/components/SearchModal.tsx +224 -0
- package/bizar-dash/src/web/components/Sidebar.tsx +66 -0
- package/bizar-dash/src/web/components/Spinner.tsx +19 -0
- package/bizar-dash/src/web/components/StatusBadge.tsx +25 -0
- package/bizar-dash/src/web/components/Tag.tsx +28 -0
- package/bizar-dash/src/web/components/Toast.tsx +150 -0
- package/bizar-dash/src/web/components/Topbar.tsx +368 -0
- package/bizar-dash/src/web/components/VisualPlanDialog.tsx +58 -0
- package/bizar-dash/src/web/components/chat/AgentChip.tsx +68 -0
- package/bizar-dash/src/web/components/chat/ChatBubble.tsx +60 -0
- package/bizar-dash/src/web/components/chat/ChatThread.tsx +88 -0
- package/bizar-dash/src/web/components/chat/ChatTopBar.tsx +50 -0
- package/bizar-dash/src/web/components/chat/Composer.tsx +164 -0
- package/bizar-dash/src/web/components/chat/ConfirmModal.tsx +54 -0
- package/bizar-dash/src/web/components/chat/EmptyState.tsx +21 -0
- package/bizar-dash/src/web/components/chat/FirstRunGreeting.tsx +18 -0
- package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +32 -0
- package/bizar-dash/src/web/components/chat/InfoPanel.tsx +119 -0
- package/bizar-dash/src/web/components/chat/LoadingSkeleton.tsx +19 -0
- package/bizar-dash/src/web/components/chat/MessageBubble.tsx +60 -0
- package/bizar-dash/src/web/components/chat/SessionList.tsx +153 -0
- package/bizar-dash/src/web/components/chat/StreamingIndicator.tsx +9 -0
- package/bizar-dash/src/web/components/chat/SuggestionCards.tsx +55 -0
- package/bizar-dash/src/web/components/chat/WelcomeScreen.tsx +36 -0
- package/bizar-dash/src/web/components/chat/index.ts +20 -0
- package/bizar-dash/src/web/components/chat/useAutoGrowTextarea.ts +18 -0
- package/bizar-dash/src/web/components/chat/useChat.ts +219 -0
- package/bizar-dash/src/web/components/chat/useSlashCommands.ts +47 -0
- package/bizar-dash/src/web/index.html +37 -0
- package/bizar-dash/src/web/lib/api.ts +193 -0
- package/bizar-dash/src/web/lib/markdown.tsx +59 -0
- package/bizar-dash/src/web/lib/types.ts +668 -0
- package/bizar-dash/src/web/lib/utils.ts +114 -0
- package/bizar-dash/src/web/lib/ws.ts +176 -0
- package/bizar-dash/src/web/main.tsx +34 -0
- package/bizar-dash/src/web/mobile/MobileApp.tsx +278 -0
- package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +38 -0
- package/bizar-dash/src/web/mobile/MobileTopbar.tsx +115 -0
- package/bizar-dash/src/web/mobile/components/MobileBottomSheet.tsx +182 -0
- package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +64 -0
- package/bizar-dash/src/web/mobile/components/MobileModal.tsx +123 -0
- package/bizar-dash/src/web/mobile/views/MobileActivity.tsx +273 -0
- package/bizar-dash/src/web/mobile/views/MobileAgents.tsx +374 -0
- package/bizar-dash/src/web/mobile/views/MobileArtifactCanvas.tsx +439 -0
- package/bizar-dash/src/web/mobile/views/MobileArtifacts.tsx +143 -0
- package/bizar-dash/src/web/mobile/views/MobileChat.tsx +180 -0
- package/bizar-dash/src/web/mobile/views/MobileConfig.tsx +175 -0
- package/bizar-dash/src/web/mobile/views/MobileHistory.tsx +191 -0
- package/bizar-dash/src/web/mobile/views/MobileMods.tsx +149 -0
- package/bizar-dash/src/web/mobile/views/MobileMore.tsx +121 -0
- package/bizar-dash/src/web/mobile/views/MobileNotifications.tsx +137 -0
- package/bizar-dash/src/web/mobile/views/MobilePlans.tsx +26 -0
- package/bizar-dash/src/web/mobile/views/MobileSchedules.tsx +685 -0
- package/bizar-dash/src/web/mobile/views/MobileSearchModal.tsx +172 -0
- package/bizar-dash/src/web/mobile/views/MobileSettings.tsx +388 -0
- package/bizar-dash/src/web/mobile/views/MobileSkills.tsx +153 -0
- package/bizar-dash/src/web/mobile/views/MobileTasks.tsx +564 -0
- package/bizar-dash/src/web/mobile.html +20 -0
- package/bizar-dash/src/web/mobile.tsx +13 -0
- package/bizar-dash/src/web/styles/chat.css +198 -0
- package/bizar-dash/src/web/styles/glyphs.css +960 -0
- package/bizar-dash/src/web/styles/main.css +8855 -0
- package/bizar-dash/src/web/styles/mobile-chat.css +5 -0
- package/bizar-dash/src/web/styles/mobile.css +1960 -0
- package/bizar-dash/src/web/views/Activity.tsx +1203 -0
- package/bizar-dash/src/web/views/Agents.tsx +701 -0
- package/bizar-dash/src/web/views/Artifacts.tsx +1480 -0
- package/bizar-dash/src/web/views/BackgroundAgents.tsx +450 -0
- package/bizar-dash/src/web/views/Chat.tsx +190 -0
- package/bizar-dash/src/web/views/Config.tsx +2063 -0
- package/bizar-dash/src/web/views/History.tsx +335 -0
- package/bizar-dash/src/web/views/ModView.tsx +207 -0
- package/bizar-dash/src/web/views/Mods.tsx +693 -0
- package/bizar-dash/src/web/views/Overview.tsx +812 -0
- package/bizar-dash/src/web/views/Providers.tsx +302 -0
- package/bizar-dash/src/web/views/Schedules.tsx +802 -0
- package/bizar-dash/src/web/views/Settings.tsx +1787 -0
- package/bizar-dash/src/web/views/Skills.tsx +431 -0
- package/bizar-dash/src/web/views/Tasks.tsx +1523 -0
- package/bizar-dash/src/web/views/glyphs/GlyphRenderer.tsx +613 -0
- package/bizar-dash/src/web/views/glyphs/components.tsx +1098 -0
- package/bizar-dash/templates/mod/FORMAT.md +76 -0
- package/bizar-dash/templates/mod/hello-mod/README.md +19 -0
- package/bizar-dash/templates/mod/hello-mod/agents/greeter.md +8 -0
- package/bizar-dash/templates/mod/hello-mod/commands/hello.md +6 -0
- package/bizar-dash/templates/mod/hello-mod/mod.json +20 -0
- package/bizar-dash/templates/mod/hello-mod/routes/ping.mjs +9 -0
- package/bizar-dash/templates/mod/hello-mod/views/HelloView.tsx +10 -0
- package/bizar-dash/tests/dashboard-ports.test.mjs +138 -0
- package/bizar-dash/tests/graphify-mod-spawn.node.test.mjs +90 -0
- package/bizar-dash/tests/memory-cli.test.mjs +542 -0
- package/bizar-dash/tests/memory-config.test.mjs +422 -0
- package/bizar-dash/tests/memory-git.test.mjs +246 -0
- package/bizar-dash/tests/memory-lightrag.test.mjs +153 -0
- package/bizar-dash/tests/memory-protocol-drift.test.mjs +45 -0
- package/bizar-dash/tests/memory-schema.test.mjs +198 -0
- package/bizar-dash/tests/memory-secrets.test.mjs +121 -0
- package/bizar-dash/tests/memory-store.test.mjs +390 -0
- package/bizar-dash/tests/memory-sync.test.mjs +141 -0
- package/bizar-dash/tests/mod-instructions.node.test.mjs +188 -0
- package/bizar-dash/tests/mod-security.test.mjs +273 -0
- package/bizar-dash/tests/mod-upgrade.node.test.mjs +357 -0
- package/bizar-dash/tests/no-agent-browser.node.test.mjs +98 -0
- package/bizar-dash/tests/obsidian-back-compat.test.mjs +199 -0
- package/bizar-dash/tests/opencode-runner.test.mjs +172 -0
- package/bizar-dash/tests/path-safe.test.mjs +108 -0
- package/bizar-dash/tests/providers-store-backup-keys.node.test.mjs +333 -0
- package/bizar-dash/tests/smoke-v2.mjs +212 -0
- package/bizar-dash/tests/strip-thinking.test.mjs +175 -0
- package/bizar-dash/tests/submit-feedback.test.mjs +353 -0
- package/bizar-dash/tests/tmux-wrap.test.mjs +145 -0
- package/bizar-dash/tests/yaml.test.mjs +128 -0
- package/bizar-dash/tsconfig.json +23 -0
- package/bizar-dash/vite.config.ts +27 -0
- package/cli/atomic.mjs +73 -0
- package/cli/banner.mjs +1 -1
- package/cli/bin.mjs +44 -47
- package/cli/bootstrap.mjs +1 -1
- package/cli/copy.mjs +25 -16
- package/cli/dev-link.mjs +17 -1
- package/cli/doctor.mjs +4 -4
- package/cli/doctor.test.mjs +2 -2
- package/cli/init.mjs +135 -1
- package/cli/install.mjs +31 -39
- package/cli/memory-constants.mjs +59 -0
- package/cli/memory.mjs +1436 -0
- package/cli/service.mjs +5 -6
- package/cli/utils.mjs +6 -3
- package/config/AGENTS.md +7 -7
- package/config/agents/_shared/AGENT_BASELINE.md +59 -61
- package/config/opencode.json +13 -38
- package/config/skills/memory-protocol/SKILL.md +105 -0
- package/config/skills/obsidian/SKILL.md +270 -65
- package/install.sh +59 -19
- package/package.json +49 -14
- package/packages/sdk/LICENSE +21 -0
- package/packages/sdk/README.md +80 -0
- package/packages/sdk/src/client.ts +183 -0
- package/packages/sdk/src/errors.ts +120 -0
- package/packages/sdk/src/events.ts +153 -0
- package/packages/sdk/src/index.ts +63 -0
- package/packages/sdk/src/types.ts +176 -0
- package/packages/sdk/src/version.ts +4 -0
- package/packages/sdk/tests/client.test.ts +217 -0
- package/packages/sdk/tests/errors.test.ts +108 -0
- package/packages/sdk/tests/events.test.ts +139 -0
- package/packages/sdk/tests/fixtures/fetch-mock.ts +152 -0
- package/packages/sdk/tests/fixtures/sse-mock.ts +30 -0
- package/packages/sdk/tsconfig.json +25 -0
- package/packages/sdk/vitest.config.ts +9 -0
- package/plugins/bizar/LICENSE +21 -0
- package/plugins/bizar/README.md +448 -0
- package/plugins/bizar/dist/index.js +29901 -0
- package/plugins/bizar/index.ts +1491 -0
- package/plugins/bizar/scripts/check-forbidden-imports.sh +33 -0
- package/plugins/bizar/src/background-state.ts +551 -0
- package/plugins/bizar/src/background.ts +1250 -0
- package/plugins/bizar/src/commands-impl.ts +464 -0
- package/plugins/bizar/src/commands.ts +1168 -0
- package/plugins/bizar/src/dashboard-client.ts +233 -0
- package/plugins/bizar/src/event-stream.ts +606 -0
- package/plugins/bizar/src/fingerprint.ts +120 -0
- package/plugins/bizar/src/handoff.ts +79 -0
- package/plugins/bizar/src/http-client.ts +467 -0
- package/plugins/bizar/src/key-rotation.ts +218 -0
- package/plugins/bizar/src/logger.ts +144 -0
- package/plugins/bizar/src/loop.ts +176 -0
- package/plugins/bizar/src/opencode-runner.ts +390 -0
- package/plugins/bizar/src/options.ts +421 -0
- package/plugins/bizar/src/plan-fs.ts +323 -0
- package/plugins/bizar/src/reasoning-clean.ts +454 -0
- package/plugins/bizar/src/report.ts +178 -0
- package/plugins/bizar/src/research-prompt.ts +35 -0
- package/plugins/bizar/src/serve-info.ts +228 -0
- package/plugins/bizar/src/serve.ts +496 -0
- package/plugins/bizar/src/settings.ts +349 -0
- package/plugins/bizar/src/state.ts +298 -0
- package/plugins/bizar/src/tools/bg-collect.ts +104 -0
- package/plugins/bizar/src/tools/bg-get-comments.ts +239 -0
- package/plugins/bizar/src/tools/bg-kill.ts +87 -0
- package/plugins/bizar/src/tools/bg-spawn.ts +401 -0
- package/plugins/bizar/src/tools/bg-status.ts +99 -0
- package/plugins/bizar/src/tools/open-kb.ts +191 -0
- package/plugins/bizar/src/tools/plan-action.ts +767 -0
- package/plugins/bizar/src/tools/read-glyph-feedback.ts +170 -0
- package/plugins/bizar/src/tools/wait-for-feedback.ts +402 -0
- package/plugins/bizar/tests/attach-handler-bug.test.ts +169 -0
- package/plugins/bizar/tests/background-state.test.ts +277 -0
- package/plugins/bizar/tests/background.test.ts +402 -0
- package/plugins/bizar/tests/block.test.ts +195 -0
- package/plugins/bizar/tests/canonical-key-order.test.ts +75 -0
- package/plugins/bizar/tests/commands-impl.test.ts +442 -0
- package/plugins/bizar/tests/commands.test.ts +584 -0
- package/plugins/bizar/tests/config.test.ts +122 -0
- package/plugins/bizar/tests/dashboard-client.test.ts +159 -0
- package/plugins/bizar/tests/dispose.test.ts +336 -0
- package/plugins/bizar/tests/event-stream.test.ts +409 -0
- package/plugins/bizar/tests/event.test.ts +262 -0
- package/plugins/bizar/tests/fingerprint.test.ts +162 -0
- package/plugins/bizar/tests/http-client.test.ts +404 -0
- package/plugins/bizar/tests/init-helpers.test.ts +203 -0
- package/plugins/bizar/tests/integration/slash-command.test.ts +348 -0
- package/plugins/bizar/tests/integration/tool-routing.test.ts +314 -0
- package/plugins/bizar/tests/key-rotation.test.ts +396 -0
- package/plugins/bizar/tests/loop.test.ts +397 -0
- package/plugins/bizar/tests/options.test.ts +276 -0
- package/plugins/bizar/tests/reasoning-clean.test.ts +422 -0
- package/plugins/bizar/tests/serve.test.ts +339 -0
- package/plugins/bizar/tests/settings.test.ts +351 -0
- package/plugins/bizar/tests/stall-think.test.ts +750 -0
- package/plugins/bizar/tests/state.test.ts +276 -0
- package/plugins/bizar/tests/tools/bg-collect.test.ts +337 -0
- package/plugins/bizar/tests/tools/bg-get-comments.test.ts +485 -0
- package/plugins/bizar/tests/tools/bg-kill.test.ts +235 -0
- package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +147 -0
- package/plugins/bizar/tests/tools/bg-spawn.test.ts +311 -0
- package/plugins/bizar/tests/tools/bg-status.test.ts +217 -0
- package/plugins/bizar/tests/tools/opencode-runner.test.ts +115 -0
- package/plugins/bizar/tests/tools/plan-action.test.ts +599 -0
- package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +253 -0
- package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +390 -0
- package/plugins/bizar/tests/update-deadlock.test.ts +145 -0
- package/plugins/bizar/tsconfig.json +29 -0
package/cli/atomic.mjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/server/atomic.mjs
|
|
3
|
+
*
|
|
4
|
+
* Atomic file I/O utilities for the Bizar Memory Service. Uses the
|
|
5
|
+
* proven tmp+rename pattern to ensure files are either fully written or
|
|
6
|
+
* not written at all (no partial writes on crash).
|
|
7
|
+
*
|
|
8
|
+
* tmp files use `process.ppid + process.pid` to avoid collisions when
|
|
9
|
+
* multiple processes race on the same file.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { writeFileSync, renameSync, existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Atomically write a JSON file. Write to a temp file then rename over
|
|
16
|
+
* the target so readers never see a partially-written document.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} filePath
|
|
19
|
+
* @param {unknown} data — will be JSON-stringified with 2-space indent
|
|
20
|
+
*/
|
|
21
|
+
export function atomicWriteJson(filePath, data) {
|
|
22
|
+
const tmp = `${filePath}.tmp.${process.ppid}+${process.pid}`;
|
|
23
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
24
|
+
renameSync(tmp, filePath);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Atomically write a text file.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} filePath
|
|
31
|
+
* @param {string} text
|
|
32
|
+
*/
|
|
33
|
+
export function atomicWriteText(filePath, text) {
|
|
34
|
+
const tmp = `${filePath}.tmp.${process.ppid}+${process.pid}`;
|
|
35
|
+
writeFileSync(tmp, text, 'utf8');
|
|
36
|
+
renameSync(tmp, filePath);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Safe JSON read. Returns `fallback` on any error (missing file,
|
|
41
|
+
* empty file, malformed JSON, permission error).
|
|
42
|
+
*
|
|
43
|
+
* @template T
|
|
44
|
+
* @param {string} filePath
|
|
45
|
+
* @param {T} [fallback=null]
|
|
46
|
+
* @returns {T}
|
|
47
|
+
*/
|
|
48
|
+
export function safeReadJSON(filePath, fallback = null) {
|
|
49
|
+
try {
|
|
50
|
+
if (!existsSync(filePath)) return fallback;
|
|
51
|
+
const text = readFileSync(filePath, 'utf8');
|
|
52
|
+
if (!text.trim()) return fallback;
|
|
53
|
+
return JSON.parse(text);
|
|
54
|
+
} catch {
|
|
55
|
+
return fallback;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Safe text read. Returns `fallback` on any error.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} filePath
|
|
63
|
+
* @param {string} [fallback='']
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
66
|
+
export function safeReadText(filePath, fallback = '') {
|
|
67
|
+
try {
|
|
68
|
+
if (!existsSync(filePath)) return fallback;
|
|
69
|
+
return readFileSync(filePath, 'utf8');
|
|
70
|
+
} catch {
|
|
71
|
+
return fallback;
|
|
72
|
+
}
|
|
73
|
+
}
|
package/cli/banner.mjs
CHANGED
|
@@ -25,7 +25,7 @@ export function showBanner() {
|
|
|
25
25
|
console.log(chalk.hex('#6366f1').bold(RUNE_HELM));
|
|
26
26
|
console.log(chalk.hex('#a855f7')(' Norse Pantheon Agent System for opencode'));
|
|
27
27
|
console.log();
|
|
28
|
-
console.log(chalk.dim(' 13 agents · 4 cost tiers · Obsidian vault long-term memory ·
|
|
28
|
+
console.log(chalk.dim(' 13 agents · 4 cost tiers · Obsidian vault long-term memory · Headroom · Semble · Skills CLI · Mods'));
|
|
29
29
|
console.log();
|
|
30
30
|
}
|
|
31
31
|
|
package/cli/bin.mjs
CHANGED
|
@@ -86,6 +86,7 @@ function showHelp() {
|
|
|
86
86
|
update Auto-update everything (opencode + bizar + dash + plugin)
|
|
87
87
|
service Manage the background service daemon
|
|
88
88
|
bg <subcommand> Manage background agents (list/view/kill/logs)
|
|
89
|
+
memory <subcommand> Manage project memory (Bizar Memory Service)
|
|
89
90
|
dash <subcommand> Manage the dashboard (start/stop/status/cleanup/tui)
|
|
90
91
|
browser-harness-up Start Chromium for browser-harness (start/stop/status/restart)
|
|
91
92
|
dev-link [src] Symlink the local plugin source into opencode's plugin dir
|
|
@@ -271,7 +272,7 @@ function showDoctorHelp() {
|
|
|
271
272
|
• plugin path resolves
|
|
272
273
|
• @polderlabs/bizar-plugin is installed globally
|
|
273
274
|
• core agent files are installed (odin, quick, thor, tyr)
|
|
274
|
-
•
|
|
275
|
+
• headroom / semble / skills on PATH (lenient — at least one)
|
|
275
276
|
• dashboard reachable (skipped if no port file)
|
|
276
277
|
• provider.minimax block + MiniMax model flags are sane
|
|
277
278
|
|
|
@@ -487,12 +488,26 @@ function showDashHelp() {
|
|
|
487
488
|
`);
|
|
488
489
|
}
|
|
489
490
|
|
|
491
|
+
function showMemoryHelp() {
|
|
492
|
+
console.log(`
|
|
493
|
+
memory <subcommand> Manage project memory (local-only or Git-shared Obsidian vault)
|
|
494
|
+
Subcommands: init, setup, status, link, unlink, write, pull, commit,
|
|
495
|
+
push, sync, reindex, conflicts, doctor
|
|
496
|
+
`);
|
|
497
|
+
}
|
|
498
|
+
|
|
490
499
|
/**
|
|
491
|
-
* Detect whether
|
|
492
|
-
*
|
|
493
|
-
*
|
|
500
|
+
* Detect whether the dashboard CLI is available.
|
|
501
|
+
* v4.0.0: primary path is the relative one (dashboard ships inside the
|
|
502
|
+
* same package at bizar-dash/src/cli.mjs). A global-npm fallback is
|
|
503
|
+
* kept for legacy users who still have @polderlabs/bizar-dash installed.
|
|
494
504
|
*/
|
|
495
505
|
async function findBizarDash() {
|
|
506
|
+
// v4.0.0 — primary: relative import inside the same package
|
|
507
|
+
const primaryPath = join(import.meta.dirname, '..', 'bizar-dash', 'src', 'cli.mjs');
|
|
508
|
+
if (existsSync(primaryPath)) return primaryPath;
|
|
509
|
+
|
|
510
|
+
// Legacy fallback: global npm install of @polderlabs/bizar-dash
|
|
496
511
|
const { execSync } = await import('node:child_process');
|
|
497
512
|
try {
|
|
498
513
|
const root = execSync('npm root -g', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
@@ -513,9 +528,9 @@ async function findBizarDash() {
|
|
|
513
528
|
async function delegateToDash(argsForDash) {
|
|
514
529
|
const dashPath = await findBizarDash();
|
|
515
530
|
if (!dashPath) {
|
|
516
|
-
console.log('The Bizar dashboard
|
|
517
|
-
console.log('
|
|
518
|
-
console.log(
|
|
531
|
+
console.log('The Bizar dashboard is part of this package.');
|
|
532
|
+
console.log('If you see this error, the install may be corrupted.');
|
|
533
|
+
console.log('Please report at: github.com/DrB0rk/BizarHarness/issues');
|
|
519
534
|
return;
|
|
520
535
|
}
|
|
521
536
|
const { spawn } = await import('node:child_process');
|
|
@@ -627,6 +642,12 @@ async function main() {
|
|
|
627
642
|
} else if (args[0] === 'init') {
|
|
628
643
|
if (isHelpRequest) showInitHelp();
|
|
629
644
|
else await runInit(process.cwd());
|
|
645
|
+
} else if (args[0] === 'memory') {
|
|
646
|
+
if (isHelpRequest && !args[1]) showMemoryHelp();
|
|
647
|
+
else {
|
|
648
|
+
const { runMemory } = await import('./memory.mjs');
|
|
649
|
+
await runMemory(args[1], args.slice(2));
|
|
650
|
+
}
|
|
630
651
|
} else if (args[0] === 'export') {
|
|
631
652
|
if (isHelpRequest) showExportHelp();
|
|
632
653
|
else await runExport(parseFlag('--target'));
|
|
@@ -750,48 +771,25 @@ function parseDashOpts(dashArgs) {
|
|
|
750
771
|
|
|
751
772
|
/**
|
|
752
773
|
* Try to load the dashboard CLI module.
|
|
753
|
-
*
|
|
754
|
-
*
|
|
774
|
+
* v4.0.0: the dashboard ships inside this package at bizar-dash/src/cli.mjs.
|
|
775
|
+
* A legacy npm-global fallback is kept for the transitional period.
|
|
755
776
|
*/
|
|
756
777
|
async function loadDashCli() {
|
|
757
|
-
//
|
|
758
|
-
|
|
759
|
-
const mod = await import('@polderlabs/bizar-dash/dash-cli');
|
|
760
|
-
return mod;
|
|
761
|
-
} catch (_e) {
|
|
762
|
-
// fall through to file probing
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
// Try 2: dynamic npm root -g (most reliable for global installs)
|
|
766
|
-
try {
|
|
767
|
-
const { execFileSync } = await import('node:child_process');
|
|
768
|
-
const { pathToFileURL } = await import('node:url');
|
|
769
|
-
const { join } = await import('node:path');
|
|
770
|
-
const npmRoot = execFileSync('npm', ['root', '-g'], { encoding: 'utf8', timeout: 5000 }).trim();
|
|
771
|
-
if (npmRoot) {
|
|
772
|
-
const cliPath = join(npmRoot, '@polderlabs', 'bizar-dash', 'src', 'cli.mjs');
|
|
773
|
-
const mod = await import(pathToFileURL(cliPath).href);
|
|
774
|
-
return mod;
|
|
775
|
-
}
|
|
776
|
-
} catch (_e) {
|
|
777
|
-
/* fall through */
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
// Try 3: file path probing
|
|
781
|
-
const { join } = await import('node:path');
|
|
782
|
-
const { homedir } = await import('node:os');
|
|
778
|
+
// v4.0.0 — primary: relative import inside the same package
|
|
779
|
+
const { pathToFileURL } = await import('node:url');
|
|
783
780
|
const candidates = [
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
781
|
+
join(import.meta.dirname, '..', 'bizar-dash', 'src', 'cli.mjs'),
|
|
782
|
+
// Legacy fallbacks for users with @polderlabs/bizar-dash still installed:
|
|
783
|
+
...(async () => {
|
|
784
|
+
const { execFileSync } = await import('node:child_process');
|
|
785
|
+
try {
|
|
786
|
+
const npmRoot = execFileSync('npm', ['root', '-g'], { encoding: 'utf8', timeout: 5000 }).trim();
|
|
787
|
+
if (npmRoot) return [join(npmRoot, '@polderlabs', 'bizar-dash', 'src', 'cli.mjs')];
|
|
788
|
+
} catch { /* ignore */ }
|
|
789
|
+
return [];
|
|
790
|
+
})(),
|
|
792
791
|
];
|
|
793
792
|
|
|
794
|
-
const { pathToFileURL } = await import('node:url');
|
|
795
793
|
for (const p of candidates) {
|
|
796
794
|
try {
|
|
797
795
|
const url = pathToFileURL(p).href;
|
|
@@ -815,9 +813,8 @@ async function runDash(dashArgs) {
|
|
|
815
813
|
|
|
816
814
|
const dashModule = await loadDashCli();
|
|
817
815
|
if (!dashModule) {
|
|
818
|
-
console.error(chalk.red(' ✗ Dashboard not
|
|
819
|
-
console.error(chalk.dim('
|
|
820
|
-
console.error(chalk.dim(' Or: npx -y @polderlabs/bizar install'));
|
|
816
|
+
console.error(chalk.red(' ✗ Dashboard not found.'));
|
|
817
|
+
console.error(chalk.dim(' this should not happen — please report a bug at github.com/DrB0rk/BizarHarness/issues'));
|
|
821
818
|
process.exit(1);
|
|
822
819
|
}
|
|
823
820
|
|
package/cli/bootstrap.mjs
CHANGED
|
@@ -49,7 +49,7 @@ export function checkSetupStatus() {
|
|
|
49
49
|
*/
|
|
50
50
|
function printSetupBanner() {
|
|
51
51
|
// Use console.log directly to avoid chalk formatting issues in non-TTY
|
|
52
|
-
console.log('\n ⚡ First-time setup — Bizar needs to install agents, plugin,
|
|
52
|
+
console.log('\n ⚡ First-time setup — Bizar needs to install agents, plugin, Headroom, Semble, Skills CLI...\n');
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
package/cli/copy.mjs
CHANGED
|
@@ -289,6 +289,9 @@ export async function installPluginBizar(projectRoot) {
|
|
|
289
289
|
// The Bizar plugin now lives in a separate npm package
|
|
290
290
|
// (@polderlabs/bizar-plugin). The interactive installer copies it from
|
|
291
291
|
// there; the source tree no longer carries plugins/bizar/.
|
|
292
|
+
// TODO (forward-compat): when plugins/bizar + bizar-dash + packages/sdk are
|
|
293
|
+
// collapsed into one package, the plugin entry point will be
|
|
294
|
+
// src/plugin/index.ts and the copy source should be updated here.
|
|
292
295
|
spinner.info(chalk.dim(' ℹ No local plugins/bizar/ — using @polderlabs/bizar-plugin from npm'));
|
|
293
296
|
return { copied: 0, errors: [] };
|
|
294
297
|
}
|
|
@@ -338,43 +341,49 @@ export async function installPluginBizar(projectRoot) {
|
|
|
338
341
|
}
|
|
339
342
|
}
|
|
340
343
|
|
|
341
|
-
export async function
|
|
344
|
+
export async function installHeadroom() {
|
|
342
345
|
const { execSync } = await import('node:child_process');
|
|
343
346
|
|
|
344
347
|
const already = await detectRtk();
|
|
345
348
|
if (already) {
|
|
346
|
-
const spinner = ora({ text: 'Configuring
|
|
349
|
+
const spinner = ora({ text: 'Configuring Headroom for opencode...', color: 'magenta' }).start();
|
|
347
350
|
try {
|
|
348
|
-
execSync('
|
|
349
|
-
spinner.succeed(chalk.green('
|
|
351
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
352
|
+
spinner.succeed(chalk.green('Headroom configured for opencode'));
|
|
350
353
|
} catch {
|
|
351
|
-
spinner.warn(chalk.yellow('Could not auto-configure
|
|
354
|
+
spinner.warn(chalk.yellow('Could not auto-configure Headroom — run `headroom wrap opencode` manually'));
|
|
352
355
|
}
|
|
353
356
|
return true;
|
|
354
357
|
}
|
|
355
358
|
|
|
356
|
-
const spinner = ora({ text: 'Installing
|
|
359
|
+
const spinner = ora({ text: 'Installing Headroom (context compressor)...', color: 'magenta' }).start();
|
|
357
360
|
|
|
358
361
|
if (process.platform === 'win32') {
|
|
359
|
-
|
|
360
|
-
// Windows the user must install RTK manually (e.g. via Cargo or
|
|
361
|
-
// prebuilt binary) and re-run `rtk init -g --opencode`.
|
|
362
|
-
spinner.fail(chalk.red('Automatic RTK install not supported on Windows. Install manually from https://github.com/rtk-ai/rtk'));
|
|
362
|
+
spinner.fail(chalk.red('Automatic Headroom install not supported on Windows. Install manually: pip install "headroom-ai[all]"'));
|
|
363
363
|
return false;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
try {
|
|
367
367
|
execSync(
|
|
368
|
-
'
|
|
368
|
+
'pip install --user "headroom-ai[all]"',
|
|
369
369
|
{ stdio: 'pipe', timeout: 60000 },
|
|
370
370
|
);
|
|
371
|
-
spinner.text = 'Configuring
|
|
372
|
-
execSync('
|
|
373
|
-
spinner.succeed(chalk.green('
|
|
371
|
+
spinner.text = 'Configuring Headroom for opencode...';
|
|
372
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
373
|
+
spinner.succeed(chalk.green('Headroom installed and configured for opencode'));
|
|
374
374
|
return true;
|
|
375
375
|
} catch {
|
|
376
|
-
|
|
377
|
-
|
|
376
|
+
// Fall back to npm
|
|
377
|
+
try {
|
|
378
|
+
execSync('npm install -g headroom-ai', { stdio: 'pipe', timeout: 60000 });
|
|
379
|
+
spinner.text = 'Configuring Headroom for opencode...';
|
|
380
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
381
|
+
spinner.succeed(chalk.green('Headroom installed (npm) and configured for opencode'));
|
|
382
|
+
return true;
|
|
383
|
+
} catch {
|
|
384
|
+
spinner.fail(chalk.red('Headroom install failed. Install manually: pip install "headroom-ai[all]" or npm install -g headroom-ai'));
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
378
387
|
}
|
|
379
388
|
}
|
|
380
389
|
|
package/cli/dev-link.mjs
CHANGED
|
@@ -51,7 +51,23 @@ function pluginDest() {
|
|
|
51
51
|
* Returns true on success, false on refusal.
|
|
52
52
|
*/
|
|
53
53
|
export function createDevLink(sourceDir = null, opts = {}) {
|
|
54
|
-
const
|
|
54
|
+
const defaultSource = 'plugins/bizar';
|
|
55
|
+
const resolvedSource = resolve(process.cwd(), sourceDir ?? defaultSource);
|
|
56
|
+
|
|
57
|
+
// Forward-compatibility: if the legacy path doesn't exist, fall back to the
|
|
58
|
+
// collapsed layout (plugins/bizar + bizar-dash + sdk collapsed into one pkg).
|
|
59
|
+
// When that restructure ships, the plugin entry point will be src/plugin/index.ts.
|
|
60
|
+
if (!existsSync(resolvedSource)) {
|
|
61
|
+
const collapsedSource = resolve(process.cwd(), 'src', 'plugin', 'index.ts');
|
|
62
|
+
// Only switch if the collapsed path actually exists — preserve the original
|
|
63
|
+
// error for genuinely missing sources.
|
|
64
|
+
if (existsSync(collapsedSource)) {
|
|
65
|
+
// sourceDir was not explicitly passed — use the collapsed path silently
|
|
66
|
+
// so `bizar dev-link` works without args in the new layout.
|
|
67
|
+
resolvedSource = resolve(process.cwd(), 'src', 'plugin');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
55
71
|
const dest = pluginDest();
|
|
56
72
|
const parentDir = join(dest, '..');
|
|
57
73
|
|
package/cli/doctor.mjs
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* result without re-printing the per-check output.
|
|
10
10
|
*
|
|
11
11
|
* The checks are intentionally tolerant: missing optional tools
|
|
12
|
-
* (
|
|
13
|
-
* skipped silently if no port file exists. The goal is "is your
|
|
12
|
+
* (headroom/semble/skills) don't fail the run, and the dashboard check
|
|
13
|
+
* is skipped silently if no port file exists. The goal is "is your
|
|
14
14
|
* install healthy?" not "is every conceivable thing present?".
|
|
15
15
|
*
|
|
16
16
|
* Usage:
|
|
@@ -187,13 +187,13 @@ async function checkAgentFilesInstalled() {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/**
|
|
190
|
-
* Lenient: passes if at least one of
|
|
190
|
+
* Lenient: passes if at least one of headroom/semble/skills is on PATH.
|
|
191
191
|
* These are informational — none of them are strictly required for
|
|
192
192
|
* `bizar doctor` to do its job, and missing them shouldn't fail the
|
|
193
193
|
* overall health report.
|
|
194
194
|
*/
|
|
195
195
|
async function checkToolsAvailable() {
|
|
196
|
-
const tools = ['
|
|
196
|
+
const tools = ['headroom', 'semble', 'skills'];
|
|
197
197
|
const found = tools.filter(which);
|
|
198
198
|
if (found.length === 0) {
|
|
199
199
|
throw new Error(`none of ${tools.join('/')} on PATH`);
|
package/cli/doctor.test.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* tmpdir, and craft the opencode.json + agents/ directory to drive
|
|
9
9
|
* specific pass/fail outcomes. For checks that depend on global
|
|
10
10
|
* npm-installed packages or external CLIs (e.g. opencode --version,
|
|
11
|
-
* npm root -g, which
|
|
11
|
+
* npm root -g, which headroom), we accept that they may pass or fail
|
|
12
12
|
* depending on the test environment and just verify the framework
|
|
13
13
|
* returns the right shape.
|
|
14
14
|
*/
|
|
@@ -116,7 +116,7 @@ describe('runDoctor() shape', () => {
|
|
|
116
116
|
|
|
117
117
|
test('silent mode suppresses ALL output when nothing fails', async () => {
|
|
118
118
|
// Build a fully healthy environment. We can't make opencode reachable
|
|
119
|
-
// or
|
|
119
|
+
// or headroom installed without modifying PATH, so we settle for: no failures
|
|
120
120
|
// means no output at all. Since we know some checks will fail in a
|
|
121
121
|
// bare tmpdir, this test is structured to assert the negative case
|
|
122
122
|
// differently: we verify silent+no-fail produces 0 lines.
|
package/cli/init.mjs
CHANGED
|
@@ -87,7 +87,17 @@ export function writePrePushNotesFile(bizarDir) {
|
|
|
87
87
|
console.log(chalk.green(` ✓ Created ${ppnPath}`));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export async function runInit(cwd) {
|
|
90
|
+
export async function runInit(cwd, opts = {}) {
|
|
91
|
+
// Extract memory-related non-interactive flags from opts.
|
|
92
|
+
// Acceptable shapes:
|
|
93
|
+
// opts = { skipMemory: true }
|
|
94
|
+
// opts = { memoryMode: 'managed', memoryRepoName: 'my-repo' }
|
|
95
|
+
// opts = { memoryMode: 'local-only' }
|
|
96
|
+
// (We also accept `args` for callers that pass raw argv — uncommon since
|
|
97
|
+
// bin.mjs only calls runInit(process.cwd()) today.)
|
|
98
|
+
const skipMemory = !!opts.skipMemory || process.env.BIZAR_SKIP_INSTALL;
|
|
99
|
+
const memoryModeOpt = opts.memoryMode || null;
|
|
100
|
+
const memoryRepoNameOpt = opts.memoryRepoName || null;
|
|
91
101
|
console.log(chalk.bold.hex('#10b981')('\n ᛗ BIZARHARNESS INIT ᛗ\n'));
|
|
92
102
|
|
|
93
103
|
const bizarDir = join(cwd, '.bizar');
|
|
@@ -229,6 +239,130 @@ ${stack.runner ? `- Dev: \`${stack.runner}\`` : ''}
|
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
241
|
|
|
242
|
+
// ── Memory configuration (Bizar Memory Service Phase 1) ──────────────────
|
|
243
|
+
// Writes `.bizar/memory.json` so the dashboard / API knows where the vault
|
|
244
|
+
// lives and which mode we're in. Gated on `BIZAR_SKIP_INSTALL` and the
|
|
245
|
+
// explicit `--skip-memory` opt (callers that pre-supply a config file pass
|
|
246
|
+
// `skipMemory: true` to avoid the interactive prompt).
|
|
247
|
+
console.log(chalk.bold('\n--- Memory ---\n'));
|
|
248
|
+
const memoryJsonPath = join(bizarDir, 'memory.json');
|
|
249
|
+
if (existsSync(memoryJsonPath)) {
|
|
250
|
+
console.log(chalk.dim(` - memory config already exists at ${memoryJsonPath} (skipped)`));
|
|
251
|
+
} else if (skipMemory) {
|
|
252
|
+
console.log(chalk.dim(' - memory config: skipped (BIZAR_SKIP_INSTALL or skipMemory opt)'));
|
|
253
|
+
} else {
|
|
254
|
+
try {
|
|
255
|
+
const inquirer = (await import('inquirer')).default;
|
|
256
|
+
const initialMode = memoryModeOpt
|
|
257
|
+
? memoryModeOpt
|
|
258
|
+
: (await inquirer.prompt([{
|
|
259
|
+
type: 'list',
|
|
260
|
+
name: 'memoryMode',
|
|
261
|
+
message: 'Memory backend',
|
|
262
|
+
choices: [
|
|
263
|
+
{ name: 'managed (shared user-level repo at ~/.local/share/bizar/memory/bizar-memory/)', value: 'managed' },
|
|
264
|
+
{ name: 'local-only (vault stays in this project at .obsidian/)', value: 'local-only' },
|
|
265
|
+
],
|
|
266
|
+
default: 'managed',
|
|
267
|
+
}])).memoryMode;
|
|
268
|
+
const memoryMode = initialMode === 'managed' ? 'managed' : 'local-only';
|
|
269
|
+
|
|
270
|
+
let repoName = memoryMode === 'managed'
|
|
271
|
+
? (memoryRepoNameOpt || 'bizar-memory')
|
|
272
|
+
: null;
|
|
273
|
+
if (memoryMode === 'managed' && !memoryRepoNameOpt) {
|
|
274
|
+
const answer = await inquirer.prompt([{
|
|
275
|
+
type: 'input',
|
|
276
|
+
name: 'repoName',
|
|
277
|
+
message: 'Memory repo name',
|
|
278
|
+
default: 'bizar-memory',
|
|
279
|
+
}]);
|
|
280
|
+
repoName = answer.repoName || 'bizar-memory';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const projectId = basename(cwd) || 'project';
|
|
284
|
+
const home = process.env.HOME || process.env.USERPROFILE || process.cwd();
|
|
285
|
+
const managedPath = join(home, '.local', 'share', 'bizar', 'memory', repoName || 'bizar-memory');
|
|
286
|
+
const vaultPath = memoryMode === 'managed' ? managedPath : join(cwd, '.obsidian');
|
|
287
|
+
|
|
288
|
+
const { atomicWriteJson } = await import('./atomic.mjs');
|
|
289
|
+
const config = {
|
|
290
|
+
version: 1,
|
|
291
|
+
backend: 'bizar-local',
|
|
292
|
+
projectId,
|
|
293
|
+
memoryRepo: {
|
|
294
|
+
mode: memoryMode,
|
|
295
|
+
path: vaultPath,
|
|
296
|
+
remote: null,
|
|
297
|
+
branch: 'main',
|
|
298
|
+
namespace: memoryMode === 'managed' ? `projects/${projectId}` : null,
|
|
299
|
+
},
|
|
300
|
+
namespaces: {
|
|
301
|
+
project: `projects/${projectId}`,
|
|
302
|
+
global: 'global/bizar',
|
|
303
|
+
user: `users/${process.env.USER || process.env.USERNAME || 'local'}`,
|
|
304
|
+
},
|
|
305
|
+
lightrag: {
|
|
306
|
+
enabled: false,
|
|
307
|
+
host: '127.0.0.1',
|
|
308
|
+
port: 9621,
|
|
309
|
+
workingDir: join(cwd, '.bizar', 'lightrag'),
|
|
310
|
+
},
|
|
311
|
+
git: {
|
|
312
|
+
autoPullOnSessionStart: false,
|
|
313
|
+
autoCommitOnMemoryWrite: false,
|
|
314
|
+
autoPushOnSessionEnd: false,
|
|
315
|
+
commitAuthor: 'Bizar Memory <bizar-memory@local>',
|
|
316
|
+
commitMessageTemplate: `memory(${projectId}): {summary}`,
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
atomicWriteJson(memoryJsonPath, config);
|
|
320
|
+
console.log(chalk.green(` ✓ Created ${memoryJsonPath} (mode: ${memoryMode})`));
|
|
321
|
+
if (memoryMode === 'managed') {
|
|
322
|
+
console.log(chalk.dim(` Vault path: ${vaultPath} (shared user-level repo)`));
|
|
323
|
+
} else {
|
|
324
|
+
console.log(chalk.dim(` Vault path: ${vaultPath} (local-only)`));
|
|
325
|
+
}
|
|
326
|
+
} catch (err) {
|
|
327
|
+
// Inquirer prompt can throw if stdin is not a TTY (CI). Fall back to
|
|
328
|
+
// a minimal local-only config so init still completes cleanly.
|
|
329
|
+
console.log(chalk.yellow(` ⚠ Memory config prompt failed (${err.message || err}); defaulting to local-only.`));
|
|
330
|
+
try {
|
|
331
|
+
const projectId = basename(cwd) || 'project';
|
|
332
|
+
const { atomicWriteJson } = await import('./atomic.mjs');
|
|
333
|
+
const fallback = {
|
|
334
|
+
version: 1,
|
|
335
|
+
backend: 'bizar-local',
|
|
336
|
+
projectId,
|
|
337
|
+
memoryRepo: {
|
|
338
|
+
mode: 'local-only',
|
|
339
|
+
path: join(cwd, '.obsidian'),
|
|
340
|
+
remote: null,
|
|
341
|
+
branch: 'main',
|
|
342
|
+
namespace: null,
|
|
343
|
+
},
|
|
344
|
+
namespaces: {
|
|
345
|
+
project: `projects/${projectId}`,
|
|
346
|
+
global: 'global/bizar',
|
|
347
|
+
user: `users/${process.env.USER || process.env.USERNAME || 'local'}`,
|
|
348
|
+
},
|
|
349
|
+
lightrag: { enabled: false, host: '127.0.0.1', port: 9621, workingDir: join(cwd, '.bizar', 'lightrag') },
|
|
350
|
+
git: {
|
|
351
|
+
autoPullOnSessionStart: false,
|
|
352
|
+
autoCommitOnMemoryWrite: false,
|
|
353
|
+
autoPushOnSessionEnd: false,
|
|
354
|
+
commitAuthor: 'Bizar Memory <bizar-memory@local>',
|
|
355
|
+
commitMessageTemplate: `memory(${projectId}): {summary}`,
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
atomicWriteJson(memoryJsonPath, fallback);
|
|
359
|
+
console.log(chalk.green(` ✓ Created ${memoryJsonPath} (mode: local-only — fallback)`));
|
|
360
|
+
} catch (innerErr) {
|
|
361
|
+
console.log(chalk.dim(` - memory config write failed (${innerErr.message || innerErr}); skipping`));
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
232
366
|
console.log(chalk.dim('\n Project initialized. Run `@frigg` to ask questions about the codebase.\n'));
|
|
233
367
|
return true;
|
|
234
368
|
}
|
package/cli/install.mjs
CHANGED
|
@@ -5,8 +5,8 @@ import { join } from 'node:path';
|
|
|
5
5
|
|
|
6
6
|
import { showBanner, showPantheon, sectionHeading } from './banner.mjs';
|
|
7
7
|
import { promptComponents, promptInstallMode, promptAgents, promptSkillPacks, promptApiKeys, promptConfirmInstall, promptRestartOpenCode } from './prompts.mjs';
|
|
8
|
-
import { detectOpenCode,
|
|
9
|
-
import { installAgents, installAgentsMd, installSkill, installOpencodeJson, installBizarFolder, installPluginBizar,
|
|
8
|
+
import { detectOpenCode, detectHeadroom, detectSemble, detectSkillsCli, detectUv, buildSummary, opencodeAgentsDir, opencodeConfigDir, repoPath } from './utils.mjs';
|
|
9
|
+
import { installAgents, installAgentsMd, installSkill, installOpencodeJson, installBizarFolder, installPluginBizar, installHeadroom, installSemble, installSkillsCli, installCuratedSkills, installRules, installHooks, installCommands, installCommandsBizar, mergeToolsIntoUserConfig } from './copy.mjs';
|
|
10
10
|
|
|
11
11
|
const AGENT_FILES = [
|
|
12
12
|
'odin.md', 'vor.md', 'frigg.md', 'quick.md',
|
|
@@ -327,30 +327,17 @@ async function promptAndInstallOptional() {
|
|
|
327
327
|
console.log(' ✓ @polderlabs/bizar-plugin already installed');
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
// Dashboard
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
console.
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
);
|
|
340
|
-
if (install) {
|
|
341
|
-
try {
|
|
342
|
-
console.log(' Installing @polderlabs/bizar-dash...');
|
|
343
|
-
execSync('npm install -g @polderlabs/bizar-dash', { stdio: 'inherit' });
|
|
344
|
-
console.log(' ✓ @polderlabs/bizar-dash installed');
|
|
345
|
-
} catch (err) {
|
|
346
|
-
console.log(` ✗ Failed to install @polderlabs/bizar-dash: ${err.message}`);
|
|
347
|
-
console.log(' You can install it later with: npm install -g @polderlabs/bizar-dash');
|
|
348
|
-
}
|
|
349
|
-
} else {
|
|
350
|
-
console.log(' Skipped. Install later with: npm install -g @polderlabs/bizar-dash');
|
|
351
|
-
}
|
|
330
|
+
// Dashboard — v4.0.0: ships inside this package at <repo>/bizar-dash/
|
|
331
|
+
// Verify the directory is present; it's a corrupted install if missing.
|
|
332
|
+
const dashDir = join(__dirname, '..', 'bizar-dash');
|
|
333
|
+
const dashPkgJson = join(dashDir, 'package.json');
|
|
334
|
+
if (!existsSync(dashPkgJson)) {
|
|
335
|
+
console.error('');
|
|
336
|
+
console.error(' ✗ Dashboard directory not found at bizar-dash/.');
|
|
337
|
+
console.error(' This looks like a corrupted install.');
|
|
338
|
+
console.error(' Please report at: github.com/DrB0rk/BizarHarness/issues');
|
|
352
339
|
} else {
|
|
353
|
-
console.log(' ✓
|
|
340
|
+
console.log(' ✓ Dashboard directory present (bizar-dash/)');
|
|
354
341
|
}
|
|
355
342
|
}
|
|
356
343
|
|
|
@@ -567,32 +554,37 @@ export async function runPostInstall() {
|
|
|
567
554
|
}
|
|
568
555
|
console.log('BizarHarness: agents installed.');
|
|
569
556
|
|
|
570
|
-
// Install
|
|
571
|
-
const
|
|
572
|
-
if (!
|
|
573
|
-
console.log('BizarHarness: installing
|
|
557
|
+
// Install Headroom
|
|
558
|
+
const headroomPresent = await detectHeadroom();
|
|
559
|
+
if (!headroomPresent) {
|
|
560
|
+
console.log('BizarHarness: installing Headroom (context compressor)...');
|
|
574
561
|
try {
|
|
575
562
|
if (process.platform === 'win32') {
|
|
576
|
-
|
|
577
|
-
// manually (e.g. `cargo install --git https://github.com/rtk-ai/rtk`).
|
|
578
|
-
console.log('BizarHarness: RTK bash installer does not run on Windows. Install manually from https://github.com/rtk-ai/rtk');
|
|
563
|
+
console.log('BizarHarness: Automatic Headroom install not supported on Windows. Install manually: pip install "headroom-ai[all]"');
|
|
579
564
|
} else {
|
|
580
565
|
execSync(
|
|
581
|
-
'
|
|
566
|
+
'pip install --user "headroom-ai[all]"',
|
|
582
567
|
{ stdio: 'pipe', timeout: 60000 },
|
|
583
568
|
);
|
|
584
|
-
execSync('
|
|
585
|
-
console.log('BizarHarness:
|
|
569
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
570
|
+
console.log('BizarHarness: Headroom installed and configured.');
|
|
586
571
|
}
|
|
587
572
|
} catch {
|
|
588
|
-
|
|
573
|
+
// Fall back to npm
|
|
574
|
+
try {
|
|
575
|
+
execSync('npm install -g headroom-ai', { stdio: 'pipe', timeout: 60000 });
|
|
576
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
577
|
+
console.log('BizarHarness: Headroom installed (npm) and configured.');
|
|
578
|
+
} catch {
|
|
579
|
+
console.log('BizarHarness: Headroom install failed. Install manually: pip install "headroom-ai[all]" or npm install -g headroom-ai');
|
|
580
|
+
}
|
|
589
581
|
}
|
|
590
582
|
} else {
|
|
591
583
|
try {
|
|
592
|
-
execSync('
|
|
593
|
-
console.log('BizarHarness:
|
|
584
|
+
execSync('headroom wrap opencode', { stdio: 'pipe' });
|
|
585
|
+
console.log('BizarHarness: Headroom configured for opencode.');
|
|
594
586
|
} catch {
|
|
595
|
-
console.log('BizarHarness: could not configure
|
|
587
|
+
console.log('BizarHarness: could not configure Headroom. Run `headroom wrap opencode` manually.');
|
|
596
588
|
}
|
|
597
589
|
}
|
|
598
590
|
|