@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
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/server/schedules-store.mjs
|
|
3
|
+
*
|
|
4
|
+
* v3.9.0 — Schedules registry.
|
|
5
|
+
*
|
|
6
|
+
* Each project has its own schedules.json at
|
|
7
|
+
* ~/.config/opencode/projects/<id>/schedules.json
|
|
8
|
+
*
|
|
9
|
+
* A schedule is a recurring task: { name, type, schedule, action, enabled, ... }.
|
|
10
|
+
* Supported types:
|
|
11
|
+
* - interval ("30m", "2h", "1d")
|
|
12
|
+
* - cron ("0 0 * * *") — full cron via the `croner` package, with
|
|
13
|
+
* optional IANA `timezone` (default "UTC")
|
|
14
|
+
* - once (ISO timestamp)
|
|
15
|
+
*
|
|
16
|
+
* The dashboard reads / writes schedules here. The bizar service daemon
|
|
17
|
+
* (cli/service.mjs) calls evaluateAndRun() on a tick to fire due actions.
|
|
18
|
+
*
|
|
19
|
+
* v3.9.0 changes vs v3.x:
|
|
20
|
+
* - Cron parsing is now delegated to `croner` (proper 5-field + 6-field
|
|
21
|
+
* + IANA TZ support). The old hand-rolled `nextCronMinute` walker is
|
|
22
|
+
* gone.
|
|
23
|
+
* - New Schedule fields: `timezone`, `budgetCheck`, `action.prompt`.
|
|
24
|
+
*/
|
|
25
|
+
import {
|
|
26
|
+
existsSync,
|
|
27
|
+
readFileSync,
|
|
28
|
+
writeFileSync,
|
|
29
|
+
renameSync,
|
|
30
|
+
mkdirSync,
|
|
31
|
+
} from 'node:fs';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
import { randomBytes } from 'node:crypto';
|
|
34
|
+
import { Cron } from 'croner';
|
|
35
|
+
import { projectsStore } from './projects-store.mjs';
|
|
36
|
+
|
|
37
|
+
function safeReadJSON(file, fallback = null) {
|
|
38
|
+
try {
|
|
39
|
+
if (!existsSync(file)) return fallback;
|
|
40
|
+
const text = readFileSync(file, 'utf8');
|
|
41
|
+
if (!text.trim()) return fallback;
|
|
42
|
+
return JSON.parse(text);
|
|
43
|
+
} catch {
|
|
44
|
+
return fallback;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function genId() {
|
|
49
|
+
return 'sched_' + randomBytes(5).toString('hex').slice(0, 10);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Parse "30m" / "2h" / "1d" / "45s" → milliseconds. */
|
|
53
|
+
export function parseInterval(s) {
|
|
54
|
+
if (typeof s !== 'string') return null;
|
|
55
|
+
const m = /^(\d+)\s*(s|sec|second|m|min|minute|h|hr|hour|d|day)$/i.exec(s.trim());
|
|
56
|
+
if (!m) return null;
|
|
57
|
+
const n = parseInt(m[1], 10);
|
|
58
|
+
const unit = m[2].toLowerCase();
|
|
59
|
+
if (unit.startsWith('s')) return n * 1000;
|
|
60
|
+
if (unit.startsWith('m')) return n * 60 * 1000;
|
|
61
|
+
if (unit.startsWith('h')) return n * 60 * 60 * 1000;
|
|
62
|
+
if (unit.startsWith('d')) return n * 24 * 60 * 60 * 1000;
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Compute the next firing time for a schedule. Returns ISO string or null. */
|
|
67
|
+
export function computeNextRun(schedule, fromMs = Date.now()) {
|
|
68
|
+
const type = schedule.type;
|
|
69
|
+
if (type === 'interval') {
|
|
70
|
+
const ms = parseInterval(schedule.schedule);
|
|
71
|
+
if (!ms) return null;
|
|
72
|
+
const last = schedule.lastRun ? new Date(schedule.lastRun).getTime() : fromMs;
|
|
73
|
+
return new Date(last + ms).toISOString();
|
|
74
|
+
}
|
|
75
|
+
if (type === 'once') {
|
|
76
|
+
if (schedule.lastRun) return null; // already fired
|
|
77
|
+
const when = new Date(schedule.schedule).getTime();
|
|
78
|
+
if (Number.isNaN(when)) return null;
|
|
79
|
+
return new Date(Math.max(when, fromMs)).toISOString();
|
|
80
|
+
}
|
|
81
|
+
if (type === 'cron') {
|
|
82
|
+
if (typeof schedule.schedule !== 'string' || !schedule.schedule.trim()) return null;
|
|
83
|
+
try {
|
|
84
|
+
const tz = schedule.timezone || 'UTC';
|
|
85
|
+
// croner takes IANA tz names ("America/New_York", "Europe/Berlin",
|
|
86
|
+
// "UTC", etc.) and falls back to the system zone on invalid input.
|
|
87
|
+
const job = new Cron(schedule.schedule, { timezone: tz });
|
|
88
|
+
const next = job.nextRun(new Date(fromMs));
|
|
89
|
+
return next ? next.toISOString() : null;
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function loadSchedules(projectId) {
|
|
98
|
+
const dir = projectsStore.ensureProjectDir(projectId);
|
|
99
|
+
const file = join(dir, 'schedules.json');
|
|
100
|
+
const data = safeReadJSON(file, null);
|
|
101
|
+
if (!data || !Array.isArray(data.schedules)) {
|
|
102
|
+
return { version: 1, schedules: [] };
|
|
103
|
+
}
|
|
104
|
+
return data;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function atomicWriteJson(filePath, data) {
|
|
108
|
+
const tmp = `${filePath}.tmp.${process.pid}`;
|
|
109
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
110
|
+
renameSync(tmp, filePath);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function saveSchedules(projectId, data) {
|
|
114
|
+
const dir = projectsStore.ensureProjectDir(projectId);
|
|
115
|
+
atomicWriteJson(join(dir, 'schedules.json'), data);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const schedulesStore = {
|
|
119
|
+
list(projectId) {
|
|
120
|
+
return loadSchedules(projectId).schedules;
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
get(projectId, id) {
|
|
124
|
+
return this.list(projectId).find((s) => s.id === id) || null;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
add(projectId, input) {
|
|
128
|
+
if (!input || typeof input !== 'object') {
|
|
129
|
+
throw new Error('schedule payload required');
|
|
130
|
+
}
|
|
131
|
+
if (!input.name) throw new Error('name is required');
|
|
132
|
+
if (!['interval', 'cron', 'once'].includes(input.type)) {
|
|
133
|
+
throw new Error('type must be interval | cron | once');
|
|
134
|
+
}
|
|
135
|
+
if (!input.schedule) throw new Error('schedule is required');
|
|
136
|
+
if (!input.action || typeof input.action !== 'object') {
|
|
137
|
+
throw new Error('action is required');
|
|
138
|
+
}
|
|
139
|
+
const data = loadSchedules(projectId);
|
|
140
|
+
const now = new Date().toISOString();
|
|
141
|
+
const sched = {
|
|
142
|
+
id: genId(),
|
|
143
|
+
name: input.name,
|
|
144
|
+
type: input.type,
|
|
145
|
+
schedule: input.schedule,
|
|
146
|
+
timezone: typeof input.timezone === 'string' && input.timezone.trim()
|
|
147
|
+
? input.timezone.trim()
|
|
148
|
+
: 'UTC',
|
|
149
|
+
action: input.action,
|
|
150
|
+
budgetCheck: input.budgetCheck && typeof input.budgetCheck === 'object'
|
|
151
|
+
? {
|
|
152
|
+
maxConcurrent: Number.isFinite(input.budgetCheck.maxConcurrent)
|
|
153
|
+
? input.budgetCheck.maxConcurrent
|
|
154
|
+
: 6,
|
|
155
|
+
skipIfBudgetLow: !!input.budgetCheck.skipIfBudgetLow,
|
|
156
|
+
}
|
|
157
|
+
: { maxConcurrent: 6, skipIfBudgetLow: false },
|
|
158
|
+
enabled: input.enabled !== false,
|
|
159
|
+
createdAt: now,
|
|
160
|
+
updatedAt: now,
|
|
161
|
+
lastRun: null,
|
|
162
|
+
lastResult: null,
|
|
163
|
+
lastError: null,
|
|
164
|
+
nextRun: computeNextRun({
|
|
165
|
+
type: input.type,
|
|
166
|
+
schedule: input.schedule,
|
|
167
|
+
timezone: input.timezone || 'UTC',
|
|
168
|
+
}),
|
|
169
|
+
history: [],
|
|
170
|
+
};
|
|
171
|
+
data.schedules.push(sched);
|
|
172
|
+
saveSchedules(projectId, data);
|
|
173
|
+
return sched;
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
update(projectId, id, patch) {
|
|
177
|
+
const data = loadSchedules(projectId);
|
|
178
|
+
const idx = data.schedules.findIndex((s) => s.id === id);
|
|
179
|
+
if (idx === -1) return null;
|
|
180
|
+
const cur = data.schedules[idx];
|
|
181
|
+
const next = {
|
|
182
|
+
...cur,
|
|
183
|
+
...patch,
|
|
184
|
+
id: cur.id,
|
|
185
|
+
updatedAt: new Date().toISOString(),
|
|
186
|
+
};
|
|
187
|
+
// Sanitize nested budgetCheck so callers can't smuggle in extra keys
|
|
188
|
+
// (matches the shape validation in `add`).
|
|
189
|
+
if (patch && Object.prototype.hasOwnProperty.call(patch, 'budgetCheck')) {
|
|
190
|
+
const bc = patch.budgetCheck && typeof patch.budgetCheck === 'object'
|
|
191
|
+
? patch.budgetCheck
|
|
192
|
+
: {};
|
|
193
|
+
next.budgetCheck = {
|
|
194
|
+
maxConcurrent: Number.isFinite(bc.maxConcurrent) ? bc.maxConcurrent : 6,
|
|
195
|
+
skipIfBudgetLow: !!bc.skipIfBudgetLow,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (patch && Object.prototype.hasOwnProperty.call(patch, 'timezone')) {
|
|
199
|
+
next.timezone = typeof patch.timezone === 'string' && patch.timezone.trim()
|
|
200
|
+
? patch.timezone.trim()
|
|
201
|
+
: 'UTC';
|
|
202
|
+
}
|
|
203
|
+
if (patch && Object.prototype.hasOwnProperty.call(patch, 'action') && patch.action) {
|
|
204
|
+
// Preserve the existing action shape; only the listed keys are merged.
|
|
205
|
+
next.action = {
|
|
206
|
+
type: patch.action.type || cur.action.type,
|
|
207
|
+
target: patch.action.target ?? cur.action.target,
|
|
208
|
+
prompt: patch.action.prompt ?? cur.action.prompt,
|
|
209
|
+
method: patch.action.method ?? cur.action.method,
|
|
210
|
+
body: patch.action.body ?? cur.action.body,
|
|
211
|
+
title: patch.action.title ?? cur.action.title,
|
|
212
|
+
name: patch.action.name ?? cur.action.name,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (patch.type || patch.schedule || patch.timezone) {
|
|
216
|
+
next.nextRun = computeNextRun({
|
|
217
|
+
type: next.type,
|
|
218
|
+
schedule: next.schedule,
|
|
219
|
+
timezone: next.timezone || 'UTC',
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
data.schedules[idx] = next;
|
|
223
|
+
saveSchedules(projectId, data);
|
|
224
|
+
return next;
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
remove(projectId, id) {
|
|
228
|
+
const data = loadSchedules(projectId);
|
|
229
|
+
const before = data.schedules.length;
|
|
230
|
+
data.schedules = data.schedules.filter((s) => s.id !== id);
|
|
231
|
+
if (data.schedules.length === before) return false;
|
|
232
|
+
saveSchedules(projectId, data);
|
|
233
|
+
return true;
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
/** Record the result of a run. */
|
|
237
|
+
recordRun(projectId, id, { result, error }) {
|
|
238
|
+
const data = loadSchedules(projectId);
|
|
239
|
+
const sched = data.schedules.find((s) => s.id === id);
|
|
240
|
+
if (!sched) return null;
|
|
241
|
+
const now = new Date().toISOString();
|
|
242
|
+
sched.lastRun = now;
|
|
243
|
+
// `result` is one of: 'success' | 'error' | 'skipped'. Pass through
|
|
244
|
+
// whatever the runner reports — null is also legal for backwards
|
|
245
|
+
// compat with old callers, but the new runner always passes a value.
|
|
246
|
+
sched.lastResult = result || null;
|
|
247
|
+
sched.lastError = error || null;
|
|
248
|
+
if (sched.type === 'once') {
|
|
249
|
+
sched.enabled = false;
|
|
250
|
+
} else {
|
|
251
|
+
sched.nextRun = computeNextRun(sched, Date.now());
|
|
252
|
+
}
|
|
253
|
+
sched.history = sched.history || [];
|
|
254
|
+
sched.history.push({ ts: now, result: result || 'unknown', error: error || null });
|
|
255
|
+
if (sched.history.length > 50) sched.history = sched.history.slice(-50);
|
|
256
|
+
saveSchedules(projectId, data);
|
|
257
|
+
return sched;
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/** Return all schedules for the project that are currently due. */
|
|
261
|
+
due(projectId, now = Date.now()) {
|
|
262
|
+
return this.list(projectId).filter((s) => {
|
|
263
|
+
if (!s.enabled) return false;
|
|
264
|
+
if (!s.nextRun) return false;
|
|
265
|
+
return new Date(s.nextRun).getTime() <= now;
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/server/search-store.mjs
|
|
3
|
+
*
|
|
4
|
+
* v3.0.0 — Fuzzy search across projects, tasks, plans, agents, mods,
|
|
5
|
+
* commands.
|
|
6
|
+
*
|
|
7
|
+
* v3.0.4 — Added `settings` scope. Reads ~/.config/bizar/settings.json
|
|
8
|
+
* and surfaces each leaf as a searchable entry. Setting descriptions
|
|
9
|
+
* come from SETTINGS_DESCRIPTIONS so users can find them by typing
|
|
10
|
+
* "theme", "accent", "layout", etc.
|
|
11
|
+
*
|
|
12
|
+
* Uses a simple substring / token match for v3. fuse.js is wired in for
|
|
13
|
+
* fuzzy ranking but we keep a simple default that works without deps.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { agentsStore } from './agents-store.mjs';
|
|
19
|
+
import { projectsStore } from './projects-store.mjs';
|
|
20
|
+
import { tasksStore } from './tasks-store.mjs';
|
|
21
|
+
import { modsLoader } from './mods-loader.mjs';
|
|
22
|
+
import { schedulesStore } from './schedules-store.mjs';
|
|
23
|
+
|
|
24
|
+
const HOME = homedir();
|
|
25
|
+
const SETTINGS_FILE = join(HOME, '.config', 'bizar', 'settings.json');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* v3.0.4 — Human-friendly descriptions for each known setting key.
|
|
29
|
+
* The `path` in the result is what we attach to the search-result item
|
|
30
|
+
* so the frontend can scroll-and-flash the right row.
|
|
31
|
+
*/
|
|
32
|
+
const SETTINGS_DESCRIPTIONS = {
|
|
33
|
+
'theme.mode': 'Dark or light theme (dark, light, system)',
|
|
34
|
+
'theme.accent': 'Accent color for highlights',
|
|
35
|
+
'theme.success': 'Color used for success indicators',
|
|
36
|
+
'theme.warning': 'Color used for warning indicators',
|
|
37
|
+
'theme.error': 'Color used for error indicators',
|
|
38
|
+
'theme.info': 'Color used for info indicators',
|
|
39
|
+
'theme.fontFamily': 'Font family (Inter, system, mono)',
|
|
40
|
+
'theme.fontSize': 'Base font size in pixels',
|
|
41
|
+
'theme.compactMode': 'Denser UI with smaller spacing',
|
|
42
|
+
'theme.animations': 'Enable UI animations and transitions',
|
|
43
|
+
'ui.layout': 'Layout style (topnav, sidebar, both)',
|
|
44
|
+
'ui.showHeader': 'Show the top header bar',
|
|
45
|
+
'ui.showStatusBar': 'Show the status bar at the bottom',
|
|
46
|
+
'ui.defaultTab': 'Tab to open on launch',
|
|
47
|
+
'defaultAgent': 'Default agent used in chat and tasks',
|
|
48
|
+
'defaultModel': 'Default model override (empty = provider default)',
|
|
49
|
+
'notifications.onAgentComplete': 'Toast when an agent invocation completes',
|
|
50
|
+
'notifications.onPlanApproval': 'Toast when a plan needs approval',
|
|
51
|
+
'dashboard.autoLaunchWeb': 'Auto-launch web UI when starting TUI',
|
|
52
|
+
'service.enabled': 'Enable background service daemon',
|
|
53
|
+
'service.autostart': 'Start the service daemon at login',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function flattenSettings(obj, prefix = '', out = []) {
|
|
57
|
+
if (!obj || typeof obj !== 'object') return out;
|
|
58
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
59
|
+
const path = prefix ? `${prefix}.${k}` : k;
|
|
60
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
61
|
+
flattenSettings(v, path, out);
|
|
62
|
+
} else {
|
|
63
|
+
out.push({ id: path, value: v });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readSettings() {
|
|
70
|
+
try {
|
|
71
|
+
if (!existsSync(SETTINGS_FILE)) return null;
|
|
72
|
+
const raw = readFileSync(SETTINGS_FILE, 'utf8');
|
|
73
|
+
if (!raw.trim()) return null;
|
|
74
|
+
return JSON.parse(raw);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function scoreItem(item, fields, query) {
|
|
81
|
+
if (!query) return 0;
|
|
82
|
+
const q = query.toLowerCase();
|
|
83
|
+
let best = 0;
|
|
84
|
+
for (const f of fields) {
|
|
85
|
+
const v = item[f];
|
|
86
|
+
if (typeof v !== 'string') continue;
|
|
87
|
+
const idx = v.toLowerCase().indexOf(q);
|
|
88
|
+
if (idx === -1) continue;
|
|
89
|
+
// earlier matches score higher
|
|
90
|
+
const s = 100 - Math.min(idx, 99);
|
|
91
|
+
if (s > best) best = s;
|
|
92
|
+
}
|
|
93
|
+
return best;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function findPlans(planDirs) {
|
|
97
|
+
// Quick local scan — the dashboard state already lists plans, but we
|
|
98
|
+
// re-discover from the active project's plans/ dir for a self-contained
|
|
99
|
+
// search.
|
|
100
|
+
const out = [];
|
|
101
|
+
// We don't have a project plan dir in v3 search — leave it empty.
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const searchStore = {
|
|
106
|
+
search(query, { activeProjectId, scope = 'all' } = {}) {
|
|
107
|
+
const q = (query || '').trim();
|
|
108
|
+
if (!q) return { query, results: [] };
|
|
109
|
+
const results = [];
|
|
110
|
+
|
|
111
|
+
if (scope === 'all' || scope === 'projects') {
|
|
112
|
+
const reg = projectsStore.list();
|
|
113
|
+
for (const p of reg.projects) {
|
|
114
|
+
const s = scoreItem(p, ['name', 'path', 'summary'], q);
|
|
115
|
+
if (s > 0) results.push({ type: 'project', score: s, item: p });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (scope === 'all' || scope === 'agents') {
|
|
120
|
+
for (const a of agentsStore.list()) {
|
|
121
|
+
const s = scoreItem(a, ['name', 'description', 'model', 'mode'], q);
|
|
122
|
+
if (s > 0) results.push({ type: 'agent', score: s, item: a });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (scope === 'all' || scope === 'tasks') {
|
|
127
|
+
const tasks = activeProjectId
|
|
128
|
+
? tasksStore.loadTasks(activeProjectId)
|
|
129
|
+
: [];
|
|
130
|
+
for (const t of tasks) {
|
|
131
|
+
const tags = (t.tags || []).join(' ');
|
|
132
|
+
const s = scoreItem(
|
|
133
|
+
{ title: t.title || '', description: t.description || '', tags },
|
|
134
|
+
['title', 'description', 'tags'],
|
|
135
|
+
q,
|
|
136
|
+
);
|
|
137
|
+
if (s > 0) results.push({ type: 'task', score: s, item: t });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (scope === 'all' || scope === 'mods') {
|
|
142
|
+
for (const m of modsLoader.list()) {
|
|
143
|
+
const s = scoreItem(
|
|
144
|
+
{ name: m.name || '', description: m.description || '', author: m.author || '' },
|
|
145
|
+
['name', 'description', 'author'],
|
|
146
|
+
q,
|
|
147
|
+
);
|
|
148
|
+
if (s > 0) results.push({ type: 'mod', score: s, item: m });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (scope === 'all' || scope === 'schedules') {
|
|
153
|
+
const list = activeProjectId
|
|
154
|
+
? schedulesStore.list(activeProjectId)
|
|
155
|
+
: [];
|
|
156
|
+
for (const sc of list) {
|
|
157
|
+
const s = scoreItem(sc, ['name', 'schedule'], q);
|
|
158
|
+
if (s > 0) results.push({ type: 'schedule', score: s, item: sc });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (scope === 'all' || scope === 'commands') {
|
|
163
|
+
// Built-in slash commands + a placeholder for the user's
|
|
164
|
+
// commands-bizar folder.
|
|
165
|
+
const builtin = [
|
|
166
|
+
{ name: 'plan', description: 'Manage visual plans' },
|
|
167
|
+
{ name: 'audit', description: 'Run security audit' },
|
|
168
|
+
{ name: 'init', description: 'Initialize .bizar/ in this project' },
|
|
169
|
+
{ name: 'update', description: 'Update bizar + plugin' },
|
|
170
|
+
{ name: 'export', description: 'Export to another harness' },
|
|
171
|
+
{ name: 'service', description: 'Manage the service daemon' },
|
|
172
|
+
{ name: 'explain', description: 'Read-only code Q&A' },
|
|
173
|
+
{ name: 'pr-review', description: 'PR review with @mimir + @forseti' },
|
|
174
|
+
];
|
|
175
|
+
for (const c of builtin) {
|
|
176
|
+
const s = scoreItem(c, ['name', 'description'], q);
|
|
177
|
+
if (s > 0) results.push({ type: 'command', score: s, item: c });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (scope === 'all' || scope === 'settings') {
|
|
182
|
+
// v3.0.4 — Surface each setting as a result. Score against the
|
|
183
|
+
// full dot-path, the human description, and the current value
|
|
184
|
+
// (stringified) so users can find e.g. "dark" or "Inter" too.
|
|
185
|
+
const settings = readSettings();
|
|
186
|
+
if (settings) {
|
|
187
|
+
const flat = flattenSettings(settings);
|
|
188
|
+
for (const s of flat) {
|
|
189
|
+
const desc = SETTINGS_DESCRIPTIONS[s.id] || '';
|
|
190
|
+
const valStr = s.value === null || s.value === undefined
|
|
191
|
+
? ''
|
|
192
|
+
: typeof s.value === 'string'
|
|
193
|
+
? s.value
|
|
194
|
+
: JSON.stringify(s.value);
|
|
195
|
+
// Score against id (path) first, then description, then value.
|
|
196
|
+
let best = 0;
|
|
197
|
+
best = Math.max(best, scoreItem({ id: s.id }, ['id'], q));
|
|
198
|
+
if (desc) best = Math.max(best, scoreItem({ desc }, ['desc'], q));
|
|
199
|
+
if (valStr) best = Math.max(best, scoreItem({ val: valStr }, ['val'], q));
|
|
200
|
+
if (best > 0) {
|
|
201
|
+
results.push({
|
|
202
|
+
type: 'setting',
|
|
203
|
+
score: best,
|
|
204
|
+
item: {
|
|
205
|
+
id: s.id,
|
|
206
|
+
path: s.id,
|
|
207
|
+
label: s.id,
|
|
208
|
+
desc,
|
|
209
|
+
value: s.value,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
results.sort((a, b) => b.score - a.score);
|
|
218
|
+
return { query, results: results.slice(0, 50) };
|
|
219
|
+
},
|
|
220
|
+
};
|