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,66 @@
|
|
|
1
|
+
import { tmpdir } from 'os';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const ROOT = join(__dirname, '..');
|
|
7
|
+
|
|
8
|
+
process.env.CLAUDE_PLUGIN_ROOT ||= ROOT;
|
|
9
|
+
process.env.CLAUDE_PLUGIN_DATA ||= join(tmpdir(), 'mixdog-guard-smoke-data');
|
|
10
|
+
|
|
11
|
+
const { classifyBashFileLookupCommand, stripSoftWarns } = await import('../src/agent/orchestrator/tool-loop-guard.mjs');
|
|
12
|
+
|
|
13
|
+
// Case A: bash file-lookup classifier catches direct + common wrapper forms.
|
|
14
|
+
{
|
|
15
|
+
const cases = [
|
|
16
|
+
['sed -n "1,40p" rules/bridge/40-cycle1-agent.md', 'sed'],
|
|
17
|
+
['bash -lc "cat rules/shared/01-tool.md"', 'bash-wrapped'],
|
|
18
|
+
['powershell.exe -NoProfile -Command "Get-Content rules/shared/01-tool.md"', 'pwsh-wrapped'],
|
|
19
|
+
['cmd /c type rules\\shared\\01-tool.md', 'cmd-wrapped'],
|
|
20
|
+
['node -e "const fs=require(\'fs\'); console.log(fs.readFileSync(\'rules/x.md\', \'utf8\'))"', 'node-fs-eval'],
|
|
21
|
+
['python -c "from pathlib import Path; print(Path(\'rules/x.md\').read_text())"', 'python-open-eval'],
|
|
22
|
+
['git grep "Bridge Worker" rules', 'git grep'],
|
|
23
|
+
];
|
|
24
|
+
const failed = cases.filter(([cmd, expected]) => classifyBashFileLookupCommand(cmd) !== expected);
|
|
25
|
+
const pass = failed.length === 0;
|
|
26
|
+
process.stdout.write(`Case A: ${pass ? 'PASS' : 'FAIL'}\n`);
|
|
27
|
+
if (!pass) {
|
|
28
|
+
for (const [cmd, expected] of failed) {
|
|
29
|
+
process.stdout.write(` expected ${expected}, got ${classifyBashFileLookupCommand(cmd)} for ${cmd}\n`);
|
|
30
|
+
}
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Case B: a genuine build/test/run/git command is NOT classified as a file lookup.
|
|
36
|
+
{
|
|
37
|
+
const cases = ['npm test', 'git commit -m "x"', 'node build.mjs', 'docker build .'];
|
|
38
|
+
const failed = cases.filter((cmd) => classifyBashFileLookupCommand(cmd) !== null);
|
|
39
|
+
const pass = failed.length === 0;
|
|
40
|
+
process.stdout.write(`Case B: ${pass ? 'PASS' : 'FAIL'}\n`);
|
|
41
|
+
if (!pass) {
|
|
42
|
+
for (const cmd of failed) {
|
|
43
|
+
process.stdout.write(` expected null, got ${classifyBashFileLookupCommand(cmd)} for ${cmd}\n`);
|
|
44
|
+
}
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Case C: stripSoftWarns removes a legacy compact marker line and leaves body intact.
|
|
50
|
+
{
|
|
51
|
+
const body = 'real tool output line 1\nreal tool output line 2';
|
|
52
|
+
const withWarn = `⚠ Same-slice reads(src/x.mjs x2): identical params, body cached.\n${body}`;
|
|
53
|
+
const stripped = stripSoftWarns(withWarn);
|
|
54
|
+
const pass = stripped === body && stripSoftWarns(body) === body;
|
|
55
|
+
process.stdout.write(`Case C: ${pass ? 'PASS' : 'FAIL'}\n`);
|
|
56
|
+
if (!pass) {
|
|
57
|
+
process.stdout.write(` stripped=${JSON.stringify(stripped)}\n`);
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!process.exitCode) {
|
|
63
|
+
process.exit(0);
|
|
64
|
+
} else {
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { tmpdir } from 'os';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
+
process.env.CLAUDE_PLUGIN_ROOT = ROOT;
|
|
8
|
+
const SMOKE_DATA_DIR = process.env.MIXDOG_SCHEMA_SMOKE_DATA_DIR
|
|
9
|
+
|| join(tmpdir(), `mixdog-hidden-role-schema-smoke-data-${process.pid}`);
|
|
10
|
+
if (process.env.MIXDOG_SCHEMA_SMOKE_USE_REAL_DATA !== '1') {
|
|
11
|
+
process.env.CLAUDE_PLUGIN_DATA = SMOKE_DATA_DIR;
|
|
12
|
+
} else {
|
|
13
|
+
process.env.CLAUDE_PLUGIN_DATA ||= SMOKE_DATA_DIR;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { loadConfig, resolveRuntimeSpec } = await import('../src/agent/orchestrator/config.mjs');
|
|
17
|
+
const { getHiddenRole, listHiddenRoleNames } = await import('../src/agent/orchestrator/internal-roles.mjs');
|
|
18
|
+
const {
|
|
19
|
+
resolvePresetName,
|
|
20
|
+
resolveHiddenRoleSchemaAllowedTools,
|
|
21
|
+
} = await import('../src/agent/orchestrator/smart-bridge/bridge-llm.mjs');
|
|
22
|
+
const { prepareBridgeSession } = await import('../src/agent/orchestrator/smart-bridge/session-builder.mjs');
|
|
23
|
+
const { preDispatchDenyForSession } = await import('../src/agent/orchestrator/session/loop.mjs');
|
|
24
|
+
const { initProviders } = await import('../src/agent/orchestrator/providers/registry.mjs');
|
|
25
|
+
|
|
26
|
+
const config = loadConfig();
|
|
27
|
+
|
|
28
|
+
// CI runs in a clean environment with no OAuth credentials, so the default
|
|
29
|
+
// presets' provider (anthropic-oauth) is never registered and createSession
|
|
30
|
+
// would throw `Provider "anthropic-oauth" not found or not enabled`. This
|
|
31
|
+
// smoke only inspects resolved tool schemas — it never issues an LLM call —
|
|
32
|
+
// so register a credential-free provider stub. The provider constructor loads
|
|
33
|
+
// credentials lazily (null when absent); only ensureAuth() touches the network.
|
|
34
|
+
await initProviders({ 'anthropic-oauth': { enabled: true } });
|
|
35
|
+
|
|
36
|
+
let failed = 0;
|
|
37
|
+
const KNOWN_PROFILES = new Set([
|
|
38
|
+
'unified',
|
|
39
|
+
'llm-only',
|
|
40
|
+
'filesystem-read',
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
function fail(message) {
|
|
44
|
+
failed += 1;
|
|
45
|
+
process.stderr.write(`FAIL ${message}\n`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function equalArray(a, b) {
|
|
49
|
+
return Array.isArray(a)
|
|
50
|
+
&& Array.isArray(b)
|
|
51
|
+
&& a.length === b.length
|
|
52
|
+
&& a.every((v, i) => v === b[i]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function buildSession(role, presetOverride = null) {
|
|
56
|
+
const hidden = getHiddenRole(role);
|
|
57
|
+
if (!hidden) throw new Error(`hidden role not found: ${role}`);
|
|
58
|
+
const presetName = presetOverride || resolvePresetName({ role, config });
|
|
59
|
+
const preset = config.presets?.find((p) => p.id === presetName || p.name === presetName);
|
|
60
|
+
if (!preset) throw new Error(`preset not found for ${role}: ${presetName}`);
|
|
61
|
+
const runtimeSpec = resolveRuntimeSpec(preset, { lane: 'bridge', agentId: role });
|
|
62
|
+
const { session } = prepareBridgeSession({
|
|
63
|
+
role,
|
|
64
|
+
presetName,
|
|
65
|
+
preset,
|
|
66
|
+
runtimeSpec,
|
|
67
|
+
permission: hidden.permission || undefined,
|
|
68
|
+
cwd: null,
|
|
69
|
+
skipRoleReminder: true,
|
|
70
|
+
schemaAllowedTools: resolveHiddenRoleSchemaAllowedTools(hidden),
|
|
71
|
+
});
|
|
72
|
+
return (session.tools || []).map((t) => t?.name).filter(Boolean);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function buildWorkerToolNames() {
|
|
76
|
+
// Tool surface parity: compare explorer against bridge `worker` on the
|
|
77
|
+
// same resolved preset (CI has no user-workflow.json worker entry).
|
|
78
|
+
const presetName = resolvePresetName({ role: 'worker', config })
|
|
79
|
+
|| resolvePresetName({ role: 'explorer', config })
|
|
80
|
+
|| null;
|
|
81
|
+
if (!presetName) throw new Error('preset not found for worker baseline');
|
|
82
|
+
const preset = config.presets?.find((p) => p.id === presetName || p.name === presetName);
|
|
83
|
+
if (!preset) throw new Error(`preset not found for worker: ${presetName}`);
|
|
84
|
+
const runtimeSpec = resolveRuntimeSpec(preset, { lane: 'bridge', agentId: 'worker' });
|
|
85
|
+
const { session } = prepareBridgeSession({
|
|
86
|
+
role: 'worker',
|
|
87
|
+
presetName,
|
|
88
|
+
preset,
|
|
89
|
+
runtimeSpec,
|
|
90
|
+
permission: 'read',
|
|
91
|
+
cwd: null,
|
|
92
|
+
});
|
|
93
|
+
return (session.tools || []).map((t) => t?.name).filter(Boolean);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let workerTools = [];
|
|
97
|
+
try {
|
|
98
|
+
workerTools = buildWorkerToolNames();
|
|
99
|
+
} catch (err) {
|
|
100
|
+
fail(`worker baseline: ${err?.message || err}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const cases = [
|
|
104
|
+
['explorer', null, workerTools],
|
|
105
|
+
['cycle1-agent', null, []],
|
|
106
|
+
['cycle2-agent', null, []],
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
for (const role of listHiddenRoleNames().sort()) {
|
|
110
|
+
const hidden = getHiddenRole(role);
|
|
111
|
+
const profile = String(hidden?.toolSchemaProfile || '').trim();
|
|
112
|
+
if (!profile) {
|
|
113
|
+
fail(`${role}: missing toolSchemaProfile`);
|
|
114
|
+
} else if (!KNOWN_PROFILES.has(profile)) {
|
|
115
|
+
fail(`${role}: unknown toolSchemaProfile ${profile}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const [role, preset, expected] of cases) {
|
|
120
|
+
let actual = [];
|
|
121
|
+
try {
|
|
122
|
+
actual = buildSession(role, preset);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
fail(`${role}: ${err?.message || err}`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const pass = equalArray(actual, expected);
|
|
128
|
+
process.stdout.write(`${role}: ${pass ? 'PASS' : 'FAIL'} tools=${actual.join(',') || '(none)'}\n`);
|
|
129
|
+
if (!pass) fail(`${role}: expected ${expected.join(',') || '(none)'}, got ${actual.join(',') || '(none)'}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Read-locked hidden roles: caller cannot upgrade permission to read-write.
|
|
133
|
+
{
|
|
134
|
+
const presetName = resolvePresetName({ role: 'explorer', config });
|
|
135
|
+
const preset = config.presets?.find((p) => p.id === presetName || p.name === presetName);
|
|
136
|
+
const runtimeSpec = resolveRuntimeSpec(preset, { lane: 'bridge', agentId: 'explorer' });
|
|
137
|
+
const { session } = prepareBridgeSession({
|
|
138
|
+
role: 'explorer',
|
|
139
|
+
presetName,
|
|
140
|
+
preset,
|
|
141
|
+
runtimeSpec,
|
|
142
|
+
permission: 'read-write',
|
|
143
|
+
cwd: null,
|
|
144
|
+
owner: 'bridge',
|
|
145
|
+
skipRoleReminder: true,
|
|
146
|
+
schemaAllowedTools: resolveHiddenRoleSchemaAllowedTools(getHiddenRole('explorer')),
|
|
147
|
+
});
|
|
148
|
+
const permOk = session.permission === 'read' && session.toolPermission === 'read';
|
|
149
|
+
const writeDeny = preDispatchDenyForSession(session, { name: 'write' }, 'builtin');
|
|
150
|
+
const pass = permOk && typeof writeDeny === 'string' && writeDeny.includes('permission=read');
|
|
151
|
+
process.stdout.write(`explorer-read-lock: ${pass ? 'PASS' : 'FAIL'}\n`);
|
|
152
|
+
if (!pass) {
|
|
153
|
+
failed += 1;
|
|
154
|
+
process.stderr.write(`FAIL explorer-read-lock: perm=${session.permission}/${session.toolPermission} deny=${writeDeny}\n`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (failed) process.exit(1);
|
|
159
|
+
// Explicit exit: the imported bridge/provider graph opens keep-alive HTTP
|
|
160
|
+
// agent handles (src/shared/llm/http-agent.mjs) that block natural exit —
|
|
161
|
+
// in CI this kept the process alive until the 6h job timeout.
|
|
162
|
+
process.stdout.write('hidden-role-schema-smoke: pass\n', () => process.exit(0));
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import assert from 'assert';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
|
+
const hooks = JSON.parse(readFileSync(join(ROOT, 'hooks', 'hooks.json'), 'utf8'));
|
|
9
|
+
const preToolUse = hooks?.hooks?.PreToolUse || [];
|
|
10
|
+
|
|
11
|
+
function matched(toolName) {
|
|
12
|
+
return preToolUse
|
|
13
|
+
.filter((entry) => new RegExp(entry.matcher).test(toolName))
|
|
14
|
+
.map((entry) => entry.matcher);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
for (const toolName of ['Read', 'Grep', 'Glob']) {
|
|
18
|
+
assert.deepStrictEqual(matched(toolName), ['^(Read|Grep|Glob)$'], `${toolName} native mirror must be blocked`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const toolName of ['mcp__plugin_mixdog_mixdog__edit', 'mcp__plugin_mixdog_trib-plugin__edit']) {
|
|
22
|
+
assert.strictEqual(matched(toolName).length, 1, `${toolName} must enter MCP sandbox hook`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
for (const toolName of ['mcp__plugin_mixdog_mixdog__read', 'mcp__plugin_mixdog_trib-plugin__read']) {
|
|
26
|
+
assert.deepStrictEqual(matched(toolName), [], `${toolName} read-only MCP tool must stay fast-path`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log('hook-routing-smoke passed');
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#requires -Version 5.1
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
Inject keystrokes into another console process via AttachConsole + WriteConsoleInputW.
|
|
5
|
+
|
|
6
|
+
.DESCRIPTION
|
|
7
|
+
Detaches from current console, attaches to target PID's console, writes a sequence of
|
|
8
|
+
KEY_EVENT INPUT_RECORDs (one keydown + one keyup per char), then detaches.
|
|
9
|
+
|
|
10
|
+
No focus dependency, no SendInput, no UI. Works only when the target owns a real
|
|
11
|
+
console (conhost/Windows Terminal). May not work for ConPTY-only hosted children.
|
|
12
|
+
|
|
13
|
+
.PARAMETER TargetPid
|
|
14
|
+
PID of the target console process.
|
|
15
|
+
|
|
16
|
+
.PARAMETER Text
|
|
17
|
+
Text to inject. Literal "\r" or actual CR (0x0D) is treated as Enter.
|
|
18
|
+
|
|
19
|
+
.PARAMETER UseVk
|
|
20
|
+
Diagnostic: also fill VirtualKeyCode/ScanCode via VkKeyScan + MapVirtualKey.
|
|
21
|
+
#>
|
|
22
|
+
[CmdletBinding()]
|
|
23
|
+
param(
|
|
24
|
+
[Parameter(Mandatory=$true)][int]$TargetPid,
|
|
25
|
+
[Parameter(Mandatory=$true)][string]$Text,
|
|
26
|
+
[switch]$UseVk
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
$ErrorActionPreference = 'Stop'
|
|
30
|
+
|
|
31
|
+
# Normalize: literal "\r" -> CR. Also collapse \r\n / lone \n to CR (Windows console Enter).
|
|
32
|
+
$normalized = $Text -replace '\\r', "`r"
|
|
33
|
+
$normalized = $normalized -replace "`r`n", "`r"
|
|
34
|
+
$normalized = $normalized -replace "`n", "`r"
|
|
35
|
+
|
|
36
|
+
$typeDef = @'
|
|
37
|
+
using System;
|
|
38
|
+
using System.Runtime.InteropServices;
|
|
39
|
+
|
|
40
|
+
public static class ConIO {
|
|
41
|
+
[DllImport("kernel32.dll", SetLastError=true)]
|
|
42
|
+
public static extern bool AttachConsole(uint dwProcessId);
|
|
43
|
+
|
|
44
|
+
[DllImport("kernel32.dll", SetLastError=true)]
|
|
45
|
+
public static extern bool FreeConsole();
|
|
46
|
+
|
|
47
|
+
[DllImport("kernel32.dll", SetLastError=true)]
|
|
48
|
+
public static extern IntPtr GetConsoleWindow();
|
|
49
|
+
|
|
50
|
+
[DllImport("kernel32.dll", SetLastError=true)]
|
|
51
|
+
public static extern IntPtr GetStdHandle(int nStdHandle);
|
|
52
|
+
|
|
53
|
+
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode, EntryPoint="CreateFileW")]
|
|
54
|
+
public static extern IntPtr CreateFileW(
|
|
55
|
+
[MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
|
|
56
|
+
uint dwDesiredAccess,
|
|
57
|
+
uint dwShareMode,
|
|
58
|
+
IntPtr lpSecurityAttributes,
|
|
59
|
+
uint dwCreationDisposition,
|
|
60
|
+
uint dwFlagsAndAttributes,
|
|
61
|
+
IntPtr hTemplateFile);
|
|
62
|
+
|
|
63
|
+
[DllImport("kernel32.dll", SetLastError=true)]
|
|
64
|
+
public static extern bool CloseHandle(IntPtr hObject);
|
|
65
|
+
|
|
66
|
+
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode, EntryPoint="WriteConsoleInputW")]
|
|
67
|
+
public static extern bool WriteConsoleInputW(
|
|
68
|
+
IntPtr hConsoleInput,
|
|
69
|
+
[MarshalAs(UnmanagedType.LPArray), In] INPUT_RECORD[] lpBuffer,
|
|
70
|
+
uint nLength,
|
|
71
|
+
out uint lpNumberOfEventsWritten);
|
|
72
|
+
|
|
73
|
+
[DllImport("user32.dll", SetLastError=true)]
|
|
74
|
+
public static extern short VkKeyScanW(char ch);
|
|
75
|
+
|
|
76
|
+
[DllImport("user32.dll", SetLastError=true)]
|
|
77
|
+
public static extern uint MapVirtualKeyW(uint uCode, uint uMapType);
|
|
78
|
+
|
|
79
|
+
public const int STD_INPUT_HANDLE = -10;
|
|
80
|
+
public const ushort KEY_EVENT = 0x0001;
|
|
81
|
+
public const uint MAPVK_VK_TO_VSC = 0;
|
|
82
|
+
public const uint GENERIC_READ = 0x80000000;
|
|
83
|
+
public const uint GENERIC_WRITE = 0x40000000;
|
|
84
|
+
public const uint FILE_SHARE_READ = 0x1;
|
|
85
|
+
public const uint FILE_SHARE_WRITE = 0x2;
|
|
86
|
+
public const uint OPEN_EXISTING = 3;
|
|
87
|
+
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
|
88
|
+
|
|
89
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
90
|
+
public struct KEY_EVENT_RECORD {
|
|
91
|
+
[MarshalAs(UnmanagedType.Bool)] public bool bKeyDown;
|
|
92
|
+
public ushort wRepeatCount;
|
|
93
|
+
public ushort wVirtualKeyCode;
|
|
94
|
+
public ushort wVirtualScanCode;
|
|
95
|
+
public ushort UnicodeChar;
|
|
96
|
+
public uint dwControlKeyState;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[StructLayout(LayoutKind.Explicit)]
|
|
100
|
+
public struct INPUT_RECORD {
|
|
101
|
+
[FieldOffset(0)] public ushort EventType;
|
|
102
|
+
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
'@
|
|
106
|
+
|
|
107
|
+
if (-not ('ConIO' -as [type])) {
|
|
108
|
+
Add-Type -TypeDefinition $typeDef -Language CSharp
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function Write-Err([string]$msg) {
|
|
112
|
+
[Console]::Error.WriteLine($msg)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Detach from any current console first (safe even if none attached).
|
|
116
|
+
[void][ConIO]::FreeConsole()
|
|
117
|
+
|
|
118
|
+
if (-not [ConIO]::AttachConsole([uint32]$TargetPid)) {
|
|
119
|
+
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
|
120
|
+
Write-Err "AttachConsole($TargetPid) failed. Win32 error=$err"
|
|
121
|
+
exit 1
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
$hStdIn = [IntPtr]::Zero
|
|
125
|
+
try {
|
|
126
|
+
# AttachConsole does NOT refresh the cached std handles. Open CONIN$ explicitly.
|
|
127
|
+
$access = [uint32]([ConIO]::GENERIC_READ -bor [ConIO]::GENERIC_WRITE)
|
|
128
|
+
$share = [uint32]([ConIO]::FILE_SHARE_READ -bor [ConIO]::FILE_SHARE_WRITE)
|
|
129
|
+
$hStdIn = [ConIO]::CreateFileW('CONIN$', $access, $share, [IntPtr]::Zero, [ConIO]::OPEN_EXISTING, 0, [IntPtr]::Zero)
|
|
130
|
+
if ($hStdIn -eq [ConIO]::INVALID_HANDLE_VALUE -or $hStdIn -eq [IntPtr]::Zero) {
|
|
131
|
+
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
|
132
|
+
Write-Err "CreateFileW(CONIN$) returned invalid handle. Win32 error=$err"
|
|
133
|
+
exit 1
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
$chars = $normalized.ToCharArray()
|
|
137
|
+
if ($chars.Length -eq 0) {
|
|
138
|
+
Write-Err "Empty text after normalization."
|
|
139
|
+
exit 1
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
$records = New-Object 'ConIO+INPUT_RECORD[]' ($chars.Length * 2)
|
|
143
|
+
for ($i = 0; $i -lt $chars.Length; $i++) {
|
|
144
|
+
$vk = [uint16]0
|
|
145
|
+
$sc = [uint16]0
|
|
146
|
+
if ($UseVk) {
|
|
147
|
+
$scan = [ConIO]::VkKeyScanW($chars[$i])
|
|
148
|
+
if ($scan -ne -1) {
|
|
149
|
+
$vk = [uint16]($scan -band 0xFF)
|
|
150
|
+
$sc = [uint16]([ConIO]::MapVirtualKeyW([uint32]$vk, [ConIO]::MAPVK_VK_TO_VSC) -band 0xFFFF)
|
|
151
|
+
}
|
|
152
|
+
# Special-case CR -> VK_RETURN
|
|
153
|
+
if ([int]$chars[$i] -eq 0x0D) {
|
|
154
|
+
$vk = [uint16]0x0D
|
|
155
|
+
$sc = [uint16]([ConIO]::MapVirtualKeyW([uint32]$vk, [ConIO]::MAPVK_VK_TO_VSC) -band 0xFFFF)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
$down = New-Object 'ConIO+INPUT_RECORD'
|
|
160
|
+
$down.EventType = [ConIO]::KEY_EVENT
|
|
161
|
+
$kd = New-Object 'ConIO+KEY_EVENT_RECORD'
|
|
162
|
+
$kd.bKeyDown = $true
|
|
163
|
+
$kd.wRepeatCount = 1
|
|
164
|
+
$kd.wVirtualKeyCode = $vk
|
|
165
|
+
$kd.wVirtualScanCode = $sc
|
|
166
|
+
$kd.UnicodeChar = [uint16][int]$chars[$i]
|
|
167
|
+
$kd.dwControlKeyState = 0
|
|
168
|
+
$down.KeyEvent = $kd
|
|
169
|
+
|
|
170
|
+
$up = New-Object 'ConIO+INPUT_RECORD'
|
|
171
|
+
$up.EventType = [ConIO]::KEY_EVENT
|
|
172
|
+
$ku = New-Object 'ConIO+KEY_EVENT_RECORD'
|
|
173
|
+
$ku.bKeyDown = $false
|
|
174
|
+
$ku.wRepeatCount = 1
|
|
175
|
+
$ku.wVirtualKeyCode = $vk
|
|
176
|
+
$ku.wVirtualScanCode = $sc
|
|
177
|
+
$ku.UnicodeChar = [uint16][int]$chars[$i]
|
|
178
|
+
$ku.dwControlKeyState = 0
|
|
179
|
+
$up.KeyEvent = $ku
|
|
180
|
+
|
|
181
|
+
$records[$i*2] = $down
|
|
182
|
+
$records[$i*2+1] = $up
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
[uint32]$written = 0
|
|
186
|
+
$ok = [ConIO]::WriteConsoleInputW($hStdIn, $records, [uint32]$records.Length, [ref]$written)
|
|
187
|
+
if (-not $ok) {
|
|
188
|
+
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
|
189
|
+
Write-Err "WriteConsoleInputW failed. Win32 error=$err written=$written expected=$($records.Length)"
|
|
190
|
+
exit 1
|
|
191
|
+
}
|
|
192
|
+
if ($written -ne [uint32]$records.Length) {
|
|
193
|
+
Write-Err "WriteConsoleInputW partial write: written=$written expected=$($records.Length)"
|
|
194
|
+
exit 1
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
if ($hStdIn -ne [IntPtr]::Zero -and $hStdIn -ne [ConIO]::INVALID_HANDLE_VALUE) {
|
|
199
|
+
[void][ConIO]::CloseHandle($hStdIn)
|
|
200
|
+
}
|
|
201
|
+
[void][ConIO]::FreeConsole()
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
exit 0
|