mixdog 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +31 -0
- package/.claude-plugin/plugin.json +20 -0
- package/.gitattributes +34 -0
- package/.mcp.json +14 -0
- package/ARCHITECTURE.md +77 -0
- package/CHANGELOG.md +7 -0
- package/CONTRIBUTING.md +45 -0
- package/DATA-FLOW.md +79 -0
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/SECURITY.md +138 -0
- package/UNINSTALL.md +112 -0
- package/agents/maintenance.md +5 -0
- package/agents/memory-classification.md +30 -0
- package/agents/scheduler-task.md +18 -0
- package/agents/webhook-handler.md +27 -0
- package/agents/worker.md +24 -0
- package/bin/bridge +133 -0
- package/bin/statusline-launcher.mjs +78 -0
- package/bin/statusline-lib.mjs +550 -0
- package/bin/statusline.mjs +607 -0
- package/bun.lock +802 -0
- package/commands/config.md +16 -0
- package/commands/doctor.md +13 -0
- package/commands/setup.md +17 -0
- package/defaults/cycle3-review-prompt.md +90 -0
- package/defaults/hidden-roles.json +65 -0
- package/defaults/memory-chunk-prompt.md +63 -0
- package/defaults/memory-promote-prompt.md +135 -0
- package/defaults/mixdog-config.template.json +27 -0
- package/defaults/user-workflow.json +8 -0
- package/defaults/user-workflow.md +12 -0
- package/hooks/hooks.json +73 -0
- package/hooks/lib/active-instance.cjs +77 -0
- package/hooks/lib/permission-evaluator.cjs +411 -0
- package/hooks/lib/permission-route.cjs +63 -0
- package/hooks/lib/permission-rules.cjs +170 -0
- package/hooks/lib/settings-loader.cjs +116 -0
- package/hooks/post-tool-use.cjs +84 -0
- package/hooks/pre-mcp-sandbox.cjs +158 -0
- package/hooks/pre-tool-subagent.cjs +253 -0
- package/hooks/session-start.cjs +1372 -0
- package/hooks/turn-timer.cjs +82 -0
- package/lib/claude-md-writer.cjs +386 -0
- package/lib/config-cjs.cjs +61 -0
- package/lib/hook-pipe-path.cjs +10 -0
- package/lib/keychain-cjs.cjs +263 -0
- package/lib/plugin-paths.cjs +61 -0
- package/lib/rules-builder.cjs +241 -0
- package/lib/text-utils.cjs +61 -0
- package/native/README.md +117 -0
- package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
- package/package.json +107 -0
- package/prompts/code-review.txt +16 -0
- package/prompts/security-audit.txt +17 -0
- package/rules/bridge/00-common.md +39 -0
- package/rules/bridge/20-skip-protocol.md +18 -0
- package/rules/bridge/30-explorer.md +33 -0
- package/rules/bridge/40-cycle1-agent.md +52 -0
- package/rules/bridge/41-cycle2-agent.md +62 -0
- package/rules/bridge/42-cycle3-agent.md +44 -0
- package/rules/lead/00-tool-lead.md +61 -0
- package/rules/lead/01-general.md +23 -0
- package/rules/lead/02-channels.md +49 -0
- package/rules/lead/03-team.md +27 -0
- package/rules/lead/04-workflow.md +20 -0
- package/rules/shared/00-language.md +14 -0
- package/rules/shared/01-tool.md +138 -0
- package/scripts/bootstrap.mjs +184 -0
- package/scripts/bridge-unify-smoke.mjs +308 -0
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/builtin-utils-smoke.mjs +392 -0
- package/scripts/check-json.mjs +45 -0
- package/scripts/check-syntax-changed.mjs +102 -0
- package/scripts/check-syntax.mjs +58 -0
- package/scripts/code-graph-batch.test.mjs +33 -0
- package/scripts/config-preserve-smoke.mjs +180 -0
- package/scripts/doctor.mjs +484 -0
- package/scripts/edit-normalize-fuzz.mjs +130 -0
- package/scripts/edit-normalize-smoke.mjs +401 -0
- package/scripts/edit-operation-smoke.mjs +369 -0
- package/scripts/edit2-smoke.mjs +63 -0
- package/scripts/fuzzy-e2e.mjs +28 -0
- package/scripts/fuzzy-smoke.mjs +26 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/guard-smoke.mjs +66 -0
- package/scripts/hidden-role-schema-smoke.mjs +162 -0
- package/scripts/hook-routing-smoke.mjs +29 -0
- package/scripts/inject-input.ps1 +204 -0
- package/scripts/io-complex-smoke.mjs +667 -0
- package/scripts/io-explore-bench.mjs +424 -0
- package/scripts/io-guardrails-smoke.mjs +205 -0
- package/scripts/io-mini-bench-baseline.json +11 -0
- package/scripts/io-mini-bench.mjs +216 -0
- package/scripts/io-route-harness.mjs +933 -0
- package/scripts/io-telemetry-report.mjs +691 -0
- package/scripts/mutation-bench.mjs +564 -0
- package/scripts/mutation-io-smoke.mjs +1081 -0
- package/scripts/native-patch-bridge-smoke.mjs +288 -0
- package/scripts/native-patch-smoke.mjs +304 -0
- package/scripts/patch-interior-context-smoke.mjs +49 -0
- package/scripts/patch-newline-utf8-smoke.mjs +157 -0
- package/scripts/perf-hook-smoke.mjs +71 -0
- package/scripts/permission-eval-smoke.mjs +426 -0
- package/scripts/prep-patch.mjs +53 -0
- package/scripts/prep-shim.mjs +96 -0
- package/scripts/provider-cache-smoke.mjs +687 -0
- package/scripts/report-runtime-health.mjs +132 -0
- package/scripts/run-mcp.mjs +1547 -0
- package/scripts/salvage-v4a-shatter.test.mjs +58 -0
- package/scripts/scoped-cache-io-smoke.mjs +103 -0
- package/scripts/shell-policy-round3-smoke.mjs +46 -0
- package/scripts/smoke-runtime-negative.ps1 +100 -0
- package/scripts/smoke-runtime-negative.sh +95 -0
- package/scripts/stall-policy-smoke.mjs +50 -0
- package/scripts/start-memory-worker.mjs +23 -0
- package/scripts/statusline-launcher-smoke.mjs +82 -0
- package/scripts/stress-atomic-write.mjs +1028 -0
- package/scripts/test-config-rmw-restore.mjs +122 -0
- package/scripts/test-fault-inject.mjs +164 -0
- package/scripts/test-large-file.mjs +174 -0
- package/scripts/tool-edge-smoke.mjs +209 -0
- package/scripts/uninstall.mjs +201 -0
- package/scripts/webhook-selfheal-smoke.mjs +29 -0
- package/scripts/write-overwrite-guard-smoke.mjs +56 -0
- package/server-main.mjs +3055 -0
- package/server.mjs +468 -0
- package/setup/config-merge.mjs +254 -0
- package/setup/install.mjs +120 -0
- package/setup/launch-core.mjs +507 -0
- package/setup/launch.mjs +101 -0
- package/setup/setup-server.mjs +3206 -0
- package/setup/setup.html +3693 -0
- package/skills/retro-skill-proposer/SKILL.md +92 -0
- package/skills/schedule-add/SKILL.md +77 -0
- package/skills/setup/SKILL.md +346 -0
- package/skills/webhook-add/SKILL.md +81 -0
- package/src/agent/bridge-stall-watchdog.mjs +337 -0
- package/src/agent/index.mjs +2138 -0
- package/src/agent/orchestrator/activity-bus.mjs +38 -0
- package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
- package/src/agent/orchestrator/bridge-retry.mjs +220 -0
- package/src/agent/orchestrator/bridge-trace.mjs +583 -0
- package/src/agent/orchestrator/cache-mtime.mjs +58 -0
- package/src/agent/orchestrator/config.mjs +358 -0
- package/src/agent/orchestrator/context/collect.mjs +651 -0
- package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
- package/src/agent/orchestrator/drain-registry.mjs +50 -0
- package/src/agent/orchestrator/explore-validator.mjs +8 -0
- package/src/agent/orchestrator/internal-roles.mjs +118 -0
- package/src/agent/orchestrator/internal-tools.mjs +88 -0
- package/src/agent/orchestrator/jobs.mjs +116 -0
- package/src/agent/orchestrator/mcp/client.mjs +364 -0
- package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
- package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
- package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
- package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
- package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
- package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
- package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
- package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
- package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
- package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
- package/src/agent/orchestrator/providers/registry.mjs +192 -0
- package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
- package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
- package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
- package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
- package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
- package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
- package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
- package/src/agent/orchestrator/session/cache/util.mjs +49 -0
- package/src/agent/orchestrator/session/loop.mjs +1478 -0
- package/src/agent/orchestrator/session/manager.mjs +1975 -0
- package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
- package/src/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
- package/src/agent/orchestrator/session/store.mjs +624 -0
- package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
- package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
- package/src/agent/orchestrator/session/trim.mjs +491 -0
- package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
- package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
- package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
- package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
- package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
- package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
- package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
- package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
- package/src/agent/orchestrator/stall-policy.mjs +195 -0
- package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
- package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
- package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
- package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
- package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
- package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
- package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
- package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
- package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
- package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
- package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
- package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
- package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
- package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
- package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
- package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
- package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
- package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
- package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
- package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
- package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
- package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
- package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
- package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
- package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
- package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
- package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
- package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
- package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
- package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
- package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
- package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
- package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
- package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
- package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
- package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
- package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
- package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
- package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
- package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
- package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
- package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
- package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
- package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
- package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
- package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
- package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
- package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
- package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
- package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
- package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
- package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
- package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
- package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
- package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
- package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
- package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
- package/src/agent/orchestrator/tools/builtin.mjs +500 -0
- package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
- package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
- package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
- package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
- package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
- package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
- package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
- package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
- package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
- package/src/agent/orchestrator/tools/host-input.mjs +204 -0
- package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
- package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
- package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
- package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
- package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
- package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
- package/src/agent/orchestrator/tools/patch.mjs +2754 -0
- package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
- package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
- package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
- package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
- package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
- package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
- package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
- package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
- package/src/agent/orchestrator/workflow-store.mjs +93 -0
- package/src/agent/tool-defs.mjs +103 -0
- package/src/channels/backends/discord.mjs +784 -0
- package/src/channels/data/voice-runtime-manifest.json +138 -0
- package/src/channels/index.mjs +3229 -0
- package/src/channels/lib/cli-worker-host.mjs +12 -0
- package/src/channels/lib/config-lock.mjs +13 -0
- package/src/channels/lib/config.mjs +292 -0
- package/src/channels/lib/drop-trace.mjs +71 -0
- package/src/channels/lib/event-pipeline.mjs +81 -0
- package/src/channels/lib/event-queue.mjs +345 -0
- package/src/channels/lib/executor.mjs +168 -0
- package/src/channels/lib/format.mjs +188 -0
- package/src/channels/lib/holidays.mjs +138 -0
- package/src/channels/lib/hook-pipe-server.mjs +802 -0
- package/src/channels/lib/interaction-workflows.mjs +184 -0
- package/src/channels/lib/memory-client.mjs +149 -0
- package/src/channels/lib/output-forwarder.mjs +765 -0
- package/src/channels/lib/runtime-paths.mjs +479 -0
- package/src/channels/lib/scheduler.mjs +723 -0
- package/src/channels/lib/session-control.mjs +36 -0
- package/src/channels/lib/session-discovery.mjs +103 -0
- package/src/channels/lib/settings.mjs +11 -0
- package/src/channels/lib/state-file.mjs +68 -0
- package/src/channels/lib/status-snapshot.mjs +219 -0
- package/src/channels/lib/tool-format.mjs +140 -0
- package/src/channels/lib/transcript-discovery.mjs +195 -0
- package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
- package/src/channels/lib/webhook.mjs +1179 -0
- package/src/channels/lib/whisper-server.mjs +477 -0
- package/src/channels/tool-defs.mjs +170 -0
- package/src/daemon/host.mjs +118 -0
- package/src/daemon/mcp-transport.mjs +47 -0
- package/src/daemon/session.mjs +100 -0
- package/src/daemon/thin-client.mjs +71 -0
- package/src/daemon/transport.mjs +163 -0
- package/src/memory/data/runtime-manifest.json +40 -0
- package/src/memory/index.mjs +3305 -0
- package/src/memory/lib/agent-ipc.mjs +93 -0
- package/src/memory/lib/bridge-trace-queries.mjs +120 -0
- package/src/memory/lib/core-memory-store.mjs +330 -0
- package/src/memory/lib/embedding-provider.mjs +269 -0
- package/src/memory/lib/embedding-worker.mjs +323 -0
- package/src/memory/lib/llm-worker-host.mjs +17 -0
- package/src/memory/lib/memory-cycle.mjs +11 -0
- package/src/memory/lib/memory-cycle1.mjs +641 -0
- package/src/memory/lib/memory-cycle2.mjs +1284 -0
- package/src/memory/lib/memory-cycle3.mjs +540 -0
- package/src/memory/lib/memory-embed.mjs +299 -0
- package/src/memory/lib/memory-extraction.mjs +5 -0
- package/src/memory/lib/memory-maintenance-store.mjs +32 -0
- package/src/memory/lib/memory-ops-policy.mjs +190 -0
- package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
- package/src/memory/lib/memory-recall-read-query.mjs +7 -0
- package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
- package/src/memory/lib/memory-recall-store.mjs +621 -0
- package/src/memory/lib/memory-retrievers.mjs +112 -0
- package/src/memory/lib/memory-score.mjs +71 -0
- package/src/memory/lib/memory-text-utils.mjs +58 -0
- package/src/memory/lib/memory.mjs +412 -0
- package/src/memory/lib/model-profile.mjs +85 -0
- package/src/memory/lib/pg/adapter.mjs +308 -0
- package/src/memory/lib/pg/process.mjs +360 -0
- package/src/memory/lib/pg/supervisor.mjs +396 -0
- package/src/memory/lib/project-id-resolver.mjs +86 -0
- package/src/memory/lib/runtime-fetcher.mjs +442 -0
- package/src/memory/lib/trace-store.mjs +728 -0
- package/src/memory/tool-defs.mjs +79 -0
- package/src/search/index.mjs +1173 -0
- package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
- package/src/search/lib/backends/exa.mjs +50 -0
- package/src/search/lib/backends/firecrawl.mjs +61 -0
- package/src/search/lib/backends/gemini-api.mjs +83 -0
- package/src/search/lib/backends/grok-oauth.mjs +86 -0
- package/src/search/lib/backends/index.mjs +150 -0
- package/src/search/lib/backends/openai-api.mjs +144 -0
- package/src/search/lib/backends/openai-oauth.mjs +98 -0
- package/src/search/lib/backends/openai-web-search.mjs +76 -0
- package/src/search/lib/backends/tavily.mjs +55 -0
- package/src/search/lib/backends/xai-api.mjs +113 -0
- package/src/search/lib/cache.mjs +131 -0
- package/src/search/lib/config.mjs +192 -0
- package/src/search/lib/formatter.mjs +115 -0
- package/src/search/lib/provider-usage.mjs +67 -0
- package/src/search/lib/providers.mjs +47 -0
- package/src/search/lib/search-intent.mjs +109 -0
- package/src/search/lib/setup-handler.mjs +261 -0
- package/src/search/lib/state.mjs +201 -0
- package/src/search/lib/web-tools.mjs +1207 -0
- package/src/search/tool-defs.mjs +83 -0
- package/src/setup/defender-exclusion.mjs +183 -0
- package/src/shared/abort-controller.mjs +15 -0
- package/src/shared/atomic-file.mjs +420 -0
- package/src/shared/config.mjs +350 -0
- package/src/shared/daemon-recycle.mjs +108 -0
- package/src/shared/disable-claude-builtins.mjs +88 -0
- package/src/shared/err-text.mjs +12 -0
- package/src/shared/llm/cost.mjs +66 -0
- package/src/shared/llm/http-agent.mjs +123 -0
- package/src/shared/llm/index.mjs +41 -0
- package/src/shared/llm/pid-cleanup.mjs +27 -0
- package/src/shared/llm/usage-log.mjs +47 -0
- package/src/shared/plugin-paths.mjs +58 -0
- package/src/shared/schedules-store.mjs +70 -0
- package/src/shared/seed.mjs +119 -0
- package/src/shared/user-cwd.mjs +213 -0
- package/src/shared/user-data-guard.mjs +238 -0
- package/src/status/aggregator.mjs +584 -0
- package/src/status/server.mjs +413 -0
- package/tools.json +1653 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup UI config merge helpers (importable without starting setup-server).
|
|
3
|
+
*/
|
|
4
|
+
import { applyDefaults as applyChannelsDefaults } from '../src/channels/lib/config.mjs';
|
|
5
|
+
import {
|
|
6
|
+
SECRET_ACCOUNTS,
|
|
7
|
+
saveSecret,
|
|
8
|
+
deleteSecret,
|
|
9
|
+
hasStoredSecret,
|
|
10
|
+
getDiscordToken,
|
|
11
|
+
getWebhookAuthtoken,
|
|
12
|
+
getSearchApiKey,
|
|
13
|
+
getAgentApiKey,
|
|
14
|
+
diagnoseDiscordTokenValue,
|
|
15
|
+
} from '../src/shared/config.mjs';
|
|
16
|
+
|
|
17
|
+
const SUPPORTED_PROVIDERS = [
|
|
18
|
+
'anthropic-oauth', 'openai-oauth', 'openai-api', 'gemini-api', 'xai-api', 'grok-oauth',
|
|
19
|
+
'tavily', 'firecrawl', 'exa',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const AGENT_PROVIDER_ENV = Object.freeze({
|
|
23
|
+
openai: 'OPENAI_API_KEY',
|
|
24
|
+
anthropic: 'ANTHROPIC_API_KEY',
|
|
25
|
+
gemini: 'GEMINI_API_KEY',
|
|
26
|
+
deepseek: 'DEEPSEEK_API_KEY',
|
|
27
|
+
xai: 'XAI_API_KEY',
|
|
28
|
+
nvidia: 'NVIDIA_API_KEY',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function envSecretPresent(account) {
|
|
32
|
+
const key = 'MIXDOG_' + String(account || '').replace(/[.\s]+/g, '_').toUpperCase();
|
|
33
|
+
if (process.env[key]) return true;
|
|
34
|
+
const agentMatch = String(account || '').match(/^agent\.([^.]+)\.apiKey$/);
|
|
35
|
+
if (agentMatch) {
|
|
36
|
+
const std = AGENT_PROVIDER_ENV[agentMatch[1]];
|
|
37
|
+
if (std && process.env[std]) return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getSecretByAccount(account) {
|
|
43
|
+
if (account === SECRET_ACCOUNTS.discordToken) return getDiscordToken();
|
|
44
|
+
if (account === SECRET_ACCOUNTS.webhookAuth) return getWebhookAuthtoken();
|
|
45
|
+
const searchMatch = String(account || '').match(/^search\.([^.]+)\.apiKey$/);
|
|
46
|
+
if (searchMatch) return getSearchApiKey(searchMatch[1]);
|
|
47
|
+
const agentMatch = String(account || '').match(/^agent\.([^.]+)\.apiKey$/);
|
|
48
|
+
if (agentMatch) return getAgentApiKey(agentMatch[1]);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function keychainSecretPresent(account) {
|
|
53
|
+
if (hasStoredSecret(account)) return true;
|
|
54
|
+
if (envSecretPresent(account)) return false;
|
|
55
|
+
return !!getSecretByAccount(account);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function saveSecretChecked(account, rawValue, label) {
|
|
59
|
+
const value = typeof rawValue === 'string' ? rawValue.trim() : '';
|
|
60
|
+
if (!value) {
|
|
61
|
+
return { attempted: false, stored: keychainSecretPresent(account), env: envSecretPresent(account), inputLength: 0 };
|
|
62
|
+
}
|
|
63
|
+
saveSecret(account, value);
|
|
64
|
+
const stored = keychainSecretPresent(account);
|
|
65
|
+
if (!stored && !envSecretPresent(account)) {
|
|
66
|
+
throw new Error(`${label}: keychain write completed but secret is not readable`);
|
|
67
|
+
}
|
|
68
|
+
return { attempted: true, stored, env: envSecretPresent(account), inputLength: value.length };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function deleteSecretIfCurrentValue(account, value) {
|
|
72
|
+
if (!value) return false;
|
|
73
|
+
try {
|
|
74
|
+
if (getSecretByAccount(account) !== value) return false;
|
|
75
|
+
deleteSecret(account);
|
|
76
|
+
return true;
|
|
77
|
+
} catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function saveDiscordTokenChecked(rawValue, config) {
|
|
83
|
+
const value = typeof rawValue === 'string' ? rawValue.trim() : '';
|
|
84
|
+
if (!value) {
|
|
85
|
+
return { attempted: false, stored: keychainSecretPresent(SECRET_ACCOUNTS.discordToken), env: envSecretPresent(SECRET_ACCOUNTS.discordToken), inputLength: 0 };
|
|
86
|
+
}
|
|
87
|
+
const problem = diagnoseDiscordTokenValue(value, config || {});
|
|
88
|
+
if (problem) {
|
|
89
|
+
const removed = deleteSecretIfCurrentValue(SECRET_ACCOUNTS.discordToken, value);
|
|
90
|
+
throw new Error(`channels.discord.token: ${problem}${removed ? ' Removed the invalid saved value.' : ''}`);
|
|
91
|
+
}
|
|
92
|
+
return saveSecretChecked(SECRET_ACCOUNTS.discordToken, value, 'channels.discord.token');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Shallow merge that preserves keys the incoming payload omits. BOTH sides are
|
|
96
|
+
// normalized to plain objects first so a stray array/string (on either side)
|
|
97
|
+
// can never spread into numeric keys (e.g. ['x'] -> {0:'x'}).
|
|
98
|
+
const plainObject = (o) => (o && typeof o === 'object' && !Array.isArray(o)) ? o : {};
|
|
99
|
+
export const mergeKept = (existing, incoming) => ({ ...plainObject(existing), ...plainObject(incoming) });
|
|
100
|
+
|
|
101
|
+
/** schedules/<name>/config.json — partial UI/skill saves must keep unmanaged keys (cron, timezone, secret, …). */
|
|
102
|
+
export function mergeEndpointConfig(existing, incoming) {
|
|
103
|
+
return mergeKept(existing, incoming);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** webhooks/<name>/config.json — merge then pin dispatch role invariant. */
|
|
107
|
+
export function mergeWebhookEndpointConfig(existing, incoming) {
|
|
108
|
+
const merged = mergeEndpointConfig(existing, incoming);
|
|
109
|
+
merged.role = 'webhook-handler';
|
|
110
|
+
return merged;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function mergeAgentConfig(existing, data, secretReport = {}) {
|
|
114
|
+
// Shallow copy of existing preserves unmanaged top-level keys; providers
|
|
115
|
+
// deep-merge per-key (partial save must not wipe other providers).
|
|
116
|
+
const config = { ...existing };
|
|
117
|
+
config.providers = { ...(config.providers || {}) };
|
|
118
|
+
if (data.providers) {
|
|
119
|
+
for (const [name, val] of Object.entries(data.providers)) {
|
|
120
|
+
if (!val || typeof val !== 'object') continue;
|
|
121
|
+
config.providers[name] = { ...(config.providers[name] || {}) };
|
|
122
|
+
for (const [k, v] of Object.entries(val)) {
|
|
123
|
+
if (v === undefined) continue;
|
|
124
|
+
if (k === 'apiKey') {
|
|
125
|
+
secretReport[`agent.${name}.apiKey`] = saveSecretChecked(SECRET_ACCOUNTS.agentApiKey(name), v, `agent.${name}.apiKey`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
config.providers[name][k] = v;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (data.bridge && typeof data.bridge === 'object') {
|
|
133
|
+
config.bridge = { ...(config.bridge || {}), ...data.bridge };
|
|
134
|
+
}
|
|
135
|
+
return config;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function mergeMemoryConfig(existing, incoming, secretReport = {}) {
|
|
139
|
+
// Field-wise partial updates + deep-merge providers (same preserve rules as agent).
|
|
140
|
+
const config = { ...existing };
|
|
141
|
+
if (incoming.enabled !== undefined) config.enabled = incoming.enabled;
|
|
142
|
+
if (incoming.cycle1) {
|
|
143
|
+
if (!config.cycle1) config.cycle1 = {};
|
|
144
|
+
if (incoming.cycle1.interval !== undefined) config.cycle1.interval = incoming.cycle1.interval;
|
|
145
|
+
if (incoming.cycle1.timeout !== undefined) config.cycle1.timeout = incoming.cycle1.timeout;
|
|
146
|
+
if (incoming.cycle1.batchSize !== undefined) config.cycle1.batchSize = incoming.cycle1.batchSize;
|
|
147
|
+
}
|
|
148
|
+
if (incoming.cycle2) {
|
|
149
|
+
if (!config.cycle2) config.cycle2 = {};
|
|
150
|
+
if (incoming.cycle2.interval !== undefined) config.cycle2.interval = incoming.cycle2.interval;
|
|
151
|
+
}
|
|
152
|
+
if (incoming.user) {
|
|
153
|
+
if (!config.user) config.user = { name: '', title: '' };
|
|
154
|
+
if (incoming.user.name !== undefined) config.user.name = incoming.user.name;
|
|
155
|
+
if (incoming.user.title !== undefined) config.user.title = incoming.user.title;
|
|
156
|
+
}
|
|
157
|
+
if (incoming.providers) {
|
|
158
|
+
config.providers = { ...(config.providers || {}) };
|
|
159
|
+
for (const [name, val] of Object.entries(incoming.providers)) {
|
|
160
|
+
if (!val || typeof val !== 'object') continue;
|
|
161
|
+
config.providers[name] = { ...(config.providers[name] || {}) };
|
|
162
|
+
for (const [k, v] of Object.entries(val)) {
|
|
163
|
+
if (v === undefined) continue;
|
|
164
|
+
if (k === 'apiKey') {
|
|
165
|
+
secretReport[`memory.${name}.apiKey`] = saveSecretChecked(SECRET_ACCOUNTS.agentApiKey(name), v, `memory.${name}.apiKey`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
config.providers[name][k] = v;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return config;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function mergeSearchConfig(existing, data, secretReport = {}) {
|
|
176
|
+
// Partial field updates; models shallow-merge; modelOptions replaces per-family
|
|
177
|
+
// entries intentionally so the UI can clear a family's overrides.
|
|
178
|
+
const config = { ...existing };
|
|
179
|
+
if (!config.rawSearch) config.rawSearch = {};
|
|
180
|
+
if (!config.rawSearch.credentials) config.rawSearch.credentials = {};
|
|
181
|
+
if (data.provider !== undefined && SUPPORTED_PROVIDERS.includes(data.provider)) {
|
|
182
|
+
config.provider = data.provider;
|
|
183
|
+
}
|
|
184
|
+
if (data.maxResults !== undefined) config.rawSearch.maxResults = data.maxResults;
|
|
185
|
+
if (data.requestTimeoutMs !== undefined) config.requestTimeoutMs = data.requestTimeoutMs;
|
|
186
|
+
if (data.crawl !== undefined) config.crawl = data.crawl;
|
|
187
|
+
if (data.models !== undefined && typeof data.models === 'object') {
|
|
188
|
+
config.models = { ...(config.models || {}), ...data.models };
|
|
189
|
+
}
|
|
190
|
+
if (data.modelOptions !== undefined && typeof data.modelOptions === 'object') {
|
|
191
|
+
config.modelOptions = { ...(config.modelOptions || {}) };
|
|
192
|
+
for (const [fam, opts] of Object.entries(data.modelOptions)) {
|
|
193
|
+
if (opts && typeof opts === 'object' && Object.keys(opts).length > 0) {
|
|
194
|
+
config.modelOptions[fam] = { ...opts };
|
|
195
|
+
} else {
|
|
196
|
+
delete config.modelOptions[fam];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
for (const [id, key] of Object.entries(data.searchProviders || {})) {
|
|
201
|
+
if (!config.rawSearch.credentials[id]) config.rawSearch.credentials[id] = {};
|
|
202
|
+
secretReport[`search.${id}.apiKey`] = saveSecretChecked(SECRET_ACCOUNTS.searchApiKey(id), key, `search.${id}.apiKey`);
|
|
203
|
+
delete config.rawSearch.credentials[id].apiKey;
|
|
204
|
+
}
|
|
205
|
+
return config;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function mergeConfig(existing, data, secretReport = {}) {
|
|
209
|
+
const config = { ...existing };
|
|
210
|
+
|
|
211
|
+
config.backend = 'discord';
|
|
212
|
+
|
|
213
|
+
if (data.discord) {
|
|
214
|
+
config.discord = { ...config.discord };
|
|
215
|
+
if (Object.prototype.hasOwnProperty.call(data.discord, 'token')) {
|
|
216
|
+
const tokenConfig = {
|
|
217
|
+
...config,
|
|
218
|
+
discord: { ...(config.discord || {}), ...data.discord },
|
|
219
|
+
channelsConfig: data.channelsConfig || config.channelsConfig,
|
|
220
|
+
mainChannel: data.mainChannel || config.mainChannel,
|
|
221
|
+
};
|
|
222
|
+
secretReport['channels.discord.token'] = saveDiscordTokenChecked(data.discord.token, tokenConfig);
|
|
223
|
+
delete config.discord.token;
|
|
224
|
+
}
|
|
225
|
+
if (data.discord.applicationId) config.discord.applicationId = data.discord.applicationId;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (data.channelsConfig && Object.keys(data.channelsConfig).length > 0) {
|
|
229
|
+
// Intentional full replace: deleting a channel in the UI must remove its row;
|
|
230
|
+
// shallow merge would leave stale channel entries on disk.
|
|
231
|
+
config.channelsConfig = data.channelsConfig;
|
|
232
|
+
}
|
|
233
|
+
if (data.mainChannel) config.mainChannel = data.mainChannel;
|
|
234
|
+
if (data.access) config.access = mergeKept(config.access, data.access);
|
|
235
|
+
if (data.voice) config.voice = mergeKept(config.voice, data.voice);
|
|
236
|
+
if (data.schedules) config.schedules = mergeKept(config.schedules, data.schedules);
|
|
237
|
+
if (data.webhook) {
|
|
238
|
+
const { authtoken, ...webhookRest } = data.webhook;
|
|
239
|
+
if (Object.prototype.hasOwnProperty.call(data.webhook, 'authtoken')) {
|
|
240
|
+
secretReport['channels.webhook.authtoken'] = saveSecretChecked(SECRET_ACCOUNTS.webhookAuth, authtoken, 'channels.webhook.authtoken');
|
|
241
|
+
}
|
|
242
|
+
// Strip any plaintext authtoken from the on-disk webhook BEFORE merging so
|
|
243
|
+
// the secret is never re-persisted to config JSON (keychain-only invariant
|
|
244
|
+
// that the prior full-replace path enforced implicitly).
|
|
245
|
+
const { authtoken: _existingAuth, ...existingWebhook } = config.webhook || {};
|
|
246
|
+
config.webhook = mergeKept(existingWebhook, webhookRest);
|
|
247
|
+
}
|
|
248
|
+
if (data.quiet) {
|
|
249
|
+
config.quiet = applyChannelsDefaults({ ...config, quiet: mergeKept(config.quiet, data.quiet) }).quiet;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return config;
|
|
253
|
+
}
|
|
254
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// install.mjs — one-shot bootstrapper that registers the mixdog plugin in the
|
|
3
|
+
// user's Claude Code settings so it auto-loads on the next session start.
|
|
4
|
+
//
|
|
5
|
+
// Run via: npx -p mixdog mixdog-install (after the package is published)
|
|
6
|
+
// or: node setup/install.mjs (from a checkout)
|
|
7
|
+
//
|
|
8
|
+
// It merges two keys into the user-scope settings file (preserving everything
|
|
9
|
+
// else that is already there):
|
|
10
|
+
// extraKnownMarketplaces["trib-plugin"] -> the GitHub marketplace source
|
|
11
|
+
// enabledPlugins["mixdog@trib-plugin"] -> true
|
|
12
|
+
//
|
|
13
|
+
// After it runs, the user restarts Claude Code (or runs /reload-plugins) and
|
|
14
|
+
// mixdog is already present — there is no separate /plugin install step.
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
readFileSync,
|
|
18
|
+
writeFileSync,
|
|
19
|
+
existsSync,
|
|
20
|
+
mkdirSync,
|
|
21
|
+
copyFileSync,
|
|
22
|
+
} from 'node:fs';
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { createInterface } from 'node:readline';
|
|
26
|
+
import { spawn } from 'node:child_process';
|
|
27
|
+
|
|
28
|
+
const MARKETPLACE = 'trib-plugin'; // must match .claude-plugin/marketplace.json "name"
|
|
29
|
+
const PLUGIN_REF = 'mixdog@trib-plugin'; // <plugin name>@<marketplace name>
|
|
30
|
+
const REPO = 'trib-plugin/mixdog'; // github owner/repo
|
|
31
|
+
const REPO_URL = 'https://github.com/trib-plugin/mixdog';
|
|
32
|
+
|
|
33
|
+
// Claude Code honours CLAUDE_CONFIG_DIR; otherwise the user scope is ~/.claude.
|
|
34
|
+
function settingsDir() {
|
|
35
|
+
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function loadSettings(file) {
|
|
39
|
+
if (!existsSync(file)) return {};
|
|
40
|
+
const raw = readFileSync(file, 'utf8');
|
|
41
|
+
if (raw.trim() === '') return {};
|
|
42
|
+
// Invariant: never clobber a file we cannot parse — let the caller abort.
|
|
43
|
+
return JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isPlainObject(value) {
|
|
47
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function main() {
|
|
51
|
+
const dir = settingsDir();
|
|
52
|
+
const file = join(dir, 'settings.json');
|
|
53
|
+
|
|
54
|
+
let settings;
|
|
55
|
+
try {
|
|
56
|
+
settings = loadSettings(file);
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error(`\n✗ ${file} is not valid JSON — refusing to overwrite it.`);
|
|
59
|
+
console.error(` Fix or remove the file, then re-run. (${err.message})`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
if (!isPlainObject(settings)) {
|
|
63
|
+
console.error(`\n✗ ${file} does not contain a JSON object — refusing to overwrite it.`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Merge marketplace + enable flag without touching any other keys.
|
|
68
|
+
if (!isPlainObject(settings.extraKnownMarketplaces)) settings.extraKnownMarketplaces = {};
|
|
69
|
+
settings.extraKnownMarketplaces[MARKETPLACE] = {
|
|
70
|
+
source: { source: 'github', repo: REPO },
|
|
71
|
+
};
|
|
72
|
+
if (!isPlainObject(settings.enabledPlugins)) settings.enabledPlugins = {};
|
|
73
|
+
const already = settings.enabledPlugins[PLUGIN_REF] === true;
|
|
74
|
+
settings.enabledPlugins[PLUGIN_REF] = true;
|
|
75
|
+
|
|
76
|
+
// Back up an existing file before the first write; create the dir otherwise.
|
|
77
|
+
if (existsSync(file)) {
|
|
78
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
79
|
+
const bak = `${file}.bak-${stamp}`;
|
|
80
|
+
copyFileSync(file, bak);
|
|
81
|
+
console.log(`• Backed up existing settings → ${bak}`);
|
|
82
|
+
} else {
|
|
83
|
+
mkdirSync(dir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
writeFileSync(file, JSON.stringify(settings, null, 2) + '\n');
|
|
87
|
+
console.log(`✓ Registered mixdog in ${file}`);
|
|
88
|
+
console.log(` - marketplace "${MARKETPLACE}" → github:${REPO}`);
|
|
89
|
+
console.log(` - enabled plugin "${PLUGIN_REF}"${already ? ' (was already enabled)' : ''}`);
|
|
90
|
+
console.log(`\nNext: restart Claude Code (or run /reload-plugins). mixdog loads automatically.`);
|
|
91
|
+
|
|
92
|
+
maybeStarNudge();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Non-blocking, opt-in star nudge. Only on a real interactive terminal — never
|
|
96
|
+
// in CI or piped/non-TTY installs, so it can never break an automated setup.
|
|
97
|
+
function maybeStarNudge() {
|
|
98
|
+
if (!process.stdin.isTTY || process.env.CI) return;
|
|
99
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
100
|
+
rl.question('\n⭐ Found this useful? Star the repo on GitHub? (Y/n) ', (answer) => {
|
|
101
|
+
const a = answer.trim().toLowerCase();
|
|
102
|
+
if (a === '' || a === 'y' || a === 'yes') openRepo();
|
|
103
|
+
else console.log(`No problem — you can star it anytime at ${REPO_URL}`);
|
|
104
|
+
rl.close();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function openRepo() {
|
|
109
|
+
const platform = process.platform;
|
|
110
|
+
const cmd = platform === 'win32' ? 'cmd' : platform === 'darwin' ? 'open' : 'xdg-open';
|
|
111
|
+
const args = platform === 'win32' ? ['/c', 'start', '', REPO_URL] : [REPO_URL];
|
|
112
|
+
try {
|
|
113
|
+
spawn(cmd, args, { stdio: 'ignore', detached: true }).unref();
|
|
114
|
+
console.log('Opening the repo in your browser — thank you! 🙏');
|
|
115
|
+
} catch {
|
|
116
|
+
console.log(`Please visit ${REPO_URL} to star. Thank you! 🙏`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
main();
|