open-multi-agent-kit 0.78.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/AGENTS.md +550 -0
- package/CHANGELOG.md +464 -0
- package/CLAUDE.md +8 -0
- package/DESIGN.md +334 -0
- package/GEMINI.md +8 -0
- package/LICENSE +21 -0
- package/MATURITY.md +77 -0
- package/README.md +279 -0
- package/ROADMAP.md +130 -0
- package/SECURITY.md +83 -0
- package/WORKER_MANIFEST.md +35 -0
- package/dist/adapters/commandcode/commandcode-cli-adapter.d.ts +10 -0
- package/dist/adapters/commandcode/commandcode-cli-adapter.js +57 -0
- package/dist/adapters/kimi/ascii-art.d.ts +1 -0
- package/dist/adapters/kimi/ascii-art.js +23 -0
- package/dist/adapters/kimi/banner.d.ts +53 -0
- package/dist/adapters/kimi/banner.js +284 -0
- package/dist/adapters/kimi/bug-filter.d.ts +15 -0
- package/dist/adapters/kimi/bug-filter.js +150 -0
- package/dist/adapters/kimi/capability.d.ts +25 -0
- package/dist/adapters/kimi/capability.js +68 -0
- package/dist/adapters/kimi/continue-prompt-guard.d.ts +20 -0
- package/dist/adapters/kimi/continue-prompt-guard.js +70 -0
- package/dist/adapters/kimi/isolated-home.d.ts +21 -0
- package/dist/adapters/kimi/isolated-home.js +270 -0
- package/dist/adapters/kimi/runner.d.ts +71 -0
- package/dist/adapters/kimi/runner.js +1084 -0
- package/dist/adapters/kimi/simple-art.d.ts +1 -0
- package/dist/adapters/kimi/simple-art.js +1 -0
- package/dist/adapters/kimi/statusline.d.ts +26 -0
- package/dist/adapters/kimi/statusline.js +142 -0
- package/dist/adapters/kimi/usage.d.ts +52 -0
- package/dist/adapters/kimi/usage.js +481 -0
- package/dist/adapters/kimi/wire-client.d.ts +142 -0
- package/dist/adapters/kimi/wire-client.js +725 -0
- package/dist/adapters/kimi/wire-protocol-types.d.ts +549 -0
- package/dist/adapters/kimi/wire-protocol-types.js +59 -0
- package/dist/adapters/opencode/opencode-cli-adapter.d.ts +9 -0
- package/dist/adapters/opencode/opencode-cli-adapter.js +43 -0
- package/dist/awareness/classifiers/browser-console-classifier.d.ts +3 -0
- package/dist/awareness/classifiers/browser-console-classifier.js +47 -0
- package/dist/awareness/classifiers/evidence-gap-classifier.d.ts +3 -0
- package/dist/awareness/classifiers/evidence-gap-classifier.js +31 -0
- package/dist/awareness/classifiers/stalled-run-classifier.d.ts +2 -0
- package/dist/awareness/classifiers/stalled-run-classifier.js +24 -0
- package/dist/awareness/notice-store.d.ts +6 -0
- package/dist/awareness/notice-store.js +91 -0
- package/dist/awareness/notice.d.ts +17 -0
- package/dist/awareness/notice.js +1 -0
- package/dist/awareness/noticer-engine.d.ts +42 -0
- package/dist/awareness/noticer-engine.js +63 -0
- package/dist/awareness/router.d.ts +6 -0
- package/dist/awareness/router.js +46 -0
- package/dist/brand/matrix-rain.d.ts +15 -0
- package/dist/brand/matrix-rain.js +132 -0
- package/dist/brand/omk-matrix-art.d.ts +1 -0
- package/dist/brand/omk-matrix-art.js +10 -0
- package/dist/brand/omk-simple-art.d.ts +7 -0
- package/dist/brand/omk-simple-art.js +13 -0
- package/dist/brand/palette.d.ts +194 -0
- package/dist/brand/palette.js +53 -0
- package/dist/brand/theme.d.ts +41 -0
- package/dist/brand/theme.js +262 -0
- package/dist/browser/browser-feedback.d.ts +10 -0
- package/dist/browser/browser-feedback.js +84 -0
- package/dist/browser/browser-observer.d.ts +21 -0
- package/dist/browser/browser-observer.js +159 -0
- package/dist/browser/browser-session.d.ts +26 -0
- package/dist/browser/browser-session.js +63 -0
- package/dist/cli/command-registry.d.ts +2 -0
- package/dist/cli/command-registry.js +20 -0
- package/dist/cli/input/argv-parser.d.ts +16 -0
- package/dist/cli/input/argv-parser.js +50 -0
- package/dist/cli/input/command-envelope.d.ts +16 -0
- package/dist/cli/input/command-envelope.js +64 -0
- package/dist/cli/input/config-loader.d.ts +16 -0
- package/dist/cli/input/config-loader.js +48 -0
- package/dist/cli/input/index.d.ts +8 -0
- package/dist/cli/input/index.js +8 -0
- package/dist/cli/input/input-resolver.d.ts +13 -0
- package/dist/cli/input/input-resolver.js +50 -0
- package/dist/cli/input/validator.d.ts +10 -0
- package/dist/cli/input/validator.js +37 -0
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.js +34 -0
- package/dist/cli/output/error-renderer.d.ts +10 -0
- package/dist/cli/output/error-renderer.js +68 -0
- package/dist/cli/output/hash.d.ts +1 -0
- package/dist/cli/output/hash.js +10 -0
- package/dist/cli/output/index.d.ts +9 -0
- package/dist/cli/output/index.js +9 -0
- package/dist/cli/output/json-renderer.d.ts +7 -0
- package/dist/cli/output/json-renderer.js +35 -0
- package/dist/cli/output/markdown-renderer.d.ts +5 -0
- package/dist/cli/output/markdown-renderer.js +86 -0
- package/dist/cli/output/nlp-renderer.d.ts +7 -0
- package/dist/cli/output/nlp-renderer.js +96 -0
- package/dist/cli/output/output-router.d.ts +5 -0
- package/dist/cli/output/output-router.js +33 -0
- package/dist/cli/register-awareness-commands.d.ts +2 -0
- package/dist/cli/register-awareness-commands.js +133 -0
- package/dist/cli/register-basic-commands.d.ts +2 -0
- package/dist/cli/register-basic-commands.js +487 -0
- package/dist/cli/register-integration-commands.d.ts +2 -0
- package/dist/cli/register-integration-commands.js +59 -0
- package/dist/cli/register-mcp-dag-cron-screenshot-commands.d.ts +2 -0
- package/dist/cli/register-mcp-dag-cron-screenshot-commands.js +273 -0
- package/dist/cli/register-openai-codex-commands.d.ts +2 -0
- package/dist/cli/register-openai-codex-commands.js +55 -0
- package/dist/cli/register-provider-commands.d.ts +2 -0
- package/dist/cli/register-provider-commands.js +244 -0
- package/dist/cli/register-spec-agent-goal-commands.d.ts +2 -0
- package/dist/cli/register-spec-agent-goal-commands.js +441 -0
- package/dist/cli/register-tool-commands.d.ts +2 -0
- package/dist/cli/register-tool-commands.js +191 -0
- package/dist/cli/register-workflow-commands.d.ts +2 -0
- package/dist/cli/register-workflow-commands.js +157 -0
- package/dist/cli/registry/core.d.ts +2 -0
- package/dist/cli/registry/core.js +27 -0
- package/dist/cli/registry/session.d.ts +2 -0
- package/dist/cli/registry/session.js +137 -0
- package/dist/cli/registry/system.d.ts +2 -0
- package/dist/cli/registry/system.js +95 -0
- package/dist/cli/registry/tooling.d.ts +2 -0
- package/dist/cli/registry/tooling.js +111 -0
- package/dist/cli/registry/visual.d.ts +2 -0
- package/dist/cli/registry/visual.js +91 -0
- package/dist/cli/root.d.ts +10 -0
- package/dist/cli/root.js +118 -0
- package/dist/cli/runtime/capability-selector.d.ts +18 -0
- package/dist/cli/runtime/capability-selector.js +208 -0
- package/dist/cli/runtime/cli-runtime.d.ts +10 -0
- package/dist/cli/runtime/cli-runtime.js +35 -0
- package/dist/cli/runtime/cli-writer.d.ts +18 -0
- package/dist/cli/runtime/cli-writer.js +87 -0
- package/dist/cli/runtime/command-bus.d.ts +45 -0
- package/dist/cli/runtime/command-bus.js +132 -0
- package/dist/cli/runtime/event-bus.d.ts +12 -0
- package/dist/cli/runtime/event-bus.js +31 -0
- package/dist/cli/runtime/generic-provider-adapter.d.ts +24 -0
- package/dist/cli/runtime/generic-provider-adapter.js +38 -0
- package/dist/cli/runtime/index.d.ts +17 -0
- package/dist/cli/runtime/index.js +18 -0
- package/dist/cli/runtime/intent-classifier.d.ts +16 -0
- package/dist/cli/runtime/intent-classifier.js +113 -0
- package/dist/cli/runtime/plan-controller.d.ts +7 -0
- package/dist/cli/runtime/plan-controller.js +29 -0
- package/dist/cli/runtime/provider-adapter-registry.d.ts +32 -0
- package/dist/cli/runtime/provider-adapter-registry.js +60 -0
- package/dist/cli/runtime/provider-event-normalizer.d.ts +19 -0
- package/dist/cli/runtime/provider-event-normalizer.js +150 -0
- package/dist/cli/runtime/run-controller.d.ts +7 -0
- package/dist/cli/runtime/run-controller.js +30 -0
- package/dist/cli/runtime/runtime-sidecar.d.ts +17 -0
- package/dist/cli/runtime/runtime-sidecar.js +138 -0
- package/dist/cli/runtime/task-controller.d.ts +7 -0
- package/dist/cli/runtime/task-controller.js +29 -0
- package/dist/cli/runtime/types.d.ts +312 -0
- package/dist/cli/runtime/types.js +6 -0
- package/dist/cli/theme/index.d.ts +9 -0
- package/dist/cli/theme/index.js +6 -0
- package/dist/cli/theme/terminal-capability.d.ts +18 -0
- package/dist/cli/theme/terminal-capability.js +88 -0
- package/dist/cli/theme/theme-registry.d.ts +25 -0
- package/dist/cli/theme/theme-registry.js +336 -0
- package/dist/cli/theme/theme-resolver.d.ts +12 -0
- package/dist/cli/theme/theme-resolver.js +38 -0
- package/dist/cli/ui/event.d.ts +65 -0
- package/dist/cli/ui/event.js +1 -0
- package/dist/cli/ui/green-rain-renderer.d.ts +17 -0
- package/dist/cli/ui/green-rain-renderer.js +96 -0
- package/dist/cli/ui/neon-grid-renderer.d.ts +17 -0
- package/dist/cli/ui/neon-grid-renderer.js +99 -0
- package/dist/cli/ui/plain-renderer.d.ts +37 -0
- package/dist/cli/ui/plain-renderer.js +160 -0
- package/dist/cli/ui/renderer.d.ts +7 -0
- package/dist/cli/ui/renderer.js +1 -0
- package/dist/cli/ui/rich-renderer.d.ts +32 -0
- package/dist/cli/ui/rich-renderer.js +234 -0
- package/dist/cli/ui/route-blocked-panel.d.ts +5 -0
- package/dist/cli/ui/route-blocked-panel.js +67 -0
- package/dist/cli/ui/rust-forge-renderer.d.ts +19 -0
- package/dist/cli/ui/rust-forge-renderer.js +129 -0
- package/dist/cli/ui/system24-renderer.d.ts +79 -0
- package/dist/cli/ui/system24-renderer.js +508 -0
- package/dist/cli/v2/chat-repl.d.ts +37 -0
- package/dist/cli/v2/chat-repl.js +280 -0
- package/dist/cli/v2/cli-v2-skeleton.d.ts +99 -0
- package/dist/cli/v2/cli-v2-skeleton.js +350 -0
- package/dist/cli/v2/interactive-prompt.d.ts +51 -0
- package/dist/cli/v2/interactive-prompt.js +187 -0
- package/dist/cli/v2/persistent-memory.d.ts +70 -0
- package/dist/cli/v2/persistent-memory.js +229 -0
- package/dist/cli/v2/provider-commands.d.ts +120 -0
- package/dist/cli/v2/provider-commands.js +244 -0
- package/dist/cli/v2/workflow-commands.d.ts +72 -0
- package/dist/cli/v2/workflow-commands.js +198 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +17 -0
- package/dist/cockpit/git-numstat.d.ts +10 -0
- package/dist/cockpit/git-numstat.js +97 -0
- package/dist/cockpit/lsp-status.d.ts +5 -0
- package/dist/cockpit/lsp-status.js +51 -0
- package/dist/cockpit/types.d.ts +66 -0
- package/dist/cockpit/types.js +4 -0
- package/dist/cockpit/views/rail-view.d.ts +9 -0
- package/dist/cockpit/views/rail-view.js +160 -0
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +263 -0
- package/dist/commands/appshot.d.ts +15 -0
- package/dist/commands/appshot.js +122 -0
- package/dist/commands/auth.d.ts +43 -0
- package/dist/commands/auth.js +167 -0
- package/dist/commands/browser.d.ts +18 -0
- package/dist/commands/browser.js +110 -0
- package/dist/commands/chat/chat-turn-dag.d.ts +21 -0
- package/dist/commands/chat/chat-turn-dag.js +72 -0
- package/dist/commands/chat/core.d.ts +27 -0
- package/dist/commands/chat/core.js +418 -0
- package/dist/commands/chat/index.d.ts +5 -0
- package/dist/commands/chat/index.js +5 -0
- package/dist/commands/chat/native-root-loop.d.ts +57 -0
- package/dist/commands/chat/native-root-loop.js +1041 -0
- package/dist/commands/chat/runtime.d.ts +46 -0
- package/dist/commands/chat/runtime.js +395 -0
- package/dist/commands/chat/slash/commands/control.d.ts +2 -0
- package/dist/commands/chat/slash/commands/control.js +196 -0
- package/dist/commands/chat/slash/commands/diagnostics.d.ts +2 -0
- package/dist/commands/chat/slash/commands/diagnostics.js +64 -0
- package/dist/commands/chat/slash/commands/harness.d.ts +2 -0
- package/dist/commands/chat/slash/commands/harness.js +21 -0
- package/dist/commands/chat/slash/commands/index.d.ts +2 -0
- package/dist/commands/chat/slash/commands/index.js +18 -0
- package/dist/commands/chat/slash/commands/routing.d.ts +2 -0
- package/dist/commands/chat/slash/commands/routing.js +355 -0
- package/dist/commands/chat/slash/commands/session.d.ts +2 -0
- package/dist/commands/chat/slash/commands/session.js +86 -0
- package/dist/commands/chat/slash/commands/tool-plane.d.ts +2 -0
- package/dist/commands/chat/slash/commands/tool-plane.js +64 -0
- package/dist/commands/chat/slash/commands/ui.d.ts +2 -0
- package/dist/commands/chat/slash/commands/ui.js +108 -0
- package/dist/commands/chat/slash/context.d.ts +3 -0
- package/dist/commands/chat/slash/context.js +9 -0
- package/dist/commands/chat/slash/format.d.ts +3 -0
- package/dist/commands/chat/slash/format.js +19 -0
- package/dist/commands/chat/slash/parser.d.ts +15 -0
- package/dist/commands/chat/slash/parser.js +97 -0
- package/dist/commands/chat/slash/registry.d.ts +13 -0
- package/dist/commands/chat/slash/registry.js +38 -0
- package/dist/commands/chat/slash/result.d.ts +7 -0
- package/dist/commands/chat/slash/result.js +35 -0
- package/dist/commands/chat/slash/types.d.ts +32 -0
- package/dist/commands/chat/slash/types.js +1 -0
- package/dist/commands/chat/startup.d.ts +68 -0
- package/dist/commands/chat/startup.js +150 -0
- package/dist/commands/chat/state.d.ts +3 -0
- package/dist/commands/chat/state.js +100 -0
- package/dist/commands/chat/utils.d.ts +25 -0
- package/dist/commands/chat/utils.js +208 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +2 -0
- package/dist/commands/cockpit/core.d.ts +5 -0
- package/dist/commands/cockpit/core.js +91 -0
- package/dist/commands/cockpit/render.d.ts +5 -0
- package/dist/commands/cockpit/render.js +931 -0
- package/dist/commands/cockpit/scroll.d.ts +39 -0
- package/dist/commands/cockpit/scroll.js +87 -0
- package/dist/commands/cockpit/telemetry.d.ts +30 -0
- package/dist/commands/cockpit/telemetry.js +361 -0
- package/dist/commands/cockpit/update-loop.d.ts +54 -0
- package/dist/commands/cockpit/update-loop.js +285 -0
- package/dist/commands/cockpit/utils.d.ts +231 -0
- package/dist/commands/cockpit/utils.js +388 -0
- package/dist/commands/cockpit.d.ts +8 -0
- package/dist/commands/cockpit.js +7 -0
- package/dist/commands/codex.d.ts +70 -0
- package/dist/commands/codex.js +597 -0
- package/dist/commands/consent.d.ts +24 -0
- package/dist/commands/consent.js +255 -0
- package/dist/commands/cron.d.ts +16 -0
- package/dist/commands/cron.js +187 -0
- package/dist/commands/dag-from-spec.d.ts +30 -0
- package/dist/commands/dag-from-spec.js +284 -0
- package/dist/commands/dag.d.ts +10 -0
- package/dist/commands/dag.js +467 -0
- package/dist/commands/design.d.ts +73 -0
- package/dist/commands/design.js +1251 -0
- package/dist/commands/diff-runs.d.ts +3 -0
- package/dist/commands/diff-runs.js +36 -0
- package/dist/commands/do.d.ts +29 -0
- package/dist/commands/do.js +196 -0
- package/dist/commands/doctor/checks.d.ts +20 -0
- package/dist/commands/doctor/checks.js +896 -0
- package/dist/commands/doctor/core.d.ts +2 -0
- package/dist/commands/doctor/core.js +53 -0
- package/dist/commands/doctor/fix-plan.d.ts +69 -0
- package/dist/commands/doctor/fix-plan.js +78 -0
- package/dist/commands/doctor/fix.d.ts +5 -0
- package/dist/commands/doctor/fix.js +1002 -0
- package/dist/commands/doctor/report.d.ts +7 -0
- package/dist/commands/doctor/report.js +151 -0
- package/dist/commands/doctor/utils.d.ts +52 -0
- package/dist/commands/doctor/utils.js +124 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +1 -0
- package/dist/commands/goal.d.ts +46 -0
- package/dist/commands/goal.js +492 -0
- package/dist/commands/google.d.ts +1 -0
- package/dist/commands/google.js +27 -0
- package/dist/commands/graph.d.ts +9 -0
- package/dist/commands/graph.js +26 -0
- package/dist/commands/hud.d.ts +57 -0
- package/dist/commands/hud.js +1031 -0
- package/dist/commands/image.d.ts +16 -0
- package/dist/commands/image.js +102 -0
- package/dist/commands/init/config.d.ts +8 -0
- package/dist/commands/init/config.js +97 -0
- package/dist/commands/init/constants.d.ts +7 -0
- package/dist/commands/init/constants.js +49 -0
- package/dist/commands/init/content.d.ts +12 -0
- package/dist/commands/init/content.js +1783 -0
- package/dist/commands/init/core.d.ts +2 -0
- package/dist/commands/init/core.js +298 -0
- package/dist/commands/init/interactive.d.ts +9 -0
- package/dist/commands/init/interactive.js +170 -0
- package/dist/commands/init/scaffold.d.ts +17 -0
- package/dist/commands/init/scaffold.js +146 -0
- package/dist/commands/init/types.d.ts +35 -0
- package/dist/commands/init/types.js +1 -0
- package/dist/commands/init/utils.d.ts +13 -0
- package/dist/commands/init/utils.js +107 -0
- package/dist/commands/init.d.ts +32 -0
- package/dist/commands/init.js +2581 -0
- package/dist/commands/inspect.d.ts +9 -0
- package/dist/commands/inspect.js +12 -0
- package/dist/commands/lsp.d.ts +8 -0
- package/dist/commands/lsp.js +60 -0
- package/dist/commands/mcp.d.ts +104 -0
- package/dist/commands/mcp.js +1603 -0
- package/dist/commands/menu.d.ts +4 -0
- package/dist/commands/menu.js +213 -0
- package/dist/commands/merge.d.ts +8 -0
- package/dist/commands/merge.js +229 -0
- package/dist/commands/mode.d.ts +3 -0
- package/dist/commands/mode.js +60 -0
- package/dist/commands/model.d.ts +15 -0
- package/dist/commands/model.js +215 -0
- package/dist/commands/notice.d.ts +7 -0
- package/dist/commands/notice.js +76 -0
- package/dist/commands/open-design-agent.d.ts +46 -0
- package/dist/commands/open-design-agent.js +569 -0
- package/dist/commands/orchestrate.d.ts +18 -0
- package/dist/commands/orchestrate.js +284 -0
- package/dist/commands/parallel/core.d.ts +34 -0
- package/dist/commands/parallel/core.js +296 -0
- package/dist/commands/parallel/index.d.ts +5 -0
- package/dist/commands/parallel/index.js +5 -0
- package/dist/commands/parallel/interactive.d.ts +27 -0
- package/dist/commands/parallel/interactive.js +172 -0
- package/dist/commands/parallel/orchestrator.d.ts +40 -0
- package/dist/commands/parallel/orchestrator.js +564 -0
- package/dist/commands/parallel/utils.d.ts +12 -0
- package/dist/commands/parallel/utils.js +114 -0
- package/dist/commands/parallel/worker.d.ts +43 -0
- package/dist/commands/parallel/worker.js +276 -0
- package/dist/commands/parallel.d.ts +4 -0
- package/dist/commands/parallel.js +3 -0
- package/dist/commands/plan.d.ts +6 -0
- package/dist/commands/plan.js +113 -0
- package/dist/commands/project-index.d.ts +18 -0
- package/dist/commands/project-index.js +312 -0
- package/dist/commands/provider.d.ts +65 -0
- package/dist/commands/provider.js +619 -0
- package/dist/commands/rail.d.ts +6 -0
- package/dist/commands/rail.js +7 -0
- package/dist/commands/replay.d.ts +7 -0
- package/dist/commands/replay.js +10 -0
- package/dist/commands/research.d.ts +5 -0
- package/dist/commands/research.js +48 -0
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.js +312 -0
- package/dist/commands/runs.d.ts +36 -0
- package/dist/commands/runs.js +504 -0
- package/dist/commands/screenshot.d.ts +10 -0
- package/dist/commands/screenshot.js +72 -0
- package/dist/commands/skill.d.ts +28 -0
- package/dist/commands/skill.js +382 -0
- package/dist/commands/snip.d.ts +8 -0
- package/dist/commands/snip.js +77 -0
- package/dist/commands/spec.d.ts +17 -0
- package/dist/commands/spec.js +262 -0
- package/dist/commands/specify.d.ts +18 -0
- package/dist/commands/specify.js +111 -0
- package/dist/commands/star.d.ts +3 -0
- package/dist/commands/star.js +30 -0
- package/dist/commands/summary.d.ts +2 -0
- package/dist/commands/summary.js +343 -0
- package/dist/commands/sync.d.ts +6 -0
- package/dist/commands/sync.js +129 -0
- package/dist/commands/team.d.ts +7 -0
- package/dist/commands/team.js +264 -0
- package/dist/commands/verify.d.ts +4 -0
- package/dist/commands/verify.js +320 -0
- package/dist/commands/version.d.ts +6 -0
- package/dist/commands/version.js +83 -0
- package/dist/commands/web-bridge.d.ts +12 -0
- package/dist/commands/web-bridge.js +75 -0
- package/dist/commands/why.d.ts +14 -0
- package/dist/commands/why.js +46 -0
- package/dist/commands/workflow.d.ts +13 -0
- package/dist/commands/workflow.js +385 -0
- package/dist/contracts/dag.d.ts +134 -0
- package/dist/contracts/dag.js +4 -0
- package/dist/contracts/decision.d.ts +23 -0
- package/dist/contracts/decision.js +1 -0
- package/dist/contracts/envelope.d.ts +29 -0
- package/dist/contracts/envelope.js +1 -0
- package/dist/contracts/errors.d.ts +13 -0
- package/dist/contracts/errors.js +15 -0
- package/dist/contracts/evidence.d.ts +23 -0
- package/dist/contracts/evidence.js +1 -0
- package/dist/contracts/goal.d.ts +169 -0
- package/dist/contracts/goal.js +4 -0
- package/dist/contracts/hud.d.ts +17 -0
- package/dist/contracts/hud.js +4 -0
- package/dist/contracts/index.d.ts +8 -0
- package/dist/contracts/index.js +8 -0
- package/dist/contracts/orchestration.d.ts +215 -0
- package/dist/contracts/orchestration.js +4 -0
- package/dist/contracts/proof.d.ts +32 -0
- package/dist/contracts/proof.js +1 -0
- package/dist/contracts/provider.d.ts +35 -0
- package/dist/contracts/provider.js +1 -0
- package/dist/contracts/replay.d.ts +95 -0
- package/dist/contracts/replay.js +7 -0
- package/dist/contracts/run.d.ts +34 -0
- package/dist/contracts/run.js +1 -0
- package/dist/contracts/safety.d.ts +10 -0
- package/dist/contracts/safety.js +4 -0
- package/dist/contracts/version.d.ts +21 -0
- package/dist/contracts/version.js +1 -0
- package/dist/contracts/web-bridge.d.ts +95 -0
- package/dist/contracts/web-bridge.js +168 -0
- package/dist/contracts/worker-context.d.ts +70 -0
- package/dist/contracts/worker-context.js +1 -0
- package/dist/evidence/attempt-record.d.ts +78 -0
- package/dist/evidence/attempt-record.js +16 -0
- package/dist/evidence/context-snapshot.d.ts +20 -0
- package/dist/evidence/context-snapshot.js +81 -0
- package/dist/evidence/decision-trace.d.ts +14 -0
- package/dist/evidence/decision-trace.js +54 -0
- package/dist/evidence/diagnosis.d.ts +15 -0
- package/dist/evidence/diagnosis.js +279 -0
- package/dist/evidence/evidence-recorder.d.ts +19 -0
- package/dist/evidence/evidence-recorder.js +55 -0
- package/dist/evidence/index.d.ts +15 -0
- package/dist/evidence/index.js +7 -0
- package/dist/evidence/run-trace.d.ts +103 -0
- package/dist/evidence/run-trace.js +191 -0
- package/dist/goal/compiler.d.ts +5 -0
- package/dist/goal/compiler.js +350 -0
- package/dist/goal/control-loop.d.ts +109 -0
- package/dist/goal/control-loop.js +1089 -0
- package/dist/goal/ensemble-memory.d.ts +26 -0
- package/dist/goal/ensemble-memory.js +55 -0
- package/dist/goal/eval-criteria.d.ts +3 -0
- package/dist/goal/eval-criteria.js +72 -0
- package/dist/goal/evidence.d.ts +20 -0
- package/dist/goal/evidence.js +321 -0
- package/dist/goal/goal-daemon.d.ts +40 -0
- package/dist/goal/goal-daemon.js +318 -0
- package/dist/goal/intake.d.ts +48 -0
- package/dist/goal/intake.js +561 -0
- package/dist/goal/intent-analyzer.d.ts +9 -0
- package/dist/goal/intent-analyzer.js +322 -0
- package/dist/goal/intent-frame.d.ts +35 -0
- package/dist/goal/intent-frame.js +566 -0
- package/dist/goal/persistence.d.ts +11 -0
- package/dist/goal/persistence.js +134 -0
- package/dist/goal/prompt-digest.d.ts +13 -0
- package/dist/goal/prompt-digest.js +111 -0
- package/dist/goal/scoring.d.ts +2 -0
- package/dist/goal/scoring.js +69 -0
- package/dist/goal/wake-policy.d.ts +26 -0
- package/dist/goal/wake-policy.js +58 -0
- package/dist/harness/create-harness-task-runner.d.ts +43 -0
- package/dist/harness/create-harness-task-runner.js +56 -0
- package/dist/harness/execute-harness-run.d.ts +34 -0
- package/dist/harness/execute-harness-run.js +109 -0
- package/dist/hooks/events.d.ts +71 -0
- package/dist/hooks/events.js +1 -0
- package/dist/hooks/hook-bus.d.ts +13 -0
- package/dist/hooks/hook-bus.js +59 -0
- package/dist/hooks/hook-registry.d.ts +6 -0
- package/dist/hooks/hook-registry.js +64 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hud/index.d.ts +9 -0
- package/dist/hud/index.js +11 -0
- package/dist/hud/live-renderer.d.ts +17 -0
- package/dist/hud/live-renderer.js +52 -0
- package/dist/hud/render.d.ts +62 -0
- package/dist/hud/render.js +954 -0
- package/dist/hud/types.d.ts +58 -0
- package/dist/hud/types.js +7 -0
- package/dist/input/input-artifacts.d.ts +10 -0
- package/dist/input/input-artifacts.js +19 -0
- package/dist/input/input-envelope.d.ts +64 -0
- package/dist/input/input-envelope.js +86 -0
- package/dist/integrations/servarr/adapter.d.ts +29 -0
- package/dist/integrations/servarr/adapter.js +156 -0
- package/dist/integrations/servarr/commands.d.ts +15 -0
- package/dist/integrations/servarr/commands.js +119 -0
- package/dist/integrations/servarr/schema.d.ts +34 -0
- package/dist/integrations/servarr/schema.js +149 -0
- package/dist/kimi/ascii-art.d.ts +1 -0
- package/dist/kimi/ascii-art.js +23 -0
- package/dist/kimi/banner.d.ts +53 -0
- package/dist/kimi/banner.js +284 -0
- package/dist/kimi/bug-filter.d.ts +15 -0
- package/dist/kimi/bug-filter.js +150 -0
- package/dist/kimi/capability.d.ts +25 -0
- package/dist/kimi/capability.js +68 -0
- package/dist/kimi/isolated-home.d.ts +21 -0
- package/dist/kimi/isolated-home.js +270 -0
- package/dist/kimi/runner.d.ts +74 -0
- package/dist/kimi/runner.js +1052 -0
- package/dist/kimi/simple-art.d.ts +1 -0
- package/dist/kimi/simple-art.js +1 -0
- package/dist/kimi/statusline.d.ts +26 -0
- package/dist/kimi/statusline.js +142 -0
- package/dist/kimi/usage.d.ts +52 -0
- package/dist/kimi/usage.js +481 -0
- package/dist/kimi/wire-client.d.ts +95 -0
- package/dist/kimi/wire-client.js +338 -0
- package/dist/lsp/default-config.d.ts +16 -0
- package/dist/lsp/default-config.js +26 -0
- package/dist/mcp/acp-server.d.ts +2 -0
- package/dist/mcp/acp-server.js +357 -0
- package/dist/mcp/autoconnect.d.ts +60 -0
- package/dist/mcp/autoconnect.js +192 -0
- package/dist/mcp/client.d.ts +112 -0
- package/dist/mcp/client.js +276 -0
- package/dist/mcp/config-permissions.d.ts +23 -0
- package/dist/mcp/config-permissions.js +66 -0
- package/dist/mcp/consent-flow.d.ts +152 -0
- package/dist/mcp/consent-flow.js +329 -0
- package/dist/mcp/filesystem-readonly-server.d.ts +2 -0
- package/dist/mcp/filesystem-readonly-server.js +320 -0
- package/dist/mcp/governance.d.ts +292 -0
- package/dist/mcp/governance.js +602 -0
- package/dist/mcp/host.d.ts +154 -0
- package/dist/mcp/host.js +792 -0
- package/dist/mcp/omk-project-server.d.ts +2 -0
- package/dist/mcp/omk-project-server.js +1632 -0
- package/dist/mcp/omk-web-bridge-server.d.ts +14 -0
- package/dist/mcp/omk-web-bridge-server.js +154 -0
- package/dist/mcp/permission-resolver.d.ts +67 -0
- package/dist/mcp/permission-resolver.js +124 -0
- package/dist/mcp/quality-gate.d.ts +36 -0
- package/dist/mcp/quality-gate.js +247 -0
- package/dist/mcp/quarantine.d.ts +11 -0
- package/dist/mcp/quarantine.js +79 -0
- package/dist/mcp/secret-scanner.d.ts +189 -0
- package/dist/mcp/secret-scanner.js +709 -0
- package/dist/mcp/server-catalog.d.ts +36 -0
- package/dist/mcp/server-catalog.js +168 -0
- package/dist/mcp/shared-secret-registry.d.ts +61 -0
- package/dist/mcp/shared-secret-registry.js +171 -0
- package/dist/mcp/transports/stdio.d.ts +22 -0
- package/dist/mcp/transports/stdio.js +165 -0
- package/dist/mcp/transports/streamable-http.d.ts +31 -0
- package/dist/mcp/transports/streamable-http.js +289 -0
- package/dist/mcp/transports/transport.d.ts +20 -0
- package/dist/mcp/transports/transport.js +3 -0
- package/dist/memory/embedding.d.ts +11 -0
- package/dist/memory/embedding.js +24 -0
- package/dist/memory/graph-viewer.d.ts +72 -0
- package/dist/memory/graph-viewer.js +402 -0
- package/dist/memory/kuzu-memory-store.d.ts +37 -0
- package/dist/memory/kuzu-memory-store.js +453 -0
- package/dist/memory/local-graph-memory-store.d.ts +141 -0
- package/dist/memory/local-graph-memory-store.js +884 -0
- package/dist/memory/memory-config.d.ts +51 -0
- package/dist/memory/memory-config.js +187 -0
- package/dist/memory/memory-store.d.ts +48 -0
- package/dist/memory/memory-store.js +210 -0
- package/dist/memory/ontology-model.d.ts +175 -0
- package/dist/memory/ontology-model.js +131 -0
- package/dist/native/linux-x64/omk-safety +0 -0
- package/dist/openai/image-client.d.ts +103 -0
- package/dist/openai/image-client.js +380 -0
- package/dist/orchestration/agent-worker.d.ts +72 -0
- package/dist/orchestration/agent-worker.js +278 -0
- package/dist/orchestration/capability-agents.d.ts +14 -0
- package/dist/orchestration/capability-agents.js +180 -0
- package/dist/orchestration/capability-routing.d.ts +42 -0
- package/dist/orchestration/capability-routing.js +65 -0
- package/dist/orchestration/compiled-dag-executor.d.ts +56 -0
- package/dist/orchestration/compiled-dag-executor.js +88 -0
- package/dist/orchestration/completion-artifacts.d.ts +37 -0
- package/dist/orchestration/completion-artifacts.js +84 -0
- package/dist/orchestration/completion-sentinel.d.ts +37 -0
- package/dist/orchestration/completion-sentinel.js +66 -0
- package/dist/orchestration/contracts/index.d.ts +45 -0
- package/dist/orchestration/contracts/index.js +6 -0
- package/dist/orchestration/dag-artifacts.d.ts +11 -0
- package/dist/orchestration/dag-artifacts.js +42 -0
- package/dist/orchestration/dag-compiler-presets.d.ts +20 -0
- package/dist/orchestration/dag-compiler-presets.js +476 -0
- package/dist/orchestration/dag-compiler-types.d.ts +40 -0
- package/dist/orchestration/dag-compiler-types.js +1 -0
- package/dist/orchestration/dag-compiler.d.ts +3 -0
- package/dist/orchestration/dag-compiler.js +122 -0
- package/dist/orchestration/dag.d.ts +158 -0
- package/dist/orchestration/dag.js +310 -0
- package/dist/orchestration/diagnostics.d.ts +27 -0
- package/dist/orchestration/diagnostics.js +262 -0
- package/dist/orchestration/enhanced-modes.d.ts +116 -0
- package/dist/orchestration/enhanced-modes.js +231 -0
- package/dist/orchestration/enhanced-parallel-orchestrator.d.ts +127 -0
- package/dist/orchestration/enhanced-parallel-orchestrator.js +734 -0
- package/dist/orchestration/ensemble-decision.d.ts +40 -0
- package/dist/orchestration/ensemble-decision.js +297 -0
- package/dist/orchestration/ensemble.d.ts +22 -0
- package/dist/orchestration/ensemble.js +558 -0
- package/dist/orchestration/eta.d.ts +10 -0
- package/dist/orchestration/eta.js +75 -0
- package/dist/orchestration/evidence-check.d.ts +36 -0
- package/dist/orchestration/evidence-check.js +257 -0
- package/dist/orchestration/evidence-gate.d.ts +34 -0
- package/dist/orchestration/evidence-gate.js +501 -0
- package/dist/orchestration/execution-planner.d.ts +40 -0
- package/dist/orchestration/execution-planner.js +252 -0
- package/dist/orchestration/executor.d.ts +11 -0
- package/dist/orchestration/executor.js +979 -0
- package/dist/orchestration/interactive-orchestrator.d.ts +134 -0
- package/dist/orchestration/interactive-orchestrator.js +450 -0
- package/dist/orchestration/log-streamer.d.ts +104 -0
- package/dist/orchestration/log-streamer.js +288 -0
- package/dist/orchestration/loop-artifacts.d.ts +14 -0
- package/dist/orchestration/loop-artifacts.js +20 -0
- package/dist/orchestration/loop-controller.d.ts +14 -0
- package/dist/orchestration/loop-controller.js +311 -0
- package/dist/orchestration/loop-guard.d.ts +28 -0
- package/dist/orchestration/loop-guard.js +104 -0
- package/dist/orchestration/loop-state.d.ts +86 -0
- package/dist/orchestration/loop-state.js +1 -0
- package/dist/orchestration/node-monitor.d.ts +18 -0
- package/dist/orchestration/node-monitor.js +98 -0
- package/dist/orchestration/orchestrate-prompt.d.ts +43 -0
- package/dist/orchestration/orchestrate-prompt.js +533 -0
- package/dist/orchestration/orchestration-state.d.ts +3 -0
- package/dist/orchestration/orchestration-state.js +2 -0
- package/dist/orchestration/parallel-orchestrator.d.ts +159 -0
- package/dist/orchestration/parallel-orchestrator.js +576 -0
- package/dist/orchestration/parallel-ui.d.ts +51 -0
- package/dist/orchestration/parallel-ui.js +470 -0
- package/dist/orchestration/repair-policy.d.ts +20 -0
- package/dist/orchestration/repair-policy.js +221 -0
- package/dist/orchestration/routing/inventory.d.ts +9 -0
- package/dist/orchestration/routing/inventory.js +273 -0
- package/dist/orchestration/routing/mcp-config.d.ts +17 -0
- package/dist/orchestration/routing/mcp-config.js +154 -0
- package/dist/orchestration/routing/types.d.ts +38 -0
- package/dist/orchestration/routing/types.js +4 -0
- package/dist/orchestration/routing.d.ts +31 -0
- package/dist/orchestration/routing.js +961 -0
- package/dist/orchestration/run-state.d.ts +36 -0
- package/dist/orchestration/run-state.js +176 -0
- package/dist/orchestration/scheduler.d.ts +9 -0
- package/dist/orchestration/scheduler.js +85 -0
- package/dist/orchestration/skill-assigner.d.ts +22 -0
- package/dist/orchestration/skill-assigner.js +345 -0
- package/dist/orchestration/state-machine/index.d.ts +3 -0
- package/dist/orchestration/state-machine/index.js +3 -0
- package/dist/orchestration/state-machine/node-state-machine.d.ts +24 -0
- package/dist/orchestration/state-machine/node-state-machine.js +35 -0
- package/dist/orchestration/state-machine/run-state-machine.d.ts +38 -0
- package/dist/orchestration/state-machine/run-state-machine.js +161 -0
- package/dist/orchestration/state-machine/run-state-manager.d.ts +108 -0
- package/dist/orchestration/state-machine/run-state-manager.js +314 -0
- package/dist/orchestration/state-persister.d.ts +7 -0
- package/dist/orchestration/state-persister.js +77 -0
- package/dist/orchestration/task-graph.d.ts +29 -0
- package/dist/orchestration/task-graph.js +261 -0
- package/dist/orchestration/verification-only.d.ts +28 -0
- package/dist/orchestration/verification-only.js +94 -0
- package/dist/providers/attempt-recorder.d.ts +10 -0
- package/dist/providers/attempt-recorder.js +38 -0
- package/dist/providers/codex-cli-runner.d.ts +11 -0
- package/dist/providers/codex-cli-runner.js +129 -0
- package/dist/providers/context-preflight.d.ts +47 -0
- package/dist/providers/context-preflight.js +134 -0
- package/dist/providers/deepseek/deepseek-balance.d.ts +29 -0
- package/dist/providers/deepseek/deepseek-balance.js +80 -0
- package/dist/providers/deepseek/deepseek-client.d.ts +53 -0
- package/dist/providers/deepseek/deepseek-client.js +164 -0
- package/dist/providers/deepseek/deepseek-config.d.ts +89 -0
- package/dist/providers/deepseek/deepseek-config.js +272 -0
- package/dist/providers/deepseek/deepseek-errors.d.ts +5 -0
- package/dist/providers/deepseek/deepseek-errors.js +48 -0
- package/dist/providers/deepseek/deepseek-provider.d.ts +10 -0
- package/dist/providers/deepseek/deepseek-provider.js +162 -0
- package/dist/providers/deepseek/deepseek-super-config.d.ts +31 -0
- package/dist/providers/deepseek/deepseek-super-config.js +136 -0
- package/dist/providers/deepseek-provider.d.ts +8 -0
- package/dist/providers/deepseek-provider.js +78 -0
- package/dist/providers/health.d.ts +13 -0
- package/dist/providers/health.js +55 -0
- package/dist/providers/index.d.ts +22 -0
- package/dist/providers/index.js +22 -0
- package/dist/providers/kimi-provider-failure.d.ts +8 -0
- package/dist/providers/kimi-provider-failure.js +56 -0
- package/dist/providers/kimi-provider.d.ts +7 -0
- package/dist/providers/kimi-provider.js +27 -0
- package/dist/providers/model-registry.d.ts +103 -0
- package/dist/providers/model-registry.js +571 -0
- package/dist/providers/model-table.d.ts +24 -0
- package/dist/providers/model-table.js +140 -0
- package/dist/providers/model-tabs.d.ts +33 -0
- package/dist/providers/model-tabs.js +98 -0
- package/dist/providers/openai-compatible-runner.d.ts +17 -0
- package/dist/providers/openai-compatible-runner.js +180 -0
- package/dist/providers/provider-router.d.ts +8 -0
- package/dist/providers/provider-router.js +174 -0
- package/dist/providers/provider-runtime.d.ts +17 -0
- package/dist/providers/provider-runtime.js +246 -0
- package/dist/providers/provider-stats.d.ts +56 -0
- package/dist/providers/provider-stats.js +303 -0
- package/dist/providers/provider-task-runner.d.ts +23 -0
- package/dist/providers/provider-task-runner.js +1171 -0
- package/dist/providers/provider.d.ts +74 -0
- package/dist/providers/provider.js +9 -0
- package/dist/providers/router.d.ts +14 -0
- package/dist/providers/router.js +486 -0
- package/dist/providers/runner/deepseek-helpers.d.ts +38 -0
- package/dist/providers/runner/deepseek-helpers.js +150 -0
- package/dist/providers/runner/env.d.ts +12 -0
- package/dist/providers/runner/env.js +98 -0
- package/dist/providers/runner/execution.d.ts +26 -0
- package/dist/providers/runner/execution.js +42 -0
- package/dist/providers/runner/helpers.d.ts +9 -0
- package/dist/providers/runner/helpers.js +38 -0
- package/dist/providers/runner/results.d.ts +26 -0
- package/dist/providers/runner/results.js +104 -0
- package/dist/providers/thinking-levels.d.ts +7 -0
- package/dist/providers/thinking-levels.js +67 -0
- package/dist/providers/types.d.ts +139 -0
- package/dist/providers/types.js +60 -0
- package/dist/replay/differ.d.ts +5 -0
- package/dist/replay/differ.js +314 -0
- package/dist/replay/index.d.ts +6 -0
- package/dist/replay/index.js +4 -0
- package/dist/replay/inspector.d.ts +14 -0
- package/dist/replay/inspector.js +264 -0
- package/dist/replay/manifest-builder.d.ts +11 -0
- package/dist/replay/manifest-builder.js +184 -0
- package/dist/replay/replay-engine.d.ts +18 -0
- package/dist/replay/replay-engine.js +265 -0
- package/dist/runtime/adapter.d.ts +77 -0
- package/dist/runtime/adapter.js +28 -0
- package/dist/runtime/agent-runtime.d.ts +123 -0
- package/dist/runtime/agent-runtime.js +18 -0
- package/dist/runtime/cache-stable-session.d.ts +55 -0
- package/dist/runtime/cache-stable-session.js +108 -0
- package/dist/runtime/capability-injection.d.ts +39 -0
- package/dist/runtime/capability-injection.js +93 -0
- package/dist/runtime/chat-advisory-runtime.d.ts +2 -0
- package/dist/runtime/chat-advisory-runtime.js +71 -0
- package/dist/runtime/child-env.d.ts +31 -0
- package/dist/runtime/child-env.js +131 -0
- package/dist/runtime/codex-cli-runtime.d.ts +10 -0
- package/dist/runtime/codex-cli-runtime.js +78 -0
- package/dist/runtime/codex-runtime.d.ts +35 -0
- package/dist/runtime/codex-runtime.js +264 -0
- package/dist/runtime/command-bus.d.ts +13 -0
- package/dist/runtime/command-bus.js +57 -0
- package/dist/runtime/context-broker-converter.d.ts +9 -0
- package/dist/runtime/context-broker-converter.js +96 -0
- package/dist/runtime/context-broker.d.ts +25 -0
- package/dist/runtime/context-broker.js +308 -0
- package/dist/runtime/context-budget-optimizer.d.ts +73 -0
- package/dist/runtime/context-budget-optimizer.js +300 -0
- package/dist/runtime/context-capsule.d.ts +81 -0
- package/dist/runtime/context-capsule.js +46 -0
- package/dist/runtime/contracts/command-envelope.d.ts +99 -0
- package/dist/runtime/contracts/command-envelope.js +5 -0
- package/dist/runtime/contracts/reasoning-trace.d.ts +120 -0
- package/dist/runtime/contracts/reasoning-trace.js +10 -0
- package/dist/runtime/contracts/shared.d.ts +34 -0
- package/dist/runtime/contracts/shared.js +12 -0
- package/dist/runtime/core-verified-preset.d.ts +37 -0
- package/dist/runtime/core-verified-preset.js +205 -0
- package/dist/runtime/debloat-nlp.d.ts +140 -0
- package/dist/runtime/debloat-nlp.js +398 -0
- package/dist/runtime/deepseek-runtime.d.ts +28 -0
- package/dist/runtime/deepseek-runtime.js +270 -0
- package/dist/runtime/external-cli-adapter.d.ts +29 -0
- package/dist/runtime/external-cli-adapter.js +283 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/kimi-api-runtime.d.ts +52 -0
- package/dist/runtime/kimi-api-runtime.js +367 -0
- package/dist/runtime/kimi-print-runtime.d.ts +10 -0
- package/dist/runtime/kimi-print-runtime.js +87 -0
- package/dist/runtime/kimi-wire-protocol-runtime.d.ts +44 -0
- package/dist/runtime/kimi-wire-protocol-runtime.js +436 -0
- package/dist/runtime/kimi-wire-runtime.d.ts +17 -0
- package/dist/runtime/kimi-wire-runtime.js +112 -0
- package/dist/runtime/legacy-bridge.d.ts +14 -0
- package/dist/runtime/legacy-bridge.js +27 -0
- package/dist/runtime/local-llm-runtime.d.ts +29 -0
- package/dist/runtime/local-llm-runtime.js +231 -0
- package/dist/runtime/mimo-api-runtime.d.ts +13 -0
- package/dist/runtime/mimo-api-runtime.js +24 -0
- package/dist/runtime/nlg-renderer.d.ts +38 -0
- package/dist/runtime/nlg-renderer.js +132 -0
- package/dist/runtime/output-router.d.ts +20 -0
- package/dist/runtime/output-router.js +171 -0
- package/dist/runtime/process-session.d.ts +27 -0
- package/dist/runtime/process-session.js +35 -0
- package/dist/runtime/prompt-envelope.d.ts +28 -0
- package/dist/runtime/prompt-envelope.js +78 -0
- package/dist/runtime/provider-event-normalizer.d.ts +117 -0
- package/dist/runtime/provider-event-normalizer.js +454 -0
- package/dist/runtime/provider-tool-contracts.d.ts +24 -0
- package/dist/runtime/provider-tool-contracts.js +56 -0
- package/dist/runtime/reasoning-trace.d.ts +46 -0
- package/dist/runtime/reasoning-trace.js +289 -0
- package/dist/runtime/renderers.d.ts +33 -0
- package/dist/runtime/renderers.js +221 -0
- package/dist/runtime/runtime-backed-task-runner.d.ts +20 -0
- package/dist/runtime/runtime-backed-task-runner.js +166 -0
- package/dist/runtime/runtime-bootstrap.d.ts +21 -0
- package/dist/runtime/runtime-bootstrap.js +208 -0
- package/dist/runtime/runtime-registry.d.ts +23 -0
- package/dist/runtime/runtime-registry.js +95 -0
- package/dist/runtime/runtime-router.d.ts +51 -0
- package/dist/runtime/runtime-router.js +620 -0
- package/dist/runtime/sandbox-profile.d.ts +25 -0
- package/dist/runtime/sandbox-profile.js +35 -0
- package/dist/runtime/slash-commands.d.ts +46 -0
- package/dist/runtime/slash-commands.js +321 -0
- package/dist/runtime/stable-json.d.ts +9 -0
- package/dist/runtime/stable-json.js +45 -0
- package/dist/runtime/tool-call-repair.d.ts +35 -0
- package/dist/runtime/tool-call-repair.js +181 -0
- package/dist/runtime/tool-dispatch-contracts.d.ts +8 -0
- package/dist/runtime/tool-dispatch-contracts.js +32 -0
- package/dist/runtime/tool-plane.d.ts +31 -0
- package/dist/runtime/tool-plane.js +112 -0
- package/dist/runtime/tool-proxy.d.ts +20 -0
- package/dist/runtime/tool-proxy.js +109 -0
- package/dist/runtime/tool-registry-contract.d.ts +40 -0
- package/dist/runtime/tool-registry-contract.js +52 -0
- package/dist/runtime/ui-components.d.ts +64 -0
- package/dist/runtime/ui-components.js +232 -0
- package/dist/runtime/worker-manifest.d.ts +34 -0
- package/dist/runtime/worker-manifest.js +204 -0
- package/dist/safety/approval-policy.d.ts +4 -0
- package/dist/safety/approval-policy.js +33 -0
- package/dist/safety/guard-hooks.d.ts +3 -0
- package/dist/safety/guard-hooks.js +64 -0
- package/dist/schema/decision.schema.d.ts +57 -0
- package/dist/schema/decision.schema.js +32 -0
- package/dist/schema/envelope.schema.d.ts +216 -0
- package/dist/schema/envelope.schema.js +38 -0
- package/dist/schema/error.schema.d.ts +51 -0
- package/dist/schema/error.schema.js +12 -0
- package/dist/schema/evidence.schema.d.ts +58 -0
- package/dist/schema/evidence.schema.js +31 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/index.js +8 -0
- package/dist/schema/proof-bundle.schema.d.ts +150 -0
- package/dist/schema/proof-bundle.schema.js +42 -0
- package/dist/schema/provider.schema.d.ts +138 -0
- package/dist/schema/provider.schema.js +35 -0
- package/dist/schema/run-manifest.schema.d.ts +168 -0
- package/dist/schema/run-manifest.schema.js +35 -0
- package/dist/schema/version.schema.d.ts +64 -0
- package/dist/schema/version.schema.js +21 -0
- package/dist/theme/ansi.d.ts +15 -0
- package/dist/theme/ansi.js +41 -0
- package/dist/theme/colors.d.ts +87 -0
- package/dist/theme/colors.js +105 -0
- package/dist/theme/hud-theme.d.ts +6 -0
- package/dist/theme/hud-theme.js +41 -0
- package/dist/theme/index.d.ts +12 -0
- package/dist/theme/index.js +20 -0
- package/dist/theme/layout.d.ts +24 -0
- package/dist/theme/layout.js +139 -0
- package/dist/theme/metrics.d.ts +23 -0
- package/dist/theme/metrics.js +93 -0
- package/dist/theme/parallel.d.ts +68 -0
- package/dist/theme/parallel.js +345 -0
- package/dist/theme/working-indicator.d.ts +38 -0
- package/dist/theme/working-indicator.js +149 -0
- package/dist/tui/model.d.ts +28 -0
- package/dist/tui/model.js +1 -0
- package/dist/tui/terminal-frame-renderer.d.ts +19 -0
- package/dist/tui/terminal-frame-renderer.js +60 -0
- package/dist/tui/views/capabilities-view.d.ts +3 -0
- package/dist/tui/views/capabilities-view.js +13 -0
- package/dist/tui/views/common.d.ts +11 -0
- package/dist/tui/views/common.js +35 -0
- package/dist/tui/views/dag-view.d.ts +3 -0
- package/dist/tui/views/dag-view.js +12 -0
- package/dist/tui/views/evidence-view.d.ts +3 -0
- package/dist/tui/views/evidence-view.js +18 -0
- package/dist/tui/views/index.d.ts +4 -0
- package/dist/tui/views/index.js +3 -0
- package/dist/ui/omk-sigil.d.ts +13 -0
- package/dist/ui/omk-sigil.js +277 -0
- package/dist/ui/omk-working-sweep.d.ts +61 -0
- package/dist/ui/omk-working-sweep.js +416 -0
- package/dist/util/agent-schema.d.ts +24 -0
- package/dist/util/agent-schema.js +293 -0
- package/dist/util/appshot-store.d.ts +68 -0
- package/dist/util/appshot-store.js +506 -0
- package/dist/util/chat-agent-mode.d.ts +173 -0
- package/dist/util/chat-agent-mode.js +905 -0
- package/dist/util/chat-cockpit.d.ts +45 -0
- package/dist/util/chat-cockpit.js +293 -0
- package/dist/util/chat-startup.d.ts +35 -0
- package/dist/util/chat-startup.js +330 -0
- package/dist/util/chat-state.d.ts +27 -0
- package/dist/util/chat-state.js +105 -0
- package/dist/util/checkpoint.d.ts +21 -0
- package/dist/util/checkpoint.js +238 -0
- package/dist/util/cli-contract.d.ts +46 -0
- package/dist/util/cli-contract.js +72 -0
- package/dist/util/cron-engine.d.ts +24 -0
- package/dist/util/cron-engine.js +227 -0
- package/dist/util/events-logger.d.ts +30 -0
- package/dist/util/events-logger.js +135 -0
- package/dist/util/execution-selection.d.ts +13 -0
- package/dist/util/execution-selection.js +82 -0
- package/dist/util/first-run-star.d.ts +49 -0
- package/dist/util/first-run-star.js +223 -0
- package/dist/util/fs.d.ts +128 -0
- package/dist/util/fs.js +1757 -0
- package/dist/util/git.d.ts +11 -0
- package/dist/util/git.js +39 -0
- package/dist/util/help-text.d.ts +1 -0
- package/dist/util/help-text.js +60 -0
- package/dist/util/i18n.d.ts +10 -0
- package/dist/util/i18n.js +848 -0
- package/dist/util/json-envelope.d.ts +15 -0
- package/dist/util/json-envelope.js +28 -0
- package/dist/util/mcp-preflight.d.ts +26 -0
- package/dist/util/mcp-preflight.js +29 -0
- package/dist/util/mode-preset.d.ts +29 -0
- package/dist/util/mode-preset.js +222 -0
- package/dist/util/mode-selector.d.ts +6 -0
- package/dist/util/mode-selector.js +74 -0
- package/dist/util/native-safety.d.ts +28 -0
- package/dist/util/native-safety.js +118 -0
- package/dist/util/output-buffer.d.ts +12 -0
- package/dist/util/output-buffer.js +59 -0
- package/dist/util/process-tree.d.ts +18 -0
- package/dist/util/process-tree.js +102 -0
- package/dist/util/project-root.d.ts +27 -0
- package/dist/util/project-root.js +382 -0
- package/dist/util/provider-usage.d.ts +2 -0
- package/dist/util/provider-usage.js +1 -0
- package/dist/util/reasoning-nlp.d.ts +84 -0
- package/dist/util/reasoning-nlp.js +325 -0
- package/dist/util/resource-profile.d.ts +32 -0
- package/dist/util/resource-profile.js +219 -0
- package/dist/util/run-store.d.ts +38 -0
- package/dist/util/run-store.js +151 -0
- package/dist/util/run-view-model.d.ts +111 -0
- package/dist/util/run-view-model.js +333 -0
- package/dist/util/runtime-profile.d.ts +34 -0
- package/dist/util/runtime-profile.js +149 -0
- package/dist/util/runtime-scope.d.ts +2 -0
- package/dist/util/runtime-scope.js +19 -0
- package/dist/util/scoped-agent-file.d.ts +47 -0
- package/dist/util/scoped-agent-file.js +121 -0
- package/dist/util/screenshot-store.d.ts +35 -0
- package/dist/util/screenshot-store.js +310 -0
- package/dist/util/secret-mask.d.ts +5 -0
- package/dist/util/secret-mask.js +41 -0
- package/dist/util/session.d.ts +19 -0
- package/dist/util/session.js +80 -0
- package/dist/util/shell.d.ts +30 -0
- package/dist/util/shell.js +350 -0
- package/dist/util/snippet.d.ts +17 -0
- package/dist/util/snippet.js +110 -0
- package/dist/util/sync-manifest.d.ts +13 -0
- package/dist/util/sync-manifest.js +22 -0
- package/dist/util/terminal-input.d.ts +25 -0
- package/dist/util/terminal-input.js +35 -0
- package/dist/util/terminal-layout.d.ts +18 -0
- package/dist/util/terminal-layout.js +108 -0
- package/dist/util/terminal-owner.d.ts +19 -0
- package/dist/util/terminal-owner.js +64 -0
- package/dist/util/theme.d.ts +9 -0
- package/dist/util/theme.js +9 -0
- package/dist/util/timeout-config.d.ts +18 -0
- package/dist/util/timeout-config.js +101 -0
- package/dist/util/todo-sync.d.ts +58 -0
- package/dist/util/todo-sync.js +473 -0
- package/dist/util/update-check.d.ts +89 -0
- package/dist/util/update-check.js +321 -0
- package/dist/util/usage-view-model.d.ts +22 -0
- package/dist/util/usage-view-model.js +57 -0
- package/dist/util/user-visible-output.d.ts +19 -0
- package/dist/util/user-visible-output.js +48 -0
- package/dist/util/version.d.ts +4 -0
- package/dist/util/version.js +51 -0
- package/dist/util/worktree.d.ts +10 -0
- package/dist/util/worktree.js +165 -0
- package/dist/ux/explain-loop-decision.d.ts +4 -0
- package/dist/ux/explain-loop-decision.js +55 -0
- package/dist/ux/intent-router.d.ts +15 -0
- package/dist/ux/intent-router.js +64 -0
- package/dist/ux/natural-entrypoint.d.ts +21 -0
- package/dist/ux/natural-entrypoint.js +122 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.js +18 -0
- package/dist/web-bridge/host.d.ts +8 -0
- package/dist/web-bridge/host.js +109 -0
- package/dist/web-bridge/native-host.d.ts +6 -0
- package/dist/web-bridge/native-host.js +40 -0
- package/dist/web-bridge/status.d.ts +84 -0
- package/dist/web-bridge/status.js +201 -0
- package/docs/2026-05-01-16gb-lite-mode.md +37 -0
- package/docs/2026-05-01-critical-issues-and-improvements.md +361 -0
- package/docs/2026-05-01-dag-ensemble-runtime.md +74 -0
- package/docs/2026-05-02-p1-p2-hardening-handoff.md +139 -0
- package/docs/2026-05-05-adjustable-timeouts-and-cron-jobs.md +252 -0
- package/docs/2026-05-08-omk-hardening-plan.md +62 -0
- package/docs/2026-05-14/critical-issues.md +20 -0
- package/docs/2026-05-14/improvements.md +14 -0
- package/docs/2026-05-14/init-checklist.md +25 -0
- package/docs/2026-05-14/plan.md +20 -0
- package/docs/2026-05-15/critical-issues.md +20 -0
- package/docs/2026-05-15/improvements.md +14 -0
- package/docs/2026-05-15/init-checklist.md +25 -0
- package/docs/2026-05-15/plan.md +20 -0
- package/docs/2026-05-16/critical-issues.md +20 -0
- package/docs/2026-05-16/improvements.md +14 -0
- package/docs/2026-05-16/init-checklist.md +25 -0
- package/docs/2026-05-16/plan.md +20 -0
- package/docs/2026-05-17/critical-issues.md +20 -0
- package/docs/2026-05-17/improvements.md +14 -0
- package/docs/2026-05-17/init-checklist.md +25 -0
- package/docs/2026-05-17/plan.md +20 -0
- package/docs/2026-05-18/improvements.md +14 -0
- package/docs/2026-05-18/init-checklist.md +25 -0
- package/docs/2026-05-18/plan.md +20 -0
- package/docs/2026-05-18-critical-issues-and-improvements.md +441 -0
- package/docs/2026-05-18-project-direction.md +223 -0
- package/docs/2026-05-19/critical-issues.md +20 -0
- package/docs/2026-05-19/improvements.md +14 -0
- package/docs/2026-05-19/init-checklist.md +25 -0
- package/docs/2026-05-19/plan.md +20 -0
- package/docs/2026-05-20/critical-issues.md +20 -0
- package/docs/2026-05-20/improvements.md +14 -0
- package/docs/2026-05-20/init-checklist.md +25 -0
- package/docs/2026-05-20/plan.md +20 -0
- package/docs/2026-05-21/critical-issues.md +20 -0
- package/docs/2026-05-21/improvements.md +14 -0
- package/docs/2026-05-21/init-checklist.md +25 -0
- package/docs/2026-05-21/plan.md +20 -0
- package/docs/2026-05-22/critical-issues.md +20 -0
- package/docs/2026-05-22/improvements.md +14 -0
- package/docs/2026-05-22/init-checklist.md +25 -0
- package/docs/2026-05-22/plan.md +20 -0
- package/docs/2026-05-23/critical-issues.md +20 -0
- package/docs/2026-05-23/improvements.md +14 -0
- package/docs/2026-05-23/init-checklist.md +25 -0
- package/docs/2026-05-23/plan.md +20 -0
- package/docs/2026-05-24/critical-issues.md +30 -0
- package/docs/2026-05-24/improvements.md +23 -0
- package/docs/2026-05-24/init-checklist.md +25 -0
- package/docs/2026-05-24/plan.md +22 -0
- package/docs/2026-05-25/critical-issues.md +20 -0
- package/docs/2026-05-25/improvements.md +14 -0
- package/docs/2026-05-25/init-checklist.md +25 -0
- package/docs/2026-05-25/plan.md +20 -0
- package/docs/2026-05-26/critical-issues.md +20 -0
- package/docs/2026-05-26/improvements.md +14 -0
- package/docs/2026-05-26/init-checklist.md +25 -0
- package/docs/2026-05-26/plan.md +20 -0
- package/docs/2026-05-27/critical-issues.md +20 -0
- package/docs/2026-05-27/improvements.md +14 -0
- package/docs/2026-05-27/init-checklist.md +25 -0
- package/docs/2026-05-27/plan.md +20 -0
- package/docs/2026-05-28/critical-issues.md +20 -0
- package/docs/2026-05-28/improvements.md +14 -0
- package/docs/2026-05-28/init-checklist.md +25 -0
- package/docs/2026-05-28/plan.md +20 -0
- package/docs/2026-05-29/critical-issues.md +20 -0
- package/docs/2026-05-29/improvements.md +14 -0
- package/docs/2026-05-29/init-checklist.md +25 -0
- package/docs/2026-05-29/plan.md +20 -0
- package/docs/2026-05-30/critical-issues.md +20 -0
- package/docs/2026-05-30/improvements.md +14 -0
- package/docs/2026-05-30/init-checklist.md +25 -0
- package/docs/2026-05-30/plan.md +20 -0
- package/docs/2026-05-31/critical-issues.md +20 -0
- package/docs/2026-05-31/improvements.md +14 -0
- package/docs/2026-05-31/init-checklist.md +25 -0
- package/docs/2026-05-31/plan.md +20 -0
- package/docs/2026-06-01/critical-issues.md +20 -0
- package/docs/2026-06-01/improvements.md +14 -0
- package/docs/2026-06-01/init-checklist.md +25 -0
- package/docs/2026-06-01/plan.md +20 -0
- package/docs/2026-06-02/critical-issues.md +20 -0
- package/docs/2026-06-02/improvements.md +14 -0
- package/docs/2026-06-02/init-checklist.md +25 -0
- package/docs/2026-06-02/plan.md +20 -0
- package/docs/2026-06-03/critical-issues.md +20 -0
- package/docs/2026-06-03/improvements.md +14 -0
- package/docs/2026-06-03/init-checklist.md +25 -0
- package/docs/2026-06-03/plan.md +20 -0
- package/docs/2026-06-04/critical-issues.md +20 -0
- package/docs/2026-06-04/improvements.md +14 -0
- package/docs/2026-06-04/init-checklist.md +25 -0
- package/docs/2026-06-04/plan.md +20 -0
- package/docs/2026-06-05/critical-issues.md +20 -0
- package/docs/2026-06-05/improvements.md +14 -0
- package/docs/2026-06-05/init-checklist.md +25 -0
- package/docs/2026-06-05/plan.md +20 -0
- package/docs/2026-06-06/critical-issues.md +20 -0
- package/docs/2026-06-06/improvements.md +14 -0
- package/docs/2026-06-06/init-checklist.md +25 -0
- package/docs/2026-06-06/plan.md +20 -0
- package/docs/2026-06-07/critical-issues.md +20 -0
- package/docs/2026-06-07/improvements.md +14 -0
- package/docs/2026-06-07/init-checklist.md +25 -0
- package/docs/2026-06-07/plan.md +20 -0
- package/docs/GSTACK_MIGRATION.md +169 -0
- package/docs/OMK_CLI_V2_RUNTIME_ARCHITECTURE.md +2058 -0
- package/docs/cli-v2-migration.md +87 -0
- package/docs/codex-oauth-setup.md +48 -0
- package/docs/demo/verified-run/README.md +32 -0
- package/docs/demo/verified-run/artifacts/README.md +18 -0
- package/docs/demo/verified-run/capture-plan.md +51 -0
- package/docs/demo/verified-run/generated-diff.md +27 -0
- package/docs/demo/verified-run/raw-prompt.md +21 -0
- package/docs/demo/verified-run/video-shot-list.md +14 -0
- package/docs/design-md.md +35 -0
- package/docs/getting-started.md +37 -0
- package/docs/hud-and-parallel-ux.md +155 -0
- package/docs/kimi-oauth-usage-status.md +33 -0
- package/docs/kimi-okabe-dmail.md +44 -0
- package/docs/local-graph-memory.md +102 -0
- package/docs/lsp.md +48 -0
- package/docs/mcp-ontology-proposal.md +12 -0
- package/docs/native-root-runtime-algorithms.md +402 -0
- package/docs/native-root-runtime-hardening.md +131 -0
- package/docs/neo4j-memory.md +5 -0
- package/docs/openai-platform-image-keys.md +23 -0
- package/docs/phase1-final-report.md +154 -0
- package/docs/provider-maturity.md +44 -0
- package/docs/runtime-architecture.md +89 -0
- package/docs/versioning.md +49 -0
- package/llms.txt +38 -0
- package/package.json +188 -0
- package/readmeasset/.npmignore +20 -0
- package/readmeasset/ASSET_INDEX.md +36 -0
- package/readmeasset/ASSET_PROVENANCE.md +94 -0
- package/readmeasset/omk-control.webp +0 -0
- package/readmeasset/omk-core-loop.svg +25 -0
- package/readmeasset/omk-evidence-gate-card.png +0 -0
- package/readmeasset/omk-github-banner.webp +0 -0
- package/readmeasset/omk-github-header.webp +0 -0
- package/readmeasset/omk-install-card.png +0 -0
- package/readmeasset/omk-logo-512.png +0 -0
- package/readmeasset/omk-logo-mark.svg +7 -0
- package/readmeasset/omk-provider-router-card.png +0 -0
- package/readmeasset/omk-runtime-flow-0.78.0.webp +0 -0
- package/readmeasset/omk-social-preview.png +0 -0
- package/readmeasset/omk-tui-0.78.0.webp +0 -0
- package/readmeasset/omk_tui.png +0 -0
- package/templates/.kimi/AGENTS.md +93 -0
- package/templates/.omk/agents/okabe.yaml +30 -0
- package/templates/.omk/agents/roles/aggregator.yaml +13 -0
- package/templates/.omk/agents/roles/architect.yaml +13 -0
- package/templates/.omk/agents/roles/coder.yaml +9 -0
- package/templates/.omk/agents/roles/explorer.yaml +13 -0
- package/templates/.omk/agents/roles/integrator.yaml +13 -0
- package/templates/.omk/agents/roles/interviewer.yaml +13 -0
- package/templates/.omk/agents/roles/ontology.yaml +18 -0
- package/templates/.omk/agents/roles/planner.yaml +13 -0
- package/templates/.omk/agents/roles/qa.yaml +12 -0
- package/templates/.omk/agents/roles/researcher.yaml +13 -0
- package/templates/.omk/agents/roles/reviewer.yaml +13 -0
- package/templates/.omk/agents/roles/router.yaml +13 -0
- package/templates/.omk/agents/roles/security.yaml +12 -0
- package/templates/.omk/agents/roles/tester.yaml +12 -0
- package/templates/.omk/agents/roles/vision-debugger.yaml +12 -0
- package/templates/.omk/agents/root.yaml +62 -0
- package/templates/.omk/lsp.json +27 -0
- package/templates/.omk/prompts/root.md +74 -0
- package/templates/AGENTS.md +510 -0
- package/templates/skills/agents/agentmemory/SKILL.md +40 -0
- package/templates/skills/agents/andrej-karpathy-skills/SKILL.md +41 -0
- package/templates/skills/agents/claude-for-legal/SKILL.md +63 -0
- package/templates/skills/agents/claude-for-legal/references/workflow-catalog.md +38 -0
- package/templates/skills/agents/matt-pocock-skills/SKILL.md +40 -0
- package/templates/skills/agents/multica/SKILL.md +40 -0
- package/templates/skills/agents/omk-adaptorch-orchestration-review/SKILL.md +52 -0
- package/templates/skills/agents/omk-backend-api-review/SKILL.md +30 -0
- package/templates/skills/agents/omk-code-review/SKILL.md +40 -0
- package/templates/skills/agents/omk-context-broker/SKILL.md +57 -0
- package/templates/skills/agents/omk-control-loop-debugger/SKILL.md +49 -0
- package/templates/skills/agents/omk-design-system/SKILL.md +22 -0
- package/templates/skills/agents/omk-docs-release/SKILL.md +42 -0
- package/templates/skills/agents/omk-evidence-contract/SKILL.md +52 -0
- package/templates/skills/agents/omk-frontend-implementation/SKILL.md +13 -0
- package/templates/skills/agents/omk-frontend-ui-review/SKILL.md +29 -0
- package/templates/skills/agents/omk-git-commit-pr/SKILL.md +45 -0
- package/templates/skills/agents/omk-industrial-control-loop/SKILL.md +33 -0
- package/templates/skills/agents/omk-plan-first/SKILL.md +39 -0
- package/templates/skills/agents/omk-project-rules/SKILL.md +46 -0
- package/templates/skills/agents/omk-python-typing/SKILL.md +33 -0
- package/templates/skills/agents/omk-quality-gate/SKILL.md +54 -0
- package/templates/skills/agents/omk-repo-explorer/SKILL.md +33 -0
- package/templates/skills/agents/omk-research-verify/SKILL.md +30 -0
- package/templates/skills/agents/omk-secret-guard/SKILL.md +23 -0
- package/templates/skills/agents/omk-security-review/SKILL.md +49 -0
- package/templates/skills/agents/omk-test-debug-loop/SKILL.md +43 -0
- package/templates/skills/agents/omk-troubleshooting/SKILL.md +14 -0
- package/templates/skills/agents/omk-typescript-strict/SKILL.md +38 -0
- package/templates/skills/agents/omk-worktree-team/SKILL.md +44 -0
- package/templates/skills/agents/react-doctor/SKILL.md +46 -0
- package/templates/skills/kimi/agentmemory/SKILL.md +40 -0
- package/templates/skills/kimi/andrej-karpathy-skills/SKILL.md +41 -0
- package/templates/skills/kimi/awesome-design-md/SKILL.md +54 -0
- package/templates/skills/kimi/claude-for-legal/SKILL.md +63 -0
- package/templates/skills/kimi/claude-for-legal/references/workflow-catalog.md +38 -0
- package/templates/skills/kimi/deepseek-api/SKILL.md +27 -0
- package/templates/skills/kimi/deepseek-disable/SKILL.md +20 -0
- package/templates/skills/kimi/deepseek-enable/SKILL.md +20 -0
- package/templates/skills/kimi/deepseekset/SKILL.md +27 -0
- package/templates/skills/kimi/graph-view/SKILL.md +29 -0
- package/templates/skills/kimi/matt-pocock-skills/SKILL.md +40 -0
- package/templates/skills/kimi/mcp-install/SKILL.md +66 -0
- package/templates/skills/kimi/multica/SKILL.md +40 -0
- package/templates/skills/kimi/omk-adaptorch-orchestration-review/SKILL.md +52 -0
- package/templates/skills/kimi/omk-backend-api-review/SKILL.md +30 -0
- package/templates/skills/kimi/omk-code-review/SKILL.md +34 -0
- package/templates/skills/kimi/omk-context-broker/SKILL.md +57 -0
- package/templates/skills/kimi/omk-control-loop-debugger/SKILL.md +49 -0
- package/templates/skills/kimi/omk-design-md/SKILL.md +55 -0
- package/templates/skills/kimi/omk-design-system/SKILL.md +22 -0
- package/templates/skills/kimi/omk-docs-release/SKILL.md +42 -0
- package/templates/skills/kimi/omk-evidence-contract/SKILL.md +52 -0
- package/templates/skills/kimi/omk-flow-bugfix/SKILL.md +20 -0
- package/templates/skills/kimi/omk-flow-design-to-code/SKILL.md +23 -0
- package/templates/skills/kimi/omk-flow-feature-dev/SKILL.md +24 -0
- package/templates/skills/kimi/omk-flow-pr-review/SKILL.md +17 -0
- package/templates/skills/kimi/omk-flow-refactor/SKILL.md +21 -0
- package/templates/skills/kimi/omk-flow-release/SKILL.md +20 -0
- package/templates/skills/kimi/omk-flow-team-run/SKILL.md +24 -0
- package/templates/skills/kimi/omk-frontend-implementation/SKILL.md +13 -0
- package/templates/skills/kimi/omk-frontend-ui-review/SKILL.md +29 -0
- package/templates/skills/kimi/omk-git-commit-pr/SKILL.md +45 -0
- package/templates/skills/kimi/omk-global-rules/SKILL.md +31 -0
- package/templates/skills/kimi/omk-industrial-control-loop/SKILL.md +33 -0
- package/templates/skills/kimi/omk-kimi-runtime/SKILL.md +46 -0
- package/templates/skills/kimi/omk-multimodal-ui-review/SKILL.md +26 -0
- package/templates/skills/kimi/omk-plan-first/SKILL.md +39 -0
- package/templates/skills/kimi/omk-project-rules/SKILL.md +21 -0
- package/templates/skills/kimi/omk-python-typing/SKILL.md +33 -0
- package/templates/skills/kimi/omk-quality-gate/SKILL.md +36 -0
- package/templates/skills/kimi/omk-repo-explorer/SKILL.md +33 -0
- package/templates/skills/kimi/omk-research-verify/SKILL.md +30 -0
- package/templates/skills/kimi/omk-secret-guard/SKILL.md +23 -0
- package/templates/skills/kimi/omk-security-review/SKILL.md +49 -0
- package/templates/skills/kimi/omk-task-router/SKILL.md +27 -0
- package/templates/skills/kimi/omk-test-debug-loop/SKILL.md +43 -0
- package/templates/skills/kimi/omk-typescript-strict/SKILL.md +38 -0
- package/templates/skills/kimi/omk-worktree-team/SKILL.md +44 -0
- package/templates/skills/kimi/open-design/SKILL.md +56 -0
- package/templates/skills/kimi/provider/SKILL.md +47 -0
- package/templates/skills/kimi/react-doctor/SKILL.md +46 -0
- package/templates/skills/kimi/speckit-analyze/SKILL.md +255 -0
- package/templates/skills/kimi/speckit-checklist/SKILL.md +367 -0
- package/templates/skills/kimi/speckit-clarify/SKILL.md +249 -0
- package/templates/skills/kimi/speckit-constitution/SKILL.md +152 -0
- package/templates/skills/kimi/speckit-implement/SKILL.md +204 -0
- package/templates/skills/kimi/speckit-plan/SKILL.md +147 -0
- package/templates/skills/kimi/speckit-specify/SKILL.md +325 -0
- package/templates/skills/kimi/speckit-tasks/SKILL.md +197 -0
- package/templates/skills/kimi/speckit-taskstoissues/SKILL.md +101 -0
- package/templates/skills/kimi/think/SKILL.md +41 -0
- package/templates/spec-kit-omk-preset/commands/plan.md +21 -0
- package/templates/spec-kit-omk-preset/commands/tasks.md +21 -0
- package/templates/spec-kit-omk-preset/preset.yml +12 -0
- package/templates/spec-kit-omk-preset/templates/plan-template.md +75 -0
- package/templates/spec-kit-omk-preset/templates/spec-template.md +80 -0
- package/templates/spec-kit-omk-preset/templates/tasks-template.md +160 -0
- package/templates/web-bridge/chrome-extension/README.md +18 -0
- package/templates/web-bridge/chrome-extension/background.js +57 -0
- package/templates/web-bridge/chrome-extension/content-script.js +46 -0
- package/templates/web-bridge/chrome-extension/manifest.json +16 -0
- package/templates/web-bridge/chrome-extension/popup.html +21 -0
- package/templates/web-bridge/chrome-extension/popup.js +9 -0
|
@@ -0,0 +1,2581 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { mkdir, writeFile, readFile, copyFile, readdir, stat, rename, symlink } from "fs/promises";
|
|
3
|
+
import { basename, join, dirname } from "path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { confirm, password } from "@inquirer/prompts";
|
|
6
|
+
import { ExitPromptError } from "@inquirer/core";
|
|
7
|
+
import { getProjectRoot, getUserHome, normalizeUserHomePath, pathExists } from "../util/fs.js";
|
|
8
|
+
import { getOmkVersionSync } from "../util/version.js";
|
|
9
|
+
import { style, header, status } from "../util/theme.js";
|
|
10
|
+
import { defaultLspConfigJson } from "../lsp/default-config.js";
|
|
11
|
+
import { t } from "../util/i18n.js";
|
|
12
|
+
import { maybeAskForGitHubStar } from "../util/first-run-star.js";
|
|
13
|
+
import { getDeepSeekProviderStatus, setDeepSeekApiKey } from "../providers/deepseek/deepseek-config.js";
|
|
14
|
+
import { OMK_CORE_VERIFIED_PRESET, OMK_RUNTIME_PRESETS } from "../runtime/core-verified-preset.js";
|
|
15
|
+
import { RECOMMENDED_MCP_SERVERS, getDefaultSelections, } from "../mcp/server-catalog.js";
|
|
16
|
+
import { mcpBulkInstallCommand } from "./mcp.js";
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = dirname(__filename);
|
|
19
|
+
const packageRoot = join(__dirname, "..", "..");
|
|
20
|
+
function createThemeJson() {
|
|
21
|
+
return JSON.stringify({
|
|
22
|
+
banner: {
|
|
23
|
+
title: "OMK://CONTROL",
|
|
24
|
+
subtitle: "Route agents. Verify evidence. Control the loop.",
|
|
25
|
+
style: "default",
|
|
26
|
+
enabled: true,
|
|
27
|
+
},
|
|
28
|
+
colors: {
|
|
29
|
+
primary: "#00D6FF",
|
|
30
|
+
accent: "#FF47B2",
|
|
31
|
+
success: "#00FFC2",
|
|
32
|
+
warning: "#FFB000",
|
|
33
|
+
danger: "#FF5874",
|
|
34
|
+
info: "#9D4EDD",
|
|
35
|
+
muted: "#758FA8",
|
|
36
|
+
},
|
|
37
|
+
metaBox: true,
|
|
38
|
+
}, null, 2) + "\n";
|
|
39
|
+
}
|
|
40
|
+
function createRuntimePresetsJson() {
|
|
41
|
+
return JSON.stringify({
|
|
42
|
+
defaultPresetId: OMK_CORE_VERIFIED_PRESET.id,
|
|
43
|
+
presets: OMK_RUNTIME_PRESETS,
|
|
44
|
+
}, null, 2) + "\n";
|
|
45
|
+
}
|
|
46
|
+
const OKABE_AGENT_YAML = `version: 1
|
|
47
|
+
agent:
|
|
48
|
+
extend: default
|
|
49
|
+
name: omk-okabe-base
|
|
50
|
+
# Provider adapters may require an explicit non-empty tools list for custom --agent-file configs.
|
|
51
|
+
# Keep the full OMK native tool surface, including Agent for parallel subagents
|
|
52
|
+
# and SendDMail for Okabe checkpoints; MCP/skills/hooks are injected by runtime config.
|
|
53
|
+
tools:
|
|
54
|
+
- "kimi_cli.tools.agent:Agent"
|
|
55
|
+
- "kimi_cli.tools.ask_user:AskUserQuestion"
|
|
56
|
+
- "kimi_cli.tools.todo:SetTodoList"
|
|
57
|
+
- "kimi_cli.tools.shell:Shell"
|
|
58
|
+
- "kimi_cli.tools.file:ReadFile"
|
|
59
|
+
- "kimi_cli.tools.file:ReadMediaFile"
|
|
60
|
+
- "kimi_cli.tools.file:Glob"
|
|
61
|
+
- "kimi_cli.tools.file:Grep"
|
|
62
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
63
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
64
|
+
- "kimi_cli.tools.web:SearchWeb"
|
|
65
|
+
- "kimi_cli.tools.web:FetchURL"
|
|
66
|
+
- "kimi_cli.tools.plan.enter:EnterPlanMode"
|
|
67
|
+
- "kimi_cli.tools.plan:ExitPlanMode"
|
|
68
|
+
- "kimi_cli.tools.background:TaskList"
|
|
69
|
+
- "kimi_cli.tools.background:TaskOutput"
|
|
70
|
+
- "kimi_cli.tools.background:TaskStop"
|
|
71
|
+
- "kimi_cli.tools.dmail:SendDMail"
|
|
72
|
+
system_prompt_args:
|
|
73
|
+
OMK_MCP_ENABLED: "true"
|
|
74
|
+
OMK_SKILLS_ENABLED: "true"
|
|
75
|
+
OMK_HOOKS_ENABLED: "true"
|
|
76
|
+
`;
|
|
77
|
+
const ROOT_AGENT_YAML = `version: 1
|
|
78
|
+
agent:
|
|
79
|
+
extend: ./okabe.yaml # Inherits the OMK provider-adapter tool surface plus MCP/skills/hooks flags
|
|
80
|
+
name: omk-root
|
|
81
|
+
system_prompt_path: ../prompts/root.md
|
|
82
|
+
system_prompt_args:
|
|
83
|
+
OMK_ROLE: "root-coordinator"
|
|
84
|
+
OMK_MCP_ENABLED: "true"
|
|
85
|
+
OMK_SKILLS_ENABLED: "true"
|
|
86
|
+
OMK_HOOKS_ENABLED: "true"
|
|
87
|
+
subagents:
|
|
88
|
+
explorer:
|
|
89
|
+
path: ./roles/explorer.yaml
|
|
90
|
+
description: "Read-only repository exploration and context mapping with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
91
|
+
explore:
|
|
92
|
+
path: ./roles/explorer.yaml
|
|
93
|
+
description: "Alias for explorer; kept for compatibility with older OMK instructions"
|
|
94
|
+
planner:
|
|
95
|
+
path: ./roles/planner.yaml
|
|
96
|
+
description: "Architecture, refactor, migration, and implementation planning with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
97
|
+
plan:
|
|
98
|
+
path: ./roles/planner.yaml
|
|
99
|
+
description: "Alias for planner; kept for compatibility with older OMK instructions"
|
|
100
|
+
router:
|
|
101
|
+
path: ./roles/router.yaml
|
|
102
|
+
description: "Task routing, skill/MCP/hook fit, context budgeting, and parallel/sequential lane decisions with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
103
|
+
architect:
|
|
104
|
+
path: ./roles/architect.yaml
|
|
105
|
+
description: "Read-only architecture and migration design with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
106
|
+
coder:
|
|
107
|
+
path: ./roles/coder.yaml
|
|
108
|
+
description: "Scoped implementation in the current project with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
109
|
+
reviewer:
|
|
110
|
+
path: ./roles/reviewer.yaml
|
|
111
|
+
description: "Adversarial code review and risk detection with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
112
|
+
security:
|
|
113
|
+
path: ./roles/security.yaml
|
|
114
|
+
description: "Security, secret, permission, and trust-boundary review with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
115
|
+
qa:
|
|
116
|
+
path: ./roles/qa.yaml
|
|
117
|
+
description: "Run and analyze lint, typecheck, test, and build results with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
118
|
+
tester:
|
|
119
|
+
path: ./roles/tester.yaml
|
|
120
|
+
description: "Focused regression and edge-case testing with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
121
|
+
researcher:
|
|
122
|
+
path: ./roles/researcher.yaml
|
|
123
|
+
description: "Reference-backed research and external documentation checks with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
124
|
+
integrator:
|
|
125
|
+
path: ./roles/integrator.yaml
|
|
126
|
+
description: "Merge coordination and final synthesis with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
127
|
+
aggregator:
|
|
128
|
+
path: ./roles/aggregator.yaml
|
|
129
|
+
description: "Parallel-lane result aggregation with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
130
|
+
interviewer:
|
|
131
|
+
path: ./roles/interviewer.yaml
|
|
132
|
+
description: "Requirement clarification and acceptance criteria discovery with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
133
|
+
ontology:
|
|
134
|
+
path: ./roles/ontology.yaml
|
|
135
|
+
description: "Project graph memory and ontology curation with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
136
|
+
vision-debugger:
|
|
137
|
+
path: ./roles/vision-debugger.yaml
|
|
138
|
+
description: "Screenshot and multimodal debugging with scoped MCP, skills, and hooks access when enabled by runtime scope"
|
|
139
|
+
`;
|
|
140
|
+
const ROLE_YAMLS = {
|
|
141
|
+
interviewer: `version: 1
|
|
142
|
+
agent:
|
|
143
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
144
|
+
name: omk-interviewer
|
|
145
|
+
system_prompt_args:
|
|
146
|
+
OMK_ROLE: "interviewer"
|
|
147
|
+
OMK_MCP_ENABLED: "true"
|
|
148
|
+
OMK_SKILLS_ENABLED: "true"
|
|
149
|
+
OMK_HOOKS_ENABLED: "true"
|
|
150
|
+
exclude_tools:
|
|
151
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
152
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
153
|
+
- "kimi_cli.tools.shell:Shell"
|
|
154
|
+
`,
|
|
155
|
+
architect: `version: 1
|
|
156
|
+
agent:
|
|
157
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
158
|
+
name: omk-architect
|
|
159
|
+
system_prompt_args:
|
|
160
|
+
OMK_ROLE: "architect"
|
|
161
|
+
OMK_MCP_ENABLED: "true"
|
|
162
|
+
OMK_SKILLS_ENABLED: "true"
|
|
163
|
+
OMK_HOOKS_ENABLED: "true"
|
|
164
|
+
exclude_tools:
|
|
165
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
166
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
167
|
+
- "kimi_cli.tools.shell:Shell"
|
|
168
|
+
`,
|
|
169
|
+
planner: `version: 1
|
|
170
|
+
agent:
|
|
171
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
172
|
+
name: omk-planner
|
|
173
|
+
system_prompt_args:
|
|
174
|
+
OMK_ROLE: "planner"
|
|
175
|
+
OMK_MCP_ENABLED: "true"
|
|
176
|
+
OMK_SKILLS_ENABLED: "true"
|
|
177
|
+
OMK_HOOKS_ENABLED: "true"
|
|
178
|
+
exclude_tools:
|
|
179
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
180
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
181
|
+
- "kimi_cli.tools.shell:Shell"
|
|
182
|
+
`,
|
|
183
|
+
router: `version: 1
|
|
184
|
+
agent:
|
|
185
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
186
|
+
name: omk-router
|
|
187
|
+
system_prompt_args:
|
|
188
|
+
OMK_ROLE: "router"
|
|
189
|
+
OMK_MCP_ENABLED: "true"
|
|
190
|
+
OMK_SKILLS_ENABLED: "true"
|
|
191
|
+
OMK_HOOKS_ENABLED: "true"
|
|
192
|
+
exclude_tools:
|
|
193
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
194
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
195
|
+
- "kimi_cli.tools.shell:Shell"
|
|
196
|
+
`,
|
|
197
|
+
explorer: `version: 1
|
|
198
|
+
agent:
|
|
199
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
200
|
+
name: omk-explorer
|
|
201
|
+
system_prompt_args:
|
|
202
|
+
OMK_ROLE: "explorer"
|
|
203
|
+
OMK_MCP_ENABLED: "true"
|
|
204
|
+
OMK_SKILLS_ENABLED: "true"
|
|
205
|
+
OMK_HOOKS_ENABLED: "true"
|
|
206
|
+
exclude_tools:
|
|
207
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
208
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
209
|
+
- "kimi_cli.tools.shell:Shell"
|
|
210
|
+
`,
|
|
211
|
+
coder: `version: 1
|
|
212
|
+
agent:
|
|
213
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
214
|
+
name: omk-coder
|
|
215
|
+
system_prompt_args:
|
|
216
|
+
OMK_ROLE: "coder"
|
|
217
|
+
OMK_MCP_ENABLED: "true"
|
|
218
|
+
OMK_SKILLS_ENABLED: "true"
|
|
219
|
+
OMK_HOOKS_ENABLED: "true"
|
|
220
|
+
`,
|
|
221
|
+
reviewer: `version: 1
|
|
222
|
+
agent:
|
|
223
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
224
|
+
name: omk-reviewer
|
|
225
|
+
system_prompt_args:
|
|
226
|
+
OMK_ROLE: "reviewer"
|
|
227
|
+
OMK_MCP_ENABLED: "true"
|
|
228
|
+
OMK_SKILLS_ENABLED: "true"
|
|
229
|
+
OMK_HOOKS_ENABLED: "true"
|
|
230
|
+
exclude_tools:
|
|
231
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
232
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
233
|
+
- "kimi_cli.tools.shell:Shell"
|
|
234
|
+
`,
|
|
235
|
+
security: `version: 1
|
|
236
|
+
agent:
|
|
237
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
238
|
+
name: omk-security
|
|
239
|
+
system_prompt_args:
|
|
240
|
+
OMK_ROLE: "security"
|
|
241
|
+
OMK_MCP_ENABLED: "true"
|
|
242
|
+
OMK_SKILLS_ENABLED: "true"
|
|
243
|
+
OMK_HOOKS_ENABLED: "true"
|
|
244
|
+
exclude_tools:
|
|
245
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
246
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
247
|
+
`,
|
|
248
|
+
qa: `version: 1
|
|
249
|
+
agent:
|
|
250
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
251
|
+
name: omk-qa
|
|
252
|
+
system_prompt_args:
|
|
253
|
+
OMK_ROLE: "qa"
|
|
254
|
+
OMK_MCP_ENABLED: "true"
|
|
255
|
+
OMK_SKILLS_ENABLED: "true"
|
|
256
|
+
OMK_HOOKS_ENABLED: "true"
|
|
257
|
+
exclude_tools:
|
|
258
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
259
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
260
|
+
`,
|
|
261
|
+
tester: `version: 1
|
|
262
|
+
agent:
|
|
263
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
264
|
+
name: omk-tester
|
|
265
|
+
system_prompt_args:
|
|
266
|
+
OMK_ROLE: "tester"
|
|
267
|
+
OMK_MCP_ENABLED: "true"
|
|
268
|
+
OMK_SKILLS_ENABLED: "true"
|
|
269
|
+
OMK_HOOKS_ENABLED: "true"
|
|
270
|
+
exclude_tools:
|
|
271
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
272
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
273
|
+
`,
|
|
274
|
+
integrator: `version: 1
|
|
275
|
+
agent:
|
|
276
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
277
|
+
name: omk-integrator
|
|
278
|
+
system_prompt_args:
|
|
279
|
+
OMK_ROLE: "integrator"
|
|
280
|
+
OMK_MCP_ENABLED: "true"
|
|
281
|
+
OMK_SKILLS_ENABLED: "true"
|
|
282
|
+
OMK_HOOKS_ENABLED: "true"
|
|
283
|
+
exclude_tools:
|
|
284
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
285
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
286
|
+
- "kimi_cli.tools.shell:Shell"
|
|
287
|
+
`,
|
|
288
|
+
aggregator: `version: 1
|
|
289
|
+
agent:
|
|
290
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
291
|
+
name: omk-aggregator
|
|
292
|
+
system_prompt_args:
|
|
293
|
+
OMK_ROLE: "aggregator"
|
|
294
|
+
OMK_MCP_ENABLED: "true"
|
|
295
|
+
OMK_SKILLS_ENABLED: "true"
|
|
296
|
+
OMK_HOOKS_ENABLED: "true"
|
|
297
|
+
exclude_tools:
|
|
298
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
299
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
300
|
+
- "kimi_cli.tools.shell:Shell"
|
|
301
|
+
`,
|
|
302
|
+
researcher: `version: 1
|
|
303
|
+
agent:
|
|
304
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
305
|
+
name: omk-researcher
|
|
306
|
+
system_prompt_args:
|
|
307
|
+
OMK_ROLE: "researcher"
|
|
308
|
+
OMK_MCP_ENABLED: "true"
|
|
309
|
+
OMK_SKILLS_ENABLED: "true"
|
|
310
|
+
OMK_HOOKS_ENABLED: "true"
|
|
311
|
+
exclude_tools:
|
|
312
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
313
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
314
|
+
- "kimi_cli.tools.shell:Shell"
|
|
315
|
+
`,
|
|
316
|
+
ontology: `version: 1
|
|
317
|
+
agent:
|
|
318
|
+
extend: ../okabe.yaml
|
|
319
|
+
name: omk-ontology
|
|
320
|
+
system_prompt_args:
|
|
321
|
+
OMK_ROLE: "ontology"
|
|
322
|
+
OMK_MCP_ENABLED: "true"
|
|
323
|
+
OMK_SKILLS_ENABLED: "true"
|
|
324
|
+
OMK_HOOKS_ENABLED: "true"
|
|
325
|
+
exclude_tools:
|
|
326
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
327
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
328
|
+
- "kimi_cli.tools.shell:Shell"
|
|
329
|
+
`,
|
|
330
|
+
"vision-debugger": `version: 1
|
|
331
|
+
agent:
|
|
332
|
+
extend: ../okabe.yaml # Inherits unrestricted default Kimi tools plus MCP/skills/hooks flags
|
|
333
|
+
name: omk-vision-debugger
|
|
334
|
+
system_prompt_args:
|
|
335
|
+
OMK_ROLE: "vision-debugger"
|
|
336
|
+
OMK_MCP_ENABLED: "true"
|
|
337
|
+
OMK_SKILLS_ENABLED: "true"
|
|
338
|
+
OMK_HOOKS_ENABLED: "true"
|
|
339
|
+
exclude_tools:
|
|
340
|
+
- "kimi_cli.tools.file:WriteFile"
|
|
341
|
+
- "kimi_cli.tools.file:StrReplaceFile"
|
|
342
|
+
`,
|
|
343
|
+
};
|
|
344
|
+
function getDesignMd(version) {
|
|
345
|
+
return `---
|
|
346
|
+
title: "Design System"
|
|
347
|
+
description: "Project visual identity and design system"
|
|
348
|
+
version: "${version}"
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
# DESIGN.md
|
|
352
|
+
|
|
353
|
+
## Overview
|
|
354
|
+
|
|
355
|
+
Project visual identity and design system.
|
|
356
|
+
|
|
357
|
+
## Colors
|
|
358
|
+
|
|
359
|
+
- Primary: #111827
|
|
360
|
+
- Accent: #7C3AED
|
|
361
|
+
- Success: #059669
|
|
362
|
+
- Warning: #D97706
|
|
363
|
+
- Danger: #DC2626
|
|
364
|
+
|
|
365
|
+
## Typography
|
|
366
|
+
|
|
367
|
+
- Inter, system-ui
|
|
368
|
+
|
|
369
|
+
## Rules
|
|
370
|
+
|
|
371
|
+
- Use tokens before inventing new values.
|
|
372
|
+
- Keep components compact and status-aware.
|
|
373
|
+
`;
|
|
374
|
+
}
|
|
375
|
+
const GEMINI_MD = `# GEMINI.md
|
|
376
|
+
|
|
377
|
+
@./AGENTS.md
|
|
378
|
+
@./DESIGN.md
|
|
379
|
+
|
|
380
|
+
Use AGENTS.md as the canonical project instruction source, including current OMK skills, MCP, agents, and harness policy.
|
|
381
|
+
Use DESIGN.md as the canonical visual identity source.
|
|
382
|
+
Do not duplicate runtime inventories; follow AGENTS.md and \`chat-agent-harness.json\` when present.
|
|
383
|
+
`;
|
|
384
|
+
const CLAUDE_MD = `# CLAUDE.md
|
|
385
|
+
|
|
386
|
+
@./AGENTS.md
|
|
387
|
+
@./DESIGN.md
|
|
388
|
+
|
|
389
|
+
Use AGENTS.md as the canonical project instruction source, including current OMK skills, MCP, agents, and harness policy.
|
|
390
|
+
Use DESIGN.md for UI/frontend work.
|
|
391
|
+
Do not duplicate runtime inventories; follow AGENTS.md and \`chat-agent-harness.json\` when present.
|
|
392
|
+
`;
|
|
393
|
+
const ROADMAP_MD = `# Roadmap
|
|
394
|
+
|
|
395
|
+
Current source version: v1.1.17
|
|
396
|
+
Last updated: 2026-05-18
|
|
397
|
+
|
|
398
|
+
## v1.1.9 reality
|
|
399
|
+
|
|
400
|
+
Provider routing and graph viewing are no longer purely future work:
|
|
401
|
+
|
|
402
|
+
- \`omk run\`, \`omk parallel\`, and DAG replay expose \`--provider auto|kimi\`.
|
|
403
|
+
- \`omk provider\` / \`omk deepseek\` manage DeepSeek enablement, key setup, availability checks, and configured authority fallback.
|
|
404
|
+
- DeepSeek is an opportunistic read-only/advisory worker; the configured authority provider remains the orchestrator, writer, merger, and final authority.
|
|
405
|
+
- \`omk graph view\` generates an HTML view from \`.omk/memory/graph-state.json\`.
|
|
406
|
+
- \`omk goal\` has a persisted lifecycle, continue loop, generated plan/evidence criteria, and verification flow.
|
|
407
|
+
|
|
408
|
+
## v1.2 — Hardening the current surface
|
|
409
|
+
|
|
410
|
+
### P0: release and contract gates
|
|
411
|
+
|
|
412
|
+
- Done: YAML validation now runs in local \`verify\` plus CI/smoke workflows.
|
|
413
|
+
- Done: package dry-pack, package audit, tarball smoke, native safety build, and release matrix gates were re-verified against v1.1.17 artifacts.
|
|
414
|
+
- Done: provider/deepseek and screenshot JSON command contracts gained hermetic regression tests.
|
|
415
|
+
- Done: current AGENTS/init templates and packaged workflow skills were aligned with the active skills/MCP/agents/harness surface, including all generated agent MCP/skills/hooks flags and parallel subagent orchestration guidance.
|
|
416
|
+
- Remaining: lock broader provider fallback metadata with tests for rate limit, timeout, and Kimi fallback variants.
|
|
417
|
+
- Remaining: define minimum machine-readable CLI envelopes for the rest of the automation-critical commands.
|
|
418
|
+
|
|
419
|
+
### P1: observability and diagnostics
|
|
420
|
+
|
|
421
|
+
- Done: provider route/fallback counts are now emitted in run summaries/reports and summary terminal output.
|
|
422
|
+
- Done: invalid MCP JSON is reported as a visible diagnostic without leaking secret-like config values.
|
|
423
|
+
- Done: \`omk mcp doctor --json\` exposes structured server status, command resolution, timeout, permission, and config-source fields.
|
|
424
|
+
- Expand JSON output for graph, DAG, summary, and workflow commands where CI or agents consume results.
|
|
425
|
+
- Link graph nodes back to runs, goals, providers, and evidence so \`omk graph view\` becomes audit evidence, not only visualization.
|
|
426
|
+
|
|
427
|
+
### P2: execution depth and planner quality
|
|
428
|
+
|
|
429
|
+
- Deepen \`omk team\` runtime reporting: worker state, pane/session health, artifacts, and verification handoff.
|
|
430
|
+
- Done: replace the \`omk goal plan\` stub with a planner that emits steps, acceptance criteria, risks, and evidence gates.
|
|
431
|
+
- Add provider-quality gates before broader non-Kimi worker pools.
|
|
432
|
+
- Keep Kimi-only execution as the safe fallback path for every run.
|
|
433
|
+
|
|
434
|
+
## Later tracks
|
|
435
|
+
|
|
436
|
+
### Provider routing maturity
|
|
437
|
+
|
|
438
|
+
- Keep Kimi as the main orchestrator, planner, merger, and final synthesis runtime.
|
|
439
|
+
- Use provider hints for explorer, reviewer, QA, planner, and documentation roles only when preflight is healthy and task risk is low.
|
|
440
|
+
- Record provider attempts, route confidence, fallback reason, and final authority in run evidence.
|
|
441
|
+
|
|
442
|
+
### Graph and memory maturity
|
|
443
|
+
|
|
444
|
+
- Materialize provider routes, fallback events, goals, evidence gates, and run artifacts in the local graph/Kuzu ontology.
|
|
445
|
+
- Keep \`omk graph view\` local-first and safe for private repositories.
|
|
446
|
+
|
|
447
|
+
### Historical milestones
|
|
448
|
+
|
|
449
|
+
| Version | Focus |
|
|
450
|
+
|---------|-------|
|
|
451
|
+
| v0.1 | init / doctor / chat, P0 skills, AGENTS.md / DESIGN.md generation, quality gate hooks |
|
|
452
|
+
| v0.2 | wire controller, HUD, run state, worker logs |
|
|
453
|
+
| v0.3 | worktree team, merge queue, reviewer / QA / integrator agents |
|
|
454
|
+
| v0.4 | Google DESIGN.md integration, Stitch skills installer, screenshot UI review, Spec Kit planning + DAG execution, agent registry, project index, run summary |
|
|
455
|
+
| v0.5 | MCP project server, plugin pack, CI agent mode |
|
|
456
|
+
| v1.1.6 | provider/deepseek commands, provider policy flags, graph view, goal lifecycle, expanded run history and update JSON |
|
|
457
|
+
| v1.1.9 | chat harness manifest, capability DAG lanes, Rust native safety loader, Windows clipboard screenshot bridge, release native matrix |
|
|
458
|
+
| v1.1.12 | Replay system, skill assigner, decision trace coverage, evidence gates, and repair policy |
|
|
459
|
+
| v1.1.13 | Bundled MCP server entrypoints, ACP/host transport groundwork, deployment-ready package metadata |
|
|
460
|
+
| v1.1.14 | Current harness docs, external-inspired workflow skills, and release-safe public wording |
|
|
461
|
+
| v1.1.15 | Isolated HOME MCP shell-profile hotfix and persistent fetch MCP entrypoint |
|
|
462
|
+
| v1.1.16 | Deterministic IntentFrame/ActionAtom orchestration, chat schema preflight, MCP duplicate policy, agent capability propagation, and doctor/init/pack smoke fixes |
|
|
463
|
+
| v1.1.17 | Full generated-agent MCP/skills/hooks enablement, parallel subagent orchestration emphasis, and v1.1.17 release docs |
|
|
464
|
+
`;
|
|
465
|
+
const SECURITY_MD = `# Security Policy
|
|
466
|
+
|
|
467
|
+
## Reporting Vulnerabilities
|
|
468
|
+
|
|
469
|
+
Please report security issues via GitHub Issues with the \`security\` label.
|
|
470
|
+
|
|
471
|
+
## Built-in Protections
|
|
472
|
+
|
|
473
|
+
open-multi-agent-kit includes default hooks to block destructive commands and secret leakage.
|
|
474
|
+
|
|
475
|
+
## MCP and Harness Secret Handling
|
|
476
|
+
|
|
477
|
+
- Fresh init writes project-local \`omk-project\` MCP only; user/global MCP and skills are runtime-only unless explicitly imported by a trusted local user.
|
|
478
|
+
- Never print, commit, or summarize MCP \`env\`, headers, tokens, or provider keys.
|
|
479
|
+
- Treat \`chat-agent-harness.json\` as private run metadata: use it for inventory/gates, but do not paste large inventories or secret-like values into prompts, memory, or reports.
|
|
480
|
+
- Prefer sanitized \`omk mcp doctor --json\`, \`omk verify --json\`, test summaries, and secret scans as shareable evidence.
|
|
481
|
+
|
|
482
|
+
## Best Practices
|
|
483
|
+
|
|
484
|
+
- Review hooks before running in production repositories.
|
|
485
|
+
- Use \`--print\` mode only in disposable worktrees.
|
|
486
|
+
- Never commit secrets into agent memory files.
|
|
487
|
+
`;
|
|
488
|
+
const ROOT_PROMPT_MD = `# OMK Root Agent
|
|
489
|
+
|
|
490
|
+
You are the OMK root orchestrator for open-multi-agent-kit — a provider-neutral orchestration control plane that turns a goal into a bounded coding team.
|
|
491
|
+
|
|
492
|
+
Models execute. OMK routes, verifies, measures, and controls.
|
|
493
|
+
|
|
494
|
+
You must operate with OMK identity as the authority layer: summon parallel subagents when scopes are independent, assign each lane scoped MCP, skills, and hooks, and keep the root context focused on goal management, integration, evidence, and verification. The active runtime scope, selected provider adapter, and harness policy decide which resources are actually available.
|
|
495
|
+
|
|
496
|
+
## Loaded Project Instructions
|
|
497
|
+
|
|
498
|
+
\${KIMI_AGENTS_MD}
|
|
499
|
+
|
|
500
|
+
## Loaded Skills
|
|
501
|
+
|
|
502
|
+
\${KIMI_SKILLS}
|
|
503
|
+
|
|
504
|
+
## Global Rules
|
|
505
|
+
|
|
506
|
+
- Apply AGENTS.md silently.
|
|
507
|
+
- Do not repeat boilerplate.
|
|
508
|
+
- Use SetTodoList for multi-step tasks.
|
|
509
|
+
- Use Agent tool for non-trivial tasks. All 15 role agents (explorer, planner, router, architect, coder, reviewer, security, qa, tester, researcher, integrator, aggregator, interviewer, ontology, vision-debugger) are available with MCP, skills, and hooks capability flags.
|
|
510
|
+
- Use skills when relevant.
|
|
511
|
+
- Use MCP tools when configured and useful. All subagents inherit scoped MCP server inventory, skills, and hooks when enabled by runtime scope. Do not hesitate to invoke available capabilities.
|
|
512
|
+
- Treat project-local ontology graph memory as mandatory when the omk-project MCP exposes memory tools.
|
|
513
|
+
- Recall relevant project memory before work, write durable findings through omk_write_memory, and use omk_memory_mindmap/omk_graph_query for graph recall.
|
|
514
|
+
- Prefer plan-first execution.
|
|
515
|
+
- Prefer small, reviewable diffs.
|
|
516
|
+
- Verify before completion.
|
|
517
|
+
- Never claim tests passed unless they were run.
|
|
518
|
+
|
|
519
|
+
## Active Harness and Resource Inventory
|
|
520
|
+
|
|
521
|
+
- If a run contains chat-agent-harness.json, read it for the full MCP/skills/hooks inventory, virtual DAG, authority boundaries, worker limits, and gate list.
|
|
522
|
+
- Treat compact prompt resource counts as summaries only.
|
|
523
|
+
- Default runtime scope is project MCP/skills; all-scope may read user ~/.kimi resources at runtime without copying personal files.
|
|
524
|
+
- Do not paste huge global MCP/skill inventories or secret-bearing env/header values into prompts, memory, or final reports.
|
|
525
|
+
|
|
526
|
+
## OMK Context Tools
|
|
527
|
+
|
|
528
|
+
- Root and generated role agents inherit an Okabe-compatible base that keeps the default Kimi tool surface unrestricted while enabling scoped MCP, skills, and hooks.
|
|
529
|
+
- Use D-Mail before risky refactors, compaction, or long-running branch points: send a concise future-facing recovery note to the relevant checkpoint.
|
|
530
|
+
- Use Kimi subagents for isolated context and parallel work; keep the root context focused on decisions, integration, and verification.
|
|
531
|
+
- Prefer /compact or a D-Mail recovery note over dumping large history back into the prompt.
|
|
532
|
+
|
|
533
|
+
## Required Workflow
|
|
534
|
+
|
|
535
|
+
For non-trivial tasks:
|
|
536
|
+
|
|
537
|
+
1. Read project instructions.
|
|
538
|
+
2. Create todos.
|
|
539
|
+
3. Launch appropriate subagents in parallel when their scopes are independent:
|
|
540
|
+
- explorer for repository discovery
|
|
541
|
+
- planner for architecture/refactor/risky work
|
|
542
|
+
- coder for implementation
|
|
543
|
+
- reviewer or qa for review and gate analysis
|
|
544
|
+
- security for secret/permission/trust-boundary review
|
|
545
|
+
- ontology for graph memory and project knowledge curation
|
|
546
|
+
4. Read relevant skills.
|
|
547
|
+
5. Use MCP if useful.
|
|
548
|
+
6. Implement minimal changes.
|
|
549
|
+
7. Run quality gates.
|
|
550
|
+
8. Review final diff.
|
|
551
|
+
9. Return factual final report.
|
|
552
|
+
|
|
553
|
+
## Final Report Format
|
|
554
|
+
|
|
555
|
+
\`\`\`txt
|
|
556
|
+
Changed:
|
|
557
|
+
Files:
|
|
558
|
+
Commands:
|
|
559
|
+
Result:
|
|
560
|
+
Risk:
|
|
561
|
+
\`\`\`
|
|
562
|
+
`;
|
|
563
|
+
function hasErrorCode(error, code) {
|
|
564
|
+
return (typeof error === "object" &&
|
|
565
|
+
error !== null &&
|
|
566
|
+
"code" in error &&
|
|
567
|
+
error.code === code);
|
|
568
|
+
}
|
|
569
|
+
async function readTemplateFile(relativePath, fallback) {
|
|
570
|
+
try {
|
|
571
|
+
return await readFile(join(packageRoot, "templates", relativePath), "utf8");
|
|
572
|
+
}
|
|
573
|
+
catch {
|
|
574
|
+
return fallback;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
async function getCopyEntryKind(srcPath, entry) {
|
|
578
|
+
if (entry.isDirectory())
|
|
579
|
+
return "directory";
|
|
580
|
+
if (entry.isFile())
|
|
581
|
+
return "file";
|
|
582
|
+
if (!entry.isSymbolicLink())
|
|
583
|
+
return null;
|
|
584
|
+
try {
|
|
585
|
+
const targetStats = await stat(srcPath);
|
|
586
|
+
if (targetStats.isDirectory())
|
|
587
|
+
return "directory";
|
|
588
|
+
if (targetStats.isFile())
|
|
589
|
+
return "file";
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
if (hasErrorCode(error, "ENOENT"))
|
|
594
|
+
return null;
|
|
595
|
+
throw error;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
const SKILL_COPY_IGNORED_NAMES = new Set([
|
|
599
|
+
".git",
|
|
600
|
+
".hg",
|
|
601
|
+
".svn",
|
|
602
|
+
".DS_Store",
|
|
603
|
+
"node_modules",
|
|
604
|
+
"dist",
|
|
605
|
+
"build",
|
|
606
|
+
"coverage",
|
|
607
|
+
".venv",
|
|
608
|
+
"venv",
|
|
609
|
+
"__pycache__",
|
|
610
|
+
".pytest_cache",
|
|
611
|
+
".mypy_cache",
|
|
612
|
+
".ruff_cache",
|
|
613
|
+
]);
|
|
614
|
+
const PROTECTED_SKILL_FILE_PATTERNS = [
|
|
615
|
+
/^\.env(?:\..*)?$/i,
|
|
616
|
+
/^\.npmrc$/i,
|
|
617
|
+
/^\.pypirc$/i,
|
|
618
|
+
/^\.netrc$/i,
|
|
619
|
+
/\.pem$/i,
|
|
620
|
+
/\.key$/i,
|
|
621
|
+
/\.p8$/i,
|
|
622
|
+
/\.p12$/i,
|
|
623
|
+
/\.pfx$/i,
|
|
624
|
+
/^id_rsa$/i,
|
|
625
|
+
/^id_ed25519$/i,
|
|
626
|
+
/^credentials\.json$/i,
|
|
627
|
+
/^service-account.*\.json$/i,
|
|
628
|
+
];
|
|
629
|
+
const SKILL_SECRET_LITERAL_PATTERNS = [
|
|
630
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY-----/,
|
|
631
|
+
/AKIA[0-9A-Z]{16}/,
|
|
632
|
+
/gh[pousr]_[A-Za-z0-9_]{20,}/,
|
|
633
|
+
/glpat-[A-Za-z0-9\-_]{20,}/,
|
|
634
|
+
/\bsk-[A-Za-z0-9]{20,}\b/,
|
|
635
|
+
/\bfc-[A-Za-z0-9_-]{20,}\b/,
|
|
636
|
+
/\b(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{16,}\b/,
|
|
637
|
+
/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/,
|
|
638
|
+
];
|
|
639
|
+
const GENERIC_SKILL_SECRET_ASSIGNMENT = /\b(api[_-]?key|secret|token|password|private[_-]?key)\b\s*[:=]\s*["']?([^"'\s;,]{20,})/i;
|
|
640
|
+
const GENERIC_SKILL_SECRET_ALLOWLIST = /\$\{|<|YOUR_|REPLACE_|NPM_TOKEN|GITHUB_TOKEN|NODE_AUTH_TOKEN|process\.env|env\.|placeholder|example|sample|redacted|\*\*\*|Do not store secrets|Do not send secrets|secret leakage|secret leak/i;
|
|
641
|
+
function shouldSkipSkillCopyEntry(_srcPath, entry) {
|
|
642
|
+
return SKILL_COPY_IGNORED_NAMES.has(entry.name);
|
|
643
|
+
}
|
|
644
|
+
function isProtectedSkillFileName(filePath) {
|
|
645
|
+
const name = basename(filePath);
|
|
646
|
+
return PROTECTED_SKILL_FILE_PATTERNS.some((pattern) => pattern.test(name));
|
|
647
|
+
}
|
|
648
|
+
function isLikelyBinaryContent(buffer) {
|
|
649
|
+
return buffer.includes(0);
|
|
650
|
+
}
|
|
651
|
+
function hasSecretLikeSkillLine(line) {
|
|
652
|
+
if (SKILL_SECRET_LITERAL_PATTERNS.some((pattern) => pattern.test(line)))
|
|
653
|
+
return true;
|
|
654
|
+
return GENERIC_SKILL_SECRET_ASSIGNMENT.test(line) && !GENERIC_SKILL_SECRET_ALLOWLIST.test(line);
|
|
655
|
+
}
|
|
656
|
+
async function skillDirectoryHasSecretContent(dir) {
|
|
657
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
658
|
+
for (const entry of entries) {
|
|
659
|
+
const srcPath = join(dir, entry.name);
|
|
660
|
+
if (shouldSkipSkillCopyEntry(srcPath, entry))
|
|
661
|
+
continue;
|
|
662
|
+
if (isProtectedSkillFileName(srcPath))
|
|
663
|
+
return true;
|
|
664
|
+
const kind = await getCopyEntryKind(srcPath, entry);
|
|
665
|
+
if (kind === "directory") {
|
|
666
|
+
if (await skillDirectoryHasSecretContent(srcPath))
|
|
667
|
+
return true;
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if (kind !== "file")
|
|
671
|
+
continue;
|
|
672
|
+
const buffer = await readFile(srcPath);
|
|
673
|
+
if (isLikelyBinaryContent(buffer))
|
|
674
|
+
continue;
|
|
675
|
+
const text = buffer.toString("utf-8");
|
|
676
|
+
for (const line of text.split(/\r?\n/)) {
|
|
677
|
+
if (hasSecretLikeSkillLine(line))
|
|
678
|
+
return true;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
async function copyTemplateDir(src, dest, options = {}) {
|
|
684
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
685
|
+
for (const entry of entries) {
|
|
686
|
+
const srcPath = join(src, entry.name);
|
|
687
|
+
if (await options.skipEntry?.(srcPath, entry))
|
|
688
|
+
continue;
|
|
689
|
+
const destPath = join(dest, entry.name);
|
|
690
|
+
const kind = await getCopyEntryKind(srcPath, entry);
|
|
691
|
+
if (kind === "directory") {
|
|
692
|
+
await mkdir(destPath, { recursive: true });
|
|
693
|
+
await copyTemplateDir(srcPath, destPath, options);
|
|
694
|
+
}
|
|
695
|
+
else if (kind === "file") {
|
|
696
|
+
await mkdir(dirname(destPath), { recursive: true });
|
|
697
|
+
await copyFile(srcPath, destPath);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
async function copySafeSkillRoot(src, dest) {
|
|
702
|
+
const stats = {
|
|
703
|
+
copied: 0,
|
|
704
|
+
skippedUnsafe: 0,
|
|
705
|
+
skippedUnavailable: 0,
|
|
706
|
+
};
|
|
707
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
708
|
+
for (const entry of entries) {
|
|
709
|
+
const srcPath = join(src, entry.name);
|
|
710
|
+
if (entry.name.startsWith(".") || shouldSkipSkillCopyEntry(srcPath, entry))
|
|
711
|
+
continue;
|
|
712
|
+
const kind = await getCopyEntryKind(srcPath, entry);
|
|
713
|
+
if (kind !== "directory") {
|
|
714
|
+
if (entry.isSymbolicLink())
|
|
715
|
+
stats.skippedUnavailable++;
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
if (await skillDirectoryHasSecretContent(srcPath)) {
|
|
720
|
+
stats.skippedUnsafe++;
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
await copyTemplateDir(srcPath, join(dest, entry.name), {
|
|
724
|
+
skipEntry: shouldSkipSkillCopyEntry,
|
|
725
|
+
});
|
|
726
|
+
stats.copied++;
|
|
727
|
+
}
|
|
728
|
+
catch {
|
|
729
|
+
stats.skippedUnavailable++;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return stats;
|
|
733
|
+
}
|
|
734
|
+
const HOOK_SCRIPTS = {
|
|
735
|
+
"session-context.sh": `#!/usr/bin/env bash
|
|
736
|
+
# OMK SessionStart Context — keeps high-value local workflows visible
|
|
737
|
+
set -euo pipefail
|
|
738
|
+
|
|
739
|
+
if ! command -v node &>/dev/null; then
|
|
740
|
+
echo '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"OMK session started. Read project rules, use graph-view for memory relationships, use open-design for localhost design, and verify before final."}}'
|
|
741
|
+
exit 0
|
|
742
|
+
fi
|
|
743
|
+
|
|
744
|
+
node <<'NODE'
|
|
745
|
+
const context = [
|
|
746
|
+
'OMK session startup context.',
|
|
747
|
+
'- Read AGENTS.md and .kimi/AGENTS.md before edits; read DESIGN.md before UI/frontend/visual work.',
|
|
748
|
+
'- For local design iteration, use /open-design or omk design open-design --open to launch localhost.',
|
|
749
|
+
'- For memory/risk/file relationships, use /graph-view or omk graph view --open before broad repo edits.',
|
|
750
|
+
'- Treat release, push, publish, and deployment as not done unless the exact command ran and fresh evidence was collected.',
|
|
751
|
+
'- Final reports should list changed files, commands run, pass/fail/not-run status, and remaining risk.',
|
|
752
|
+
].join('\\n');
|
|
753
|
+
|
|
754
|
+
process.stdout.write(JSON.stringify({
|
|
755
|
+
hookSpecificOutput: {
|
|
756
|
+
hookEventName: 'SessionStart',
|
|
757
|
+
additionalContext: context,
|
|
758
|
+
},
|
|
759
|
+
}) + '\\n');
|
|
760
|
+
NODE
|
|
761
|
+
`,
|
|
762
|
+
"awesome-agent-skills-router.sh": `#!/usr/bin/env bash
|
|
763
|
+
# Awesome Agent Skills Router — curated OMK hints from VoltAgent/awesome-agent-skills
|
|
764
|
+
set -euo pipefail
|
|
765
|
+
|
|
766
|
+
# This hook is advisory only: no network access, no third-party skill install,
|
|
767
|
+
# and no prompt blocking. It maps common awesome-agent-skills domains to the
|
|
768
|
+
# already-installed OMK skills/workflows that are safe to consider.
|
|
769
|
+
if ! command -v node &>/dev/null; then
|
|
770
|
+
exit 0
|
|
771
|
+
fi
|
|
772
|
+
|
|
773
|
+
INPUT_FILE="$(mktemp)"
|
|
774
|
+
trap 'rm -f "$INPUT_FILE"' EXIT
|
|
775
|
+
cat > "$INPUT_FILE"
|
|
776
|
+
|
|
777
|
+
node - "$INPUT_FILE" <<'NODE'
|
|
778
|
+
const fs = require('node:fs');
|
|
779
|
+
// Static slash markers for non-shell smoke validation:
|
|
780
|
+
// /open-design /awesome-design-md /omk-design-md /omk-quality-gate /graph-view /omk-kimi-runtime
|
|
781
|
+
|
|
782
|
+
function readPayload(filePath) {
|
|
783
|
+
try {
|
|
784
|
+
const raw = fs.readFileSync(filePath, 'utf8').trim();
|
|
785
|
+
if (!raw) return {};
|
|
786
|
+
return JSON.parse(raw);
|
|
787
|
+
} catch {
|
|
788
|
+
return {};
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function textFrom(value) {
|
|
793
|
+
if (typeof value === 'string') return value;
|
|
794
|
+
if (Array.isArray(value)) {
|
|
795
|
+
return value.map(textFrom).filter(Boolean).join('\\n');
|
|
796
|
+
}
|
|
797
|
+
if (value && typeof value === 'object') {
|
|
798
|
+
for (const key of ['prompt', 'user_prompt', 'message', 'input', 'text', 'content', 'command_args']) {
|
|
799
|
+
const found = textFrom(value[key]);
|
|
800
|
+
if (found) return found;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
return '';
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
const payload = readPayload(process.argv[2]);
|
|
807
|
+
const prompt = textFrom(payload.prompt)
|
|
808
|
+
|| textFrom(payload.user_prompt)
|
|
809
|
+
|| textFrom(payload.message)
|
|
810
|
+
|| textFrom(payload.input)
|
|
811
|
+
|| textFrom(payload.command_args)
|
|
812
|
+
|| textFrom(payload.tool_input)
|
|
813
|
+
|| textFrom(payload);
|
|
814
|
+
|
|
815
|
+
const normalized = prompt.toLowerCase();
|
|
816
|
+
if (normalized.trim().length < 3) {
|
|
817
|
+
process.exit(0);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
const routes = [
|
|
821
|
+
{
|
|
822
|
+
id: 'design-ui',
|
|
823
|
+
patterns: [
|
|
824
|
+
'design', 'ui', 'ux', 'frontend', 'front-end', 'figma', 'stitch', 'open-design',
|
|
825
|
+
'prototype', 'landing', 'component', 'visual', 'screenshot', 'responsive', 'accessibility',
|
|
826
|
+
'react', 'next.js', 'vite', 'expo', 'react native',
|
|
827
|
+
'디자인', '화면', '프론트', '랜딩', '컴포넌트', '시각', '스크린샷', '반응형', '접근성', '프로토타입',
|
|
828
|
+
],
|
|
829
|
+
skills: ['open-design', 'awesome-design-md', 'omk-design-md', 'omk-flow-design-to-code', 'omk-multimodal-ui-review', 'react-doctor'],
|
|
830
|
+
note: 'For visual work, read DESIGN.md, reuse tokens, use awesome-design-md references when a named style is requested, and launch localhost with omk design open-design when interactive design is useful.',
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
id: 'bugfix-debug',
|
|
834
|
+
patterns: [
|
|
835
|
+
'bug', 'error', 'failed', 'failure', 'traceback', 'exception', 'fix', 'regression', 'broken', 'debug',
|
|
836
|
+
'버그', '에러', '오류', '실패', '고쳐', '수정', '안됨', '안돼', '문제', '디버그',
|
|
837
|
+
],
|
|
838
|
+
skills: ['omk-flow-bugfix', 'andrej-karpathy-skills', 'matt-pocock-skills', 'omk-quality-gate'],
|
|
839
|
+
note: 'For failures, isolate root cause first, keep the patch small, and rerun the failing command plus the quality gate.',
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
id: 'feature-build',
|
|
843
|
+
patterns: [
|
|
844
|
+
'implement', 'build', 'add ', 'create', 'scaffold', 'generate', 'feature', 'new command',
|
|
845
|
+
'구현', '추가', '만들', '생성', '기능', '신규',
|
|
846
|
+
],
|
|
847
|
+
skills: ['omk-plan-first', 'omk-flow-feature-dev', 'matt-pocock-skills', 'andrej-karpathy-skills', 'omk-quality-gate'],
|
|
848
|
+
note: 'For new capability work, plan the smallest reversible diff and include regression coverage before completion.',
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
id: 'review-security',
|
|
852
|
+
patterns: [
|
|
853
|
+
'review', 'audit', 'security', 'vulnerability', 'secret', 'token', 'auth', 'permission', 'xss', 'sql injection', 'ssrf',
|
|
854
|
+
'리뷰', '검토', '보안', '취약', '시크릿', '토큰', '인증', '권한',
|
|
855
|
+
],
|
|
856
|
+
skills: ['omk-code-review', 'omk-quality-gate'],
|
|
857
|
+
note: 'For security-sensitive work, do not print secrets, review trust boundaries, and run the project secret scan when available.',
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
id: 'release-git',
|
|
861
|
+
patterns: [
|
|
862
|
+
'release', 'publish', 'npm', 'version', 'changelog', 'commit', 'pull request', ' pr ', 'pr로', 'push', 'tag',
|
|
863
|
+
'배포', '릴리즈', '버전', '변경로그', '커밋', '푸시',
|
|
864
|
+
],
|
|
865
|
+
skills: ['omk-flow-release', 'omk-flow-pr-review', 'omk-quality-gate'],
|
|
866
|
+
note: 'For release or PR work, verify build/test/package evidence before reporting publish or PR readiness.',
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
id: 'spec-planning',
|
|
870
|
+
patterns: [
|
|
871
|
+
'spec', 'prd', 'requirements', 'acceptance', 'tasks', 'speckit', 'plan', 'architecture',
|
|
872
|
+
'명세', '요구사항', '수락기준', '계획', '아키텍처',
|
|
873
|
+
],
|
|
874
|
+
skills: ['omk-plan-first', 'speckit-specify', 'speckit-plan', 'speckit-tasks'],
|
|
875
|
+
note: 'For specification work, produce acceptance criteria and a test shape before implementation.',
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
id: 'refactor-cleanup',
|
|
879
|
+
patterns: [
|
|
880
|
+
'refactor', 'cleanup', 'simplify', 'deslop', 'debt', 'migration',
|
|
881
|
+
'리팩토', '정리', '단순화', '마이그레이션',
|
|
882
|
+
],
|
|
883
|
+
skills: ['omk-flow-refactor', 'andrej-karpathy-skills', 'matt-pocock-skills', 'omk-quality-gate'],
|
|
884
|
+
note: 'For refactors, preserve behavior with tests first and avoid unrelated rewrites.',
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
id: 'ontology-graph',
|
|
888
|
+
patterns: [
|
|
889
|
+
'ontology', 'graph', 'graph-view', 'node', 'nodes', 'edge', 'edges', 'relationship',
|
|
890
|
+
'memory graph', 'risk map', 'decision graph', 'trace map',
|
|
891
|
+
'온톨로지', '그래프', '노드', '엣지', '관계', '메모리 그래프', '리스크맵', '결정 그래프',
|
|
892
|
+
],
|
|
893
|
+
skills: ['graph-view', 'omk-kimi-runtime', 'omk-quality-gate'],
|
|
894
|
+
note: 'For graph or memory-relationship work, inspect .omk/memory/graph-state.json with omk graph view --open or /graph-view before changing code.',
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
id: 'agent-orchestration',
|
|
898
|
+
patterns: [
|
|
899
|
+
'agent', 'subagent', 'multi-agent', 'orchestration', 'workflow', 'mcp', 'hook', 'hooks', 'skill', 'skills', 'memory',
|
|
900
|
+
'에이전트', '서브에이전트', '워크플로', '훅', '스킬', '메모리',
|
|
901
|
+
],
|
|
902
|
+
skills: ['omk-task-router', 'omk-project-rules', 'omk-kimi-runtime', 'omk-flow-team-run', 'agentmemory', 'multica', 'andrej-karpathy-skills'],
|
|
903
|
+
note: 'For agent or hook work, keep routing advisory, avoid installing unreviewed external skills, and verify generated config locally.',
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
id: 'tests-quality',
|
|
907
|
+
patterns: [
|
|
908
|
+
'test', 'tests', 'qa', 'quality', 'lint', 'typecheck', 'playwright', 'e2e', 'coverage',
|
|
909
|
+
'테스트', '검증', '품질', '타입체크', '커버리지',
|
|
910
|
+
],
|
|
911
|
+
skills: ['omk-quality-gate'],
|
|
912
|
+
note: 'For validation requests, run the actual project scripts and report exact pass/fail evidence.',
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
id: 'docs-research',
|
|
916
|
+
patterns: [
|
|
917
|
+
'docs', 'documentation', 'readme', 'research', 'verify', 'official docs', 'look up',
|
|
918
|
+
'문서', '조사', '검증', '검색', '찾아',
|
|
919
|
+
],
|
|
920
|
+
skills: ['omk-plan-first', 'omk-quality-gate'],
|
|
921
|
+
note: 'For docs or external references, prefer official/current sources and cite or record what was verified.',
|
|
922
|
+
},
|
|
923
|
+
];
|
|
924
|
+
|
|
925
|
+
const matched = routes.filter((route) => route.patterns.some((pattern) => normalized.includes(pattern)));
|
|
926
|
+
if (matched.length === 0) {
|
|
927
|
+
process.exit(0);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
const skills = [];
|
|
931
|
+
for (const route of matched) {
|
|
932
|
+
for (const skill of route.skills) {
|
|
933
|
+
if (!skills.includes(skill)) skills.push(skill);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if (!skills.includes('omk-quality-gate')) {
|
|
938
|
+
skills.push('omk-quality-gate');
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
const context = [
|
|
942
|
+
'OMK awesome-agent-skills routing hint (curated from VoltAgent/awesome-agent-skills; advisory only).',
|
|
943
|
+
'Matched domains: ' + matched.map((route) => route.id).join(', '),
|
|
944
|
+
'Prefer installed OMK skills/workflows: ' + skills.map((skill) => '/' + skill).join(', '),
|
|
945
|
+
'Do not auto-install third-party skills from awesome-agent-skills. Review source, license, and security before adoption.',
|
|
946
|
+
...matched.slice(0, 4).map((route) => route.note),
|
|
947
|
+
].join('\\n');
|
|
948
|
+
|
|
949
|
+
process.stdout.write(JSON.stringify({
|
|
950
|
+
hookSpecificOutput: {
|
|
951
|
+
hookEventName: 'UserPromptSubmit',
|
|
952
|
+
additionalContext: context,
|
|
953
|
+
},
|
|
954
|
+
}) + '\\n');
|
|
955
|
+
NODE
|
|
956
|
+
`,
|
|
957
|
+
"precompact-checkpoint.sh": `#!/usr/bin/env bash
|
|
958
|
+
# OMK PreCompact Checkpoint — compact without losing recovery state
|
|
959
|
+
set -euo pipefail
|
|
960
|
+
|
|
961
|
+
if ! command -v node &>/dev/null; then
|
|
962
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PreCompact","additionalContext":"Before compaction: record goal, changed files, verification state, blockers, and next action. Never store secrets."}}'
|
|
963
|
+
exit 0
|
|
964
|
+
fi
|
|
965
|
+
|
|
966
|
+
node <<'NODE'
|
|
967
|
+
const context = [
|
|
968
|
+
'OMK pre-compaction checkpoint.',
|
|
969
|
+
'- Preserve current goal, changed files, verification state, blockers, and intended next action.',
|
|
970
|
+
'- If available, write concise notes to .omx/notepad.md or project-local memory; never store secrets.',
|
|
971
|
+
'- After compaction, refresh from the checkpoint before editing or claiming completion.',
|
|
972
|
+
].join('\\n');
|
|
973
|
+
|
|
974
|
+
process.stdout.write(JSON.stringify({
|
|
975
|
+
hookSpecificOutput: {
|
|
976
|
+
hookEventName: 'PreCompact',
|
|
977
|
+
additionalContext: context,
|
|
978
|
+
},
|
|
979
|
+
}) + '\\n');
|
|
980
|
+
NODE
|
|
981
|
+
`,
|
|
982
|
+
"subagent-stop-audit.sh": `#!/usr/bin/env bash
|
|
983
|
+
# OMK SubagentStop Audit — leader must verify delegated work
|
|
984
|
+
set -euo pipefail
|
|
985
|
+
|
|
986
|
+
HOOK_INPUT="$(cat || true)"
|
|
987
|
+
|
|
988
|
+
if ! command -v node &>/dev/null; then
|
|
989
|
+
exit 0
|
|
990
|
+
fi
|
|
991
|
+
|
|
992
|
+
OMK_HOOK_INPUT="$HOOK_INPUT" \\
|
|
993
|
+
node <<'NODE'
|
|
994
|
+
const inputText = process.env.OMK_HOOK_INPUT || '';
|
|
995
|
+
|
|
996
|
+
let input = {};
|
|
997
|
+
try {
|
|
998
|
+
input = inputText.trim() ? JSON.parse(inputText) : {};
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
console.error('[subagent-stop-audit] invalid stdin JSON: ' + String(error));
|
|
1001
|
+
process.exit(0);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
if (input.stop_hook_active === true) {
|
|
1005
|
+
process.exit(0);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
const context = [
|
|
1009
|
+
'OMK subagent completion audit.',
|
|
1010
|
+
'- Do not claim success from a subagent report alone.',
|
|
1011
|
+
'- Review the concrete files changed, reconcile conflicts, and keep unrelated user edits intact.',
|
|
1012
|
+
'- Run the relevant quality gates locally and report pass/fail/not-run evidence.',
|
|
1013
|
+
].join('\\n');
|
|
1014
|
+
|
|
1015
|
+
process.stdout.write(JSON.stringify({
|
|
1016
|
+
systemMessage: context,
|
|
1017
|
+
}) + '\\n');
|
|
1018
|
+
NODE
|
|
1019
|
+
`,
|
|
1020
|
+
"branch-diff-snapshot.sh": `#!/usr/bin/env bash
|
|
1021
|
+
# OMK Branch Diff Snapshot — records merge-review metadata without full diff contents
|
|
1022
|
+
set +e
|
|
1023
|
+
|
|
1024
|
+
SNAP_DIR=".omk/runs/_branch-snapshots"
|
|
1025
|
+
mkdir -p "$SNAP_DIR" >/dev/null 2>&1
|
|
1026
|
+
|
|
1027
|
+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
1028
|
+
echo '{"hookSpecificOutput":{"hookEventName":"SubagentStop","additionalContext":"Branch diff snapshot skipped: not inside a git worktree."}}'
|
|
1029
|
+
exit 0
|
|
1030
|
+
fi
|
|
1031
|
+
|
|
1032
|
+
branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
|
|
1033
|
+
commit="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
|
1034
|
+
safe_branch="$(printf '%s' "$branch" | tr -c 'A-Za-z0-9._-' '-')"
|
|
1035
|
+
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
1036
|
+
snapshot="$SNAP_DIR/$stamp-$safe_branch.md"
|
|
1037
|
+
|
|
1038
|
+
{
|
|
1039
|
+
echo "# OMK branch diff snapshot"
|
|
1040
|
+
echo
|
|
1041
|
+
echo "- branch: $branch"
|
|
1042
|
+
echo "- commit: $commit"
|
|
1043
|
+
echo "- captured_at: $stamp"
|
|
1044
|
+
echo
|
|
1045
|
+
echo "## Status"
|
|
1046
|
+
git status --short 2>/dev/null || true
|
|
1047
|
+
echo
|
|
1048
|
+
echo "## Diff stat"
|
|
1049
|
+
git diff --stat 2>/dev/null || true
|
|
1050
|
+
echo
|
|
1051
|
+
echo "## Changed files"
|
|
1052
|
+
git diff --name-only 2>/dev/null || true
|
|
1053
|
+
} > "$snapshot"
|
|
1054
|
+
|
|
1055
|
+
printf '{"hookSpecificOutput":{"hookEventName":"SubagentStop","additionalContext":"Branch diff snapshot saved: %s"}}\\n' "$snapshot"
|
|
1056
|
+
`,
|
|
1057
|
+
"pre-shell-guard.sh": `#!/usr/bin/env bash
|
|
1058
|
+
# PreShellUse Guard — blocks dangerous commands
|
|
1059
|
+
set -e
|
|
1060
|
+
|
|
1061
|
+
# Close security gate if jq/python3 is missing (deny by default)
|
|
1062
|
+
if command -v python3 &>/dev/null; then
|
|
1063
|
+
PY=python3
|
|
1064
|
+
elif command -v python &>/dev/null; then
|
|
1065
|
+
PY=python
|
|
1066
|
+
else
|
|
1067
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"python3 not installed — pre-shell-guard cannot validate commands"}}'
|
|
1068
|
+
exit 0
|
|
1069
|
+
fi
|
|
1070
|
+
|
|
1071
|
+
INPUT=$(cat)
|
|
1072
|
+
DESTRUCTIVE_DECISION=$(INPUT_JSON="$INPUT" "$PY" <<'PY'
|
|
1073
|
+
import json
|
|
1074
|
+
import os
|
|
1075
|
+
import posixpath
|
|
1076
|
+
import shlex
|
|
1077
|
+
|
|
1078
|
+
def decision(reason):
|
|
1079
|
+
print(json.dumps({"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":reason}}, separators=(",", ":")))
|
|
1080
|
+
|
|
1081
|
+
def as_tokens(value):
|
|
1082
|
+
if isinstance(value, list):
|
|
1083
|
+
return [str(item) for item in value]
|
|
1084
|
+
if isinstance(value, str) and value.strip():
|
|
1085
|
+
return shlex.split(value, comments=True, posix=True)
|
|
1086
|
+
return []
|
|
1087
|
+
|
|
1088
|
+
def expand_shell_wrappers(root_tokens):
|
|
1089
|
+
result = []
|
|
1090
|
+
queue = [root_tokens]
|
|
1091
|
+
while queue and len(result) < 8:
|
|
1092
|
+
current = queue.pop(0)
|
|
1093
|
+
result.append(current)
|
|
1094
|
+
for idx, token in enumerate(current):
|
|
1095
|
+
if posixpath.basename(token) not in {"bash", "sh", "zsh", "dash"}:
|
|
1096
|
+
continue
|
|
1097
|
+
j = idx + 1
|
|
1098
|
+
while j < len(current):
|
|
1099
|
+
opt = current[j]
|
|
1100
|
+
if opt == "--":
|
|
1101
|
+
j += 1
|
|
1102
|
+
break
|
|
1103
|
+
if opt in {"-c", "-lc"} or (opt.startswith("-") and not opt.startswith("--") and "c" in opt):
|
|
1104
|
+
if j + 1 < len(current):
|
|
1105
|
+
queue.append(as_tokens(current[j + 1]))
|
|
1106
|
+
break
|
|
1107
|
+
if opt.startswith("-"):
|
|
1108
|
+
j += 1
|
|
1109
|
+
continue
|
|
1110
|
+
break
|
|
1111
|
+
return result
|
|
1112
|
+
|
|
1113
|
+
def flag_letters(token):
|
|
1114
|
+
if token.startswith("--"):
|
|
1115
|
+
return set()
|
|
1116
|
+
if token.startswith("-"):
|
|
1117
|
+
return set(token[1:])
|
|
1118
|
+
return set()
|
|
1119
|
+
|
|
1120
|
+
def has_rm_rf(tokens, index):
|
|
1121
|
+
letters = set()
|
|
1122
|
+
for token in tokens[index + 1:]:
|
|
1123
|
+
letters.update(flag_letters(token))
|
|
1124
|
+
if not token.startswith("-"):
|
|
1125
|
+
break
|
|
1126
|
+
return "r" in letters and "f" in letters
|
|
1127
|
+
|
|
1128
|
+
def rm_rf_targets_catastrophic(tokens, index):
|
|
1129
|
+
if not has_rm_rf(tokens, index):
|
|
1130
|
+
return False
|
|
1131
|
+
targets = []
|
|
1132
|
+
for token in tokens[index + 1:]:
|
|
1133
|
+
if token == "--" or token.startswith("-"):
|
|
1134
|
+
continue
|
|
1135
|
+
targets.append(token)
|
|
1136
|
+
return any(target in {"/", "~", "$HOME"} or target.startswith("/*") or target.startswith("/dev/") for target in targets)
|
|
1137
|
+
|
|
1138
|
+
def has_git_clean_danger(tokens, index):
|
|
1139
|
+
rest = tokens[index + 1:]
|
|
1140
|
+
if "clean" not in rest:
|
|
1141
|
+
return False
|
|
1142
|
+
clean_index = rest.index("clean") + index + 1
|
|
1143
|
+
letters = set()
|
|
1144
|
+
for token in tokens[clean_index + 1:]:
|
|
1145
|
+
letters.update(flag_letters(token))
|
|
1146
|
+
return {"f", "d", "x"}.issubset(letters)
|
|
1147
|
+
|
|
1148
|
+
def has_pipe_to_shell(tokens):
|
|
1149
|
+
shell_names = {"bash", "sh", "zsh", "dash"}
|
|
1150
|
+
downloaders = {"curl", "wget"}
|
|
1151
|
+
for idx, token in enumerate(tokens):
|
|
1152
|
+
if token != "|":
|
|
1153
|
+
continue
|
|
1154
|
+
left = {posixpath.basename(item) for item in tokens[:idx]}
|
|
1155
|
+
right = {posixpath.basename(item) for item in tokens[idx + 1:]}
|
|
1156
|
+
if left & downloaders and right & shell_names:
|
|
1157
|
+
return True
|
|
1158
|
+
return False
|
|
1159
|
+
|
|
1160
|
+
def is_destructive(tokens):
|
|
1161
|
+
# Low-friction benchmark/SWE mode: only stop machine-destroying operations.
|
|
1162
|
+
# Package managers, git clean, chmod, docker, kubectl, sudo, and pipe-to-shell
|
|
1163
|
+
# are allowed so normal coding agents do not stall on broad heuristics.
|
|
1164
|
+
normalized = [str(token) for token in tokens]
|
|
1165
|
+
for idx, token in enumerate(normalized):
|
|
1166
|
+
exe = posixpath.basename(token)
|
|
1167
|
+
if exe == "rm" and rm_rf_targets_catastrophic(normalized, idx):
|
|
1168
|
+
return True
|
|
1169
|
+
if exe.startswith("mkfs"):
|
|
1170
|
+
return True
|
|
1171
|
+
if exe == "dd" and any(arg.startswith("of=/dev/") for arg in normalized[idx + 1:]):
|
|
1172
|
+
return True
|
|
1173
|
+
return False
|
|
1174
|
+
|
|
1175
|
+
try:
|
|
1176
|
+
data = json.loads(os.environ.get("INPUT_JSON", "{}"))
|
|
1177
|
+
tool_input = data.get("tool_input", {})
|
|
1178
|
+
tokens = as_tokens(tool_input.get("command", "")) + as_tokens(tool_input.get("args", ""))
|
|
1179
|
+
for expanded in expand_shell_wrappers(tokens):
|
|
1180
|
+
if is_destructive(expanded):
|
|
1181
|
+
decision("Potentially destructive command blocked by pre-shell-guard")
|
|
1182
|
+
break
|
|
1183
|
+
except Exception:
|
|
1184
|
+
# If token parsing fails on complex shell/heredoc syntax, fall through to the
|
|
1185
|
+
# literal block list and release guard instead of blocking benign coding work.
|
|
1186
|
+
pass
|
|
1187
|
+
PY
|
|
1188
|
+
)
|
|
1189
|
+
if [ -n "$DESTRUCTIVE_DECISION" ]; then
|
|
1190
|
+
echo "$DESTRUCTIVE_DECISION"
|
|
1191
|
+
exit 0
|
|
1192
|
+
fi
|
|
1193
|
+
COMMAND=$(echo "$INPUT" | $PY -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_input",{}).get("command",""))')
|
|
1194
|
+
ARGS=$(echo "$INPUT" | $PY -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_input",{}).get("args",""))')
|
|
1195
|
+
|
|
1196
|
+
FULL="$COMMAND $ARGS"
|
|
1197
|
+
|
|
1198
|
+
# Block list
|
|
1199
|
+
BLOCKED=(
|
|
1200
|
+
"rm -rf /"
|
|
1201
|
+
"rm -fr /"
|
|
1202
|
+
"rm -rf /*"
|
|
1203
|
+
"rm -fr /*"
|
|
1204
|
+
"rm -rf ~"
|
|
1205
|
+
"rm -fr ~"
|
|
1206
|
+
"mkfs"
|
|
1207
|
+
"of=/dev/"
|
|
1208
|
+
"> /dev/"
|
|
1209
|
+
":(){ :|:& };:"
|
|
1210
|
+
)
|
|
1211
|
+
|
|
1212
|
+
for pattern in "\${BLOCKED[@]}"; do
|
|
1213
|
+
if [[ "$FULL" == *"$pattern"* ]]; then
|
|
1214
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Potentially destructive command blocked by pre-shell-guard"}}'
|
|
1215
|
+
exit 0
|
|
1216
|
+
fi
|
|
1217
|
+
done
|
|
1218
|
+
|
|
1219
|
+
# Release/deploy guard. These commands are not destructive like rm -rf, but
|
|
1220
|
+
# they can publish external state. Parse tokens so common option/shell-wrapper
|
|
1221
|
+
# variants cannot bypass the guard.
|
|
1222
|
+
SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
1223
|
+
INPUT_JSON="$INPUT" SCRIPT_DIR="$SCRIPT_DIR" "$PY" <<'PY'
|
|
1224
|
+
import json
|
|
1225
|
+
import os
|
|
1226
|
+
import posixpath
|
|
1227
|
+
import shlex
|
|
1228
|
+
import sys
|
|
1229
|
+
|
|
1230
|
+
def respond(permission, reason=None):
|
|
1231
|
+
payload = {"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": permission}}
|
|
1232
|
+
if reason:
|
|
1233
|
+
payload["hookSpecificOutput"]["permissionDecisionReason"] = reason
|
|
1234
|
+
print(json.dumps(payload, separators=(",", ":")))
|
|
1235
|
+
sys.exit(0)
|
|
1236
|
+
|
|
1237
|
+
def as_tokens(value):
|
|
1238
|
+
if isinstance(value, list):
|
|
1239
|
+
return [str(item) for item in value]
|
|
1240
|
+
if isinstance(value, str) and value.strip():
|
|
1241
|
+
return shlex.split(value, comments=True, posix=True)
|
|
1242
|
+
return []
|
|
1243
|
+
|
|
1244
|
+
def expand_shell_wrappers(root_tokens):
|
|
1245
|
+
result = []
|
|
1246
|
+
queue = [root_tokens]
|
|
1247
|
+
while queue and len(result) < 8:
|
|
1248
|
+
current = queue.pop(0)
|
|
1249
|
+
result.append(current)
|
|
1250
|
+
for idx, token in enumerate(current):
|
|
1251
|
+
if posixpath.basename(token) not in {"bash", "sh", "zsh", "dash"}:
|
|
1252
|
+
continue
|
|
1253
|
+
j = idx + 1
|
|
1254
|
+
while j < len(current):
|
|
1255
|
+
opt = current[j]
|
|
1256
|
+
if opt == "--":
|
|
1257
|
+
j += 1
|
|
1258
|
+
break
|
|
1259
|
+
if opt in {"-c", "-lc"} or (opt.startswith("-") and not opt.startswith("--") and "c" in opt):
|
|
1260
|
+
if j + 1 < len(current):
|
|
1261
|
+
try:
|
|
1262
|
+
queue.append(as_tokens(current[j + 1]))
|
|
1263
|
+
except ValueError as exc:
|
|
1264
|
+
respond("deny", f"Unable to parse shell-wrapped release/deploy command safely: {exc}")
|
|
1265
|
+
break
|
|
1266
|
+
if opt.startswith("-"):
|
|
1267
|
+
j += 1
|
|
1268
|
+
continue
|
|
1269
|
+
break
|
|
1270
|
+
return result
|
|
1271
|
+
|
|
1272
|
+
def skip_flags(tokens, index):
|
|
1273
|
+
value_flags = {
|
|
1274
|
+
"-C", "-c", "--config-env", "--git-dir", "--work-tree", "--namespace",
|
|
1275
|
+
"--registry", "--userconfig", "--prefix", "--cache", "--filter", "--workspace",
|
|
1276
|
+
"--cwd", "--repo", "-R", "--ref", "--field", "-f", "--json", "--jq",
|
|
1277
|
+
}
|
|
1278
|
+
i = index
|
|
1279
|
+
while i < len(tokens):
|
|
1280
|
+
token = tokens[i]
|
|
1281
|
+
if token == "--":
|
|
1282
|
+
return i + 1
|
|
1283
|
+
if token in value_flags and i + 1 < len(tokens):
|
|
1284
|
+
i += 2
|
|
1285
|
+
continue
|
|
1286
|
+
if any(token.startswith(prefix + "=") for prefix in value_flags if prefix.startswith("--")):
|
|
1287
|
+
i += 1
|
|
1288
|
+
continue
|
|
1289
|
+
if token.startswith("-"):
|
|
1290
|
+
i += 1
|
|
1291
|
+
continue
|
|
1292
|
+
return i
|
|
1293
|
+
return i
|
|
1294
|
+
|
|
1295
|
+
def is_release_command(tokens):
|
|
1296
|
+
i = 0
|
|
1297
|
+
while i < len(tokens):
|
|
1298
|
+
exe = posixpath.basename(tokens[i])
|
|
1299
|
+
if exe == "git":
|
|
1300
|
+
command_index = skip_flags(tokens, i + 1)
|
|
1301
|
+
if command_index < len(tokens) and tokens[command_index] == "push":
|
|
1302
|
+
return True
|
|
1303
|
+
i = max(command_index + 1, i + 1)
|
|
1304
|
+
continue
|
|
1305
|
+
if exe == "npm":
|
|
1306
|
+
command_index = skip_flags(tokens, i + 1)
|
|
1307
|
+
if command_index < len(tokens) and tokens[command_index] in {"publish", "version"}:
|
|
1308
|
+
return True
|
|
1309
|
+
i = max(command_index + 1, i + 1)
|
|
1310
|
+
continue
|
|
1311
|
+
if exe == "pnpm":
|
|
1312
|
+
command_index = skip_flags(tokens, i + 1)
|
|
1313
|
+
if command_index < len(tokens) and tokens[command_index] == "publish":
|
|
1314
|
+
return True
|
|
1315
|
+
i = max(command_index + 1, i + 1)
|
|
1316
|
+
continue
|
|
1317
|
+
if exe == "yarn":
|
|
1318
|
+
command_index = skip_flags(tokens, i + 1)
|
|
1319
|
+
if command_index < len(tokens) and tokens[command_index] == "publish":
|
|
1320
|
+
return True
|
|
1321
|
+
if command_index + 1 < len(tokens) and tokens[command_index] == "npm" and tokens[command_index + 1] == "publish":
|
|
1322
|
+
return True
|
|
1323
|
+
i = max(command_index + 1, i + 1)
|
|
1324
|
+
continue
|
|
1325
|
+
if exe == "gh":
|
|
1326
|
+
command_index = skip_flags(tokens, i + 1)
|
|
1327
|
+
if command_index + 1 < len(tokens):
|
|
1328
|
+
pair = (tokens[command_index], tokens[command_index + 1])
|
|
1329
|
+
if pair in {("release", "create"), ("workflow", "run")}:
|
|
1330
|
+
return True
|
|
1331
|
+
i += 1
|
|
1332
|
+
continue
|
|
1333
|
+
i += 1
|
|
1334
|
+
return False
|
|
1335
|
+
|
|
1336
|
+
tool_input = {}
|
|
1337
|
+
try:
|
|
1338
|
+
data = json.loads(os.environ.get("INPUT_JSON", "{}"))
|
|
1339
|
+
tool_input = data.get("tool_input", {})
|
|
1340
|
+
tokens = as_tokens(tool_input.get("command", "")) + as_tokens(tool_input.get("args", ""))
|
|
1341
|
+
except Exception as exc:
|
|
1342
|
+
raw_command = str(tool_input.get("command", "")) if isinstance(tool_input, dict) else ""
|
|
1343
|
+
raw_args = str(tool_input.get("args", "")) if isinstance(tool_input, dict) else ""
|
|
1344
|
+
raw_full = f"{raw_command} {raw_args}"
|
|
1345
|
+
release_markers = ("git push", "npm publish", "npm version", "pnpm publish", "yarn publish", "yarn npm publish", "gh release create", "gh workflow run")
|
|
1346
|
+
if any(marker in raw_full for marker in release_markers):
|
|
1347
|
+
respond("deny", f"Unable to parse release/deploy command safely: {exc}")
|
|
1348
|
+
respond("allow")
|
|
1349
|
+
|
|
1350
|
+
if os.environ.get("OMK_ALLOW_RELEASE") == "1":
|
|
1351
|
+
respond("allow")
|
|
1352
|
+
|
|
1353
|
+
# File-based override for environments where env vars don't propagate to hooks
|
|
1354
|
+
allow_release_path = os.path.join(os.environ.get("SCRIPT_DIR", ""), ".allow-release")
|
|
1355
|
+
if os.path.exists(allow_release_path):
|
|
1356
|
+
respond("allow")
|
|
1357
|
+
|
|
1358
|
+
for expanded in expand_shell_wrappers(tokens):
|
|
1359
|
+
if is_release_command(expanded):
|
|
1360
|
+
respond("deny", "Release/deploy command blocked by OMK release guard. Re-run with OMK_ALLOW_RELEASE=1 only after an explicit user request and fresh verification evidence.")
|
|
1361
|
+
|
|
1362
|
+
respond("allow")
|
|
1363
|
+
PY
|
|
1364
|
+
`,
|
|
1365
|
+
"worktree-create-guard.sh": `#!/usr/bin/env bash
|
|
1366
|
+
# OMK Worktree Create Guard — keeps worker lanes under .omk/worktrees by default
|
|
1367
|
+
set -e
|
|
1368
|
+
|
|
1369
|
+
if command -v python3 &>/dev/null; then
|
|
1370
|
+
PY=python3
|
|
1371
|
+
elif command -v python &>/dev/null; then
|
|
1372
|
+
PY=python
|
|
1373
|
+
else
|
|
1374
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"python3 not installed — worktree-create-guard cannot validate commands"}}'
|
|
1375
|
+
exit 0
|
|
1376
|
+
fi
|
|
1377
|
+
|
|
1378
|
+
INPUT=$(cat)
|
|
1379
|
+
INPUT_JSON="$INPUT" "$PY" <<'PY'
|
|
1380
|
+
import json
|
|
1381
|
+
import os
|
|
1382
|
+
import posixpath
|
|
1383
|
+
import shlex
|
|
1384
|
+
import sys
|
|
1385
|
+
|
|
1386
|
+
def respond(permission, reason=None):
|
|
1387
|
+
payload = {"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": permission}}
|
|
1388
|
+
if reason:
|
|
1389
|
+
payload["hookSpecificOutput"]["permissionDecisionReason"] = reason
|
|
1390
|
+
print(json.dumps(payload, separators=(",", ":")))
|
|
1391
|
+
sys.exit(0)
|
|
1392
|
+
|
|
1393
|
+
def as_tokens(value):
|
|
1394
|
+
if isinstance(value, list):
|
|
1395
|
+
return [str(item) for item in value]
|
|
1396
|
+
if isinstance(value, str) and value.strip():
|
|
1397
|
+
return shlex.split(value, comments=True, posix=True)
|
|
1398
|
+
return []
|
|
1399
|
+
|
|
1400
|
+
try:
|
|
1401
|
+
data = json.loads(os.environ.get("INPUT_JSON", "{}"))
|
|
1402
|
+
except Exception:
|
|
1403
|
+
respond("allow")
|
|
1404
|
+
|
|
1405
|
+
tool_input = data.get("tool_input", {})
|
|
1406
|
+
raw_full = f"{tool_input.get('command', '')} {tool_input.get('args', '')}"
|
|
1407
|
+
try:
|
|
1408
|
+
initial_tokens = as_tokens(tool_input.get("command", "")) + as_tokens(tool_input.get("args", ""))
|
|
1409
|
+
except ValueError as exc:
|
|
1410
|
+
if "git" in raw_full and "worktree" in raw_full:
|
|
1411
|
+
respond("deny", f"Unable to parse git worktree command safely: {exc}")
|
|
1412
|
+
respond("allow")
|
|
1413
|
+
|
|
1414
|
+
def canonical_path(path):
|
|
1415
|
+
return os.path.realpath(os.path.abspath(path))
|
|
1416
|
+
|
|
1417
|
+
def resolve_path(path_arg, base_dir):
|
|
1418
|
+
return canonical_path(path_arg if os.path.isabs(path_arg) else os.path.join(base_dir, path_arg))
|
|
1419
|
+
|
|
1420
|
+
project_root = canonical_path(os.environ.get("OMK_PROJECT_ROOT") or os.getcwd())
|
|
1421
|
+
allowed_root = canonical_path(os.path.join(project_root, ".omk", "worktrees"))
|
|
1422
|
+
options_with_values = {
|
|
1423
|
+
"-C", "-c", "--git-dir", "--work-tree", "--namespace", "--config-env",
|
|
1424
|
+
"-b", "-B", "--reason", "--lock", "--orphan",
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
def path_within_allowed(path_arg, base_dir):
|
|
1428
|
+
base = canonical_path(base_dir)
|
|
1429
|
+
actual = resolve_path(path_arg, base)
|
|
1430
|
+
try:
|
|
1431
|
+
return os.path.commonpath([allowed_root, actual]) == allowed_root
|
|
1432
|
+
except ValueError:
|
|
1433
|
+
return False
|
|
1434
|
+
|
|
1435
|
+
def skip_git_globals(index):
|
|
1436
|
+
base_dir = canonical_path(os.getcwd())
|
|
1437
|
+
i = index
|
|
1438
|
+
while i < len(tokens):
|
|
1439
|
+
token = tokens[i]
|
|
1440
|
+
if token == "-C" and i + 1 < len(tokens):
|
|
1441
|
+
next_dir = tokens[i + 1]
|
|
1442
|
+
base_dir = resolve_path(next_dir, base_dir)
|
|
1443
|
+
i += 2
|
|
1444
|
+
elif token.startswith("-C") and len(token) > 2:
|
|
1445
|
+
next_dir = token[2:]
|
|
1446
|
+
base_dir = resolve_path(next_dir, base_dir)
|
|
1447
|
+
i += 1
|
|
1448
|
+
elif token in {"-c", "--git-dir", "--work-tree", "--namespace", "--config-env"} and i + 1 < len(tokens):
|
|
1449
|
+
i += 2
|
|
1450
|
+
elif token.startswith(("--git-dir=", "--work-tree=", "--namespace=", "--config-env=")):
|
|
1451
|
+
i += 1
|
|
1452
|
+
elif token == "--":
|
|
1453
|
+
i += 1
|
|
1454
|
+
break
|
|
1455
|
+
elif token.startswith("-"):
|
|
1456
|
+
i += 1
|
|
1457
|
+
else:
|
|
1458
|
+
break
|
|
1459
|
+
return i, base_dir
|
|
1460
|
+
|
|
1461
|
+
def find_worktree_path(index):
|
|
1462
|
+
i = index
|
|
1463
|
+
while i < len(tokens):
|
|
1464
|
+
token = tokens[i]
|
|
1465
|
+
if token == "--":
|
|
1466
|
+
i += 1
|
|
1467
|
+
break
|
|
1468
|
+
if token in options_with_values and i + 1 < len(tokens):
|
|
1469
|
+
i += 2
|
|
1470
|
+
continue
|
|
1471
|
+
if any(token.startswith(prefix) for prefix in ("--reason=", "--orphan=")):
|
|
1472
|
+
i += 1
|
|
1473
|
+
continue
|
|
1474
|
+
if token.startswith("-"):
|
|
1475
|
+
i += 1
|
|
1476
|
+
continue
|
|
1477
|
+
return token
|
|
1478
|
+
return tokens[i] if i < len(tokens) else None
|
|
1479
|
+
|
|
1480
|
+
def expand_shell_wrappers(root_tokens):
|
|
1481
|
+
result = []
|
|
1482
|
+
queue = [root_tokens]
|
|
1483
|
+
while queue and len(result) < 8:
|
|
1484
|
+
current = queue.pop(0)
|
|
1485
|
+
result.append(current)
|
|
1486
|
+
for idx, token in enumerate(current):
|
|
1487
|
+
if posixpath.basename(token) not in {"bash", "sh", "zsh", "dash"}:
|
|
1488
|
+
continue
|
|
1489
|
+
j = idx + 1
|
|
1490
|
+
while j < len(current):
|
|
1491
|
+
opt = current[j]
|
|
1492
|
+
if opt == "--":
|
|
1493
|
+
j += 1
|
|
1494
|
+
break
|
|
1495
|
+
if opt in {"-c", "-lc"} or (opt.startswith("-") and not opt.startswith("--") and "c" in opt):
|
|
1496
|
+
if j + 1 < len(current):
|
|
1497
|
+
try:
|
|
1498
|
+
queue.append(as_tokens(current[j + 1]))
|
|
1499
|
+
except ValueError as exc:
|
|
1500
|
+
if "git" in current[j + 1] and "worktree" in current[j + 1]:
|
|
1501
|
+
respond("deny", f"Unable to parse shell-wrapped git worktree command safely: {exc}")
|
|
1502
|
+
break
|
|
1503
|
+
if opt.startswith("-"):
|
|
1504
|
+
j += 1
|
|
1505
|
+
continue
|
|
1506
|
+
break
|
|
1507
|
+
return result
|
|
1508
|
+
|
|
1509
|
+
for tokens in expand_shell_wrappers(initial_tokens):
|
|
1510
|
+
i = 0
|
|
1511
|
+
while i < len(tokens):
|
|
1512
|
+
if posixpath.basename(tokens[i]) != "git":
|
|
1513
|
+
i += 1
|
|
1514
|
+
continue
|
|
1515
|
+
command_index, base_dir = skip_git_globals(i + 1)
|
|
1516
|
+
if command_index + 1 >= len(tokens) or tokens[command_index] != "worktree":
|
|
1517
|
+
i += 1
|
|
1518
|
+
continue
|
|
1519
|
+
action = tokens[command_index + 1]
|
|
1520
|
+
if action in {"remove", "prune"} and os.environ.get("OMK_ALLOW_WORKTREE_DELETE") != "1":
|
|
1521
|
+
respond("deny", "Worktree delete/prune blocked unless OMK_ALLOW_WORKTREE_DELETE=1 is set after review.")
|
|
1522
|
+
if action == "add" and os.environ.get("OMK_ALLOW_EXTERNAL_WORKTREE") != "1":
|
|
1523
|
+
path_arg = find_worktree_path(command_index + 2)
|
|
1524
|
+
if not path_arg or not path_within_allowed(path_arg, base_dir):
|
|
1525
|
+
respond("deny", "Worktree lanes must be created under .omk/worktrees/ unless OMK_ALLOW_EXTERNAL_WORKTREE=1 is set.")
|
|
1526
|
+
i = command_index + 2
|
|
1527
|
+
|
|
1528
|
+
respond("allow")
|
|
1529
|
+
PY
|
|
1530
|
+
`,
|
|
1531
|
+
"protect-secrets.sh": `#!/usr/bin/env bash
|
|
1532
|
+
# Secret/environment variable protection
|
|
1533
|
+
set -e
|
|
1534
|
+
|
|
1535
|
+
# Close security gate if jq/python3 is missing (deny by default)
|
|
1536
|
+
if command -v python3 &>/dev/null; then
|
|
1537
|
+
PY=python3
|
|
1538
|
+
elif command -v python &>/dev/null; then
|
|
1539
|
+
PY=python
|
|
1540
|
+
else
|
|
1541
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"python3 not installed — protect-secrets cannot validate files"}}'
|
|
1542
|
+
exit 0
|
|
1543
|
+
fi
|
|
1544
|
+
|
|
1545
|
+
INPUT=$(cat)
|
|
1546
|
+
OMK_HOOK_INPUT="$INPUT" "$PY" - <<'PY'
|
|
1547
|
+
import json
|
|
1548
|
+
import os
|
|
1549
|
+
import re
|
|
1550
|
+
|
|
1551
|
+
def respond(decision, reason=None):
|
|
1552
|
+
payload = {"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": decision}}
|
|
1553
|
+
if reason:
|
|
1554
|
+
payload["hookSpecificOutput"]["permissionDecisionReason"] = reason
|
|
1555
|
+
print(json.dumps(payload, separators=(",", ":")))
|
|
1556
|
+
|
|
1557
|
+
try:
|
|
1558
|
+
data = json.loads(os.environ.get("OMK_HOOK_INPUT", "{}") or "{}")
|
|
1559
|
+
except Exception:
|
|
1560
|
+
respond("deny", "Invalid hook input")
|
|
1561
|
+
raise SystemExit(0)
|
|
1562
|
+
|
|
1563
|
+
tool_input = data.get("tool_input", {})
|
|
1564
|
+
if not isinstance(tool_input, dict):
|
|
1565
|
+
respond("allow")
|
|
1566
|
+
raise SystemExit(0)
|
|
1567
|
+
|
|
1568
|
+
def walk(value, key=""):
|
|
1569
|
+
if isinstance(value, str):
|
|
1570
|
+
yield key, value
|
|
1571
|
+
elif isinstance(value, dict):
|
|
1572
|
+
for child_key, child_value in value.items():
|
|
1573
|
+
yield from walk(child_value, str(child_key))
|
|
1574
|
+
elif isinstance(value, list):
|
|
1575
|
+
for child_value in value:
|
|
1576
|
+
yield from walk(child_value, key)
|
|
1577
|
+
|
|
1578
|
+
SENSITIVE_PATHS = (".env", ".pem", ".key", "id_rsa", "id_ed25519", "credentials", "service-account", ".p12", ".pfx", ".keystore", ".pi", "auth.json", "oauth.json", "tokens.json", "session.json")
|
|
1579
|
+
HIGH_CONFIDENCE_PATTERNS = (
|
|
1580
|
+
re.compile(r"(?:ghp_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|npm_[A-Za-z0-9_-]{30,}|pypi[-_][A-Za-z0-9_-]{30,}|sk-[A-Za-z0-9_-]{20,})", re.IGNORECASE),
|
|
1581
|
+
re.compile(r"(?:AKIA|ASIA)[0-9A-Z]{16}"),
|
|
1582
|
+
re.compile(r"BEGIN [A-Z ]*PRIVATE KEY"),
|
|
1583
|
+
re.compile(r"(?:ssh-rsa|ssh-ed25519)\\s+[A-Za-z0-9+/=]{40,}"),
|
|
1584
|
+
re.compile(r"\\bBearer\\s+[A-Za-z0-9._~+/-]{16,}", re.IGNORECASE),
|
|
1585
|
+
)
|
|
1586
|
+
ASSIGNMENT_PATTERN = re.compile(r"""\\b(?:password|secret|api[_-]?key|token|access[_-]?token|refresh[_-]?token|session[_-]?token|oauth|authorization|private[_-]?key|aws[_-]?access[_-]?key[_-]?id|aws[_-]?secret[_-]?access[_-]?key)\\b['"]?\\s*[:=]\\s*['"]?[A-Za-z0-9_./+=@:-]{12,}""", re.IGNORECASE)
|
|
1587
|
+
SCAN_VALUE_KEYS = ("content", "text", "string", "newtext", "oldtext", "input", "value", "body", "data")
|
|
1588
|
+
SKIP_ASSIGNMENT_KEYS = ("path", "file", "command", "args", "name")
|
|
1589
|
+
|
|
1590
|
+
def should_scan_assignment(key):
|
|
1591
|
+
key_lower = key.lower()
|
|
1592
|
+
if any(marker in key_lower for marker in SKIP_ASSIGNMENT_KEYS):
|
|
1593
|
+
return False
|
|
1594
|
+
return key_lower == "" or any(marker in key_lower for marker in SCAN_VALUE_KEYS)
|
|
1595
|
+
|
|
1596
|
+
for key, value in walk(tool_input):
|
|
1597
|
+
key_lower = key.lower()
|
|
1598
|
+
if ("path" in key_lower or "file" in key_lower) and any(marker in value for marker in SENSITIVE_PATHS):
|
|
1599
|
+
respond("deny", "Direct modification of sensitive file blocked")
|
|
1600
|
+
raise SystemExit(0)
|
|
1601
|
+
|
|
1602
|
+
for key, value in walk(tool_input):
|
|
1603
|
+
if should_scan_assignment(key) and any(pattern.search(value) for pattern in HIGH_CONFIDENCE_PATTERNS):
|
|
1604
|
+
respond("deny", "High-confidence credential value detected")
|
|
1605
|
+
raise SystemExit(0)
|
|
1606
|
+
|
|
1607
|
+
for key, value in walk(tool_input):
|
|
1608
|
+
if should_scan_assignment(key) and ASSIGNMENT_PATTERN.search(value):
|
|
1609
|
+
respond("deny", "High-confidence credential assignment detected")
|
|
1610
|
+
raise SystemExit(0)
|
|
1611
|
+
respond("allow")
|
|
1612
|
+
PY
|
|
1613
|
+
`,
|
|
1614
|
+
"post-format.sh": `#!/usr/bin/env bash
|
|
1615
|
+
# Auto-format after save (single file target)
|
|
1616
|
+
set -e
|
|
1617
|
+
|
|
1618
|
+
if command -v python3 &>/dev/null; then
|
|
1619
|
+
PY=python3
|
|
1620
|
+
elif command -v python &>/dev/null; then
|
|
1621
|
+
PY=python
|
|
1622
|
+
else
|
|
1623
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1624
|
+
exit 0
|
|
1625
|
+
fi
|
|
1626
|
+
|
|
1627
|
+
INPUT=$(cat)
|
|
1628
|
+
FILEPATH=$(echo "$INPUT" | $PY -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_input",{}).get("file_path",""))')
|
|
1629
|
+
|
|
1630
|
+
if [ -z "$FILEPATH" ]; then
|
|
1631
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1632
|
+
exit 0
|
|
1633
|
+
fi
|
|
1634
|
+
|
|
1635
|
+
# Detect project root and run formatter (target file only)
|
|
1636
|
+
if [ -f "package.json" ] && [ -f "$FILEPATH" ]; then
|
|
1637
|
+
npx prettier --write "$FILEPATH" >/dev/null 2>&1 || true
|
|
1638
|
+
fi
|
|
1639
|
+
|
|
1640
|
+
if [ -f "Cargo.toml" ] && [ -f "$FILEPATH" ]; then
|
|
1641
|
+
rustfmt "$FILEPATH" >/dev/null 2>&1 || true
|
|
1642
|
+
fi
|
|
1643
|
+
|
|
1644
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1645
|
+
`,
|
|
1646
|
+
"typecheck-after-edit.sh": `#!/usr/bin/env bash
|
|
1647
|
+
# TypeScript product preset: run project typecheck after TS edits when available.
|
|
1648
|
+
set +e
|
|
1649
|
+
|
|
1650
|
+
if command -v python3 &>/dev/null; then
|
|
1651
|
+
PY=python3
|
|
1652
|
+
elif command -v python &>/dev/null; then
|
|
1653
|
+
PY=python
|
|
1654
|
+
else
|
|
1655
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1656
|
+
exit 0
|
|
1657
|
+
fi
|
|
1658
|
+
|
|
1659
|
+
INPUT=$(cat)
|
|
1660
|
+
FILEPATH=$(echo "$INPUT" | $PY -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_input",{}).get("file_path",""))')
|
|
1661
|
+
|
|
1662
|
+
case "$FILEPATH" in
|
|
1663
|
+
*.ts|*.tsx|*.mts|*.cts) ;;
|
|
1664
|
+
*) echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'; exit 0 ;;
|
|
1665
|
+
esac
|
|
1666
|
+
|
|
1667
|
+
if [ ! -f "package.json" ] || ! command -v npm &>/dev/null; then
|
|
1668
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1669
|
+
exit 0
|
|
1670
|
+
fi
|
|
1671
|
+
|
|
1672
|
+
node -e "const p=require('./package.json'); process.exit(p.scripts && p.scripts.check ? 0 : 1)" >/dev/null 2>&1
|
|
1673
|
+
if [ $? -ne 0 ]; then
|
|
1674
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1675
|
+
exit 0
|
|
1676
|
+
fi
|
|
1677
|
+
|
|
1678
|
+
TMP=$(mktemp)
|
|
1679
|
+
npm run check >"$TMP" 2>&1
|
|
1680
|
+
STATUS=$?
|
|
1681
|
+
if [ $STATUS -eq 0 ]; then
|
|
1682
|
+
rm -f "$TMP"
|
|
1683
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1684
|
+
exit 0
|
|
1685
|
+
fi
|
|
1686
|
+
|
|
1687
|
+
tail -n 40 "$TMP" | $PY -c 'import json,sys; print(json.dumps({"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow","additionalContext":"Typecheck failed after edit. Inspect npm run check output:\\n"+sys.stdin.read()}}))'
|
|
1688
|
+
rm -f "$TMP"
|
|
1689
|
+
`,
|
|
1690
|
+
"eslint-after-edit.sh": `#!/usr/bin/env bash
|
|
1691
|
+
# TypeScript product preset: run project lint after JS/TS edits when available.
|
|
1692
|
+
set +e
|
|
1693
|
+
|
|
1694
|
+
if command -v python3 &>/dev/null; then
|
|
1695
|
+
PY=python3
|
|
1696
|
+
elif command -v python &>/dev/null; then
|
|
1697
|
+
PY=python
|
|
1698
|
+
else
|
|
1699
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1700
|
+
exit 0
|
|
1701
|
+
fi
|
|
1702
|
+
|
|
1703
|
+
INPUT=$(cat)
|
|
1704
|
+
FILEPATH=$(echo "$INPUT" | $PY -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_input",{}).get("file_path",""))')
|
|
1705
|
+
|
|
1706
|
+
case "$FILEPATH" in
|
|
1707
|
+
*.js|*.jsx|*.mjs|*.cjs|*.ts|*.tsx|*.mts|*.cts) ;;
|
|
1708
|
+
*) echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'; exit 0 ;;
|
|
1709
|
+
esac
|
|
1710
|
+
|
|
1711
|
+
if [ ! -f "package.json" ] || ! command -v npm &>/dev/null; then
|
|
1712
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1713
|
+
exit 0
|
|
1714
|
+
fi
|
|
1715
|
+
|
|
1716
|
+
node -e "const p=require('./package.json'); process.exit(p.scripts && p.scripts.lint ? 0 : 1)" >/dev/null 2>&1
|
|
1717
|
+
if [ $? -ne 0 ]; then
|
|
1718
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1719
|
+
exit 0
|
|
1720
|
+
fi
|
|
1721
|
+
|
|
1722
|
+
TMP=$(mktemp)
|
|
1723
|
+
npm run lint >"$TMP" 2>&1
|
|
1724
|
+
STATUS=$?
|
|
1725
|
+
if [ $STATUS -eq 0 ]; then
|
|
1726
|
+
rm -f "$TMP"
|
|
1727
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow"}}'
|
|
1728
|
+
exit 0
|
|
1729
|
+
fi
|
|
1730
|
+
|
|
1731
|
+
tail -n 40 "$TMP" | $PY -c 'import json,sys; print(json.dumps({"hookSpecificOutput":{"hookEventName":"PostToolUse","permissionDecision":"allow","additionalContext":"ESLint failed after edit. Inspect npm run lint output:\\n"+sys.stdin.read()}}))'
|
|
1732
|
+
rm -f "$TMP"
|
|
1733
|
+
`,
|
|
1734
|
+
"stop-verify.sh": `#!/usr/bin/env bash
|
|
1735
|
+
# Final verification on Stop
|
|
1736
|
+
set -euo pipefail
|
|
1737
|
+
|
|
1738
|
+
HOOK_INPUT="$(cat || true)"
|
|
1739
|
+
|
|
1740
|
+
if ! command -v node &>/dev/null; then
|
|
1741
|
+
exit 0
|
|
1742
|
+
fi
|
|
1743
|
+
|
|
1744
|
+
OMK_HOOK_INPUT="$HOOK_INPUT" \\
|
|
1745
|
+
node <<'NODE'
|
|
1746
|
+
const inputText = process.env.OMK_HOOK_INPUT || '';
|
|
1747
|
+
|
|
1748
|
+
let input = {};
|
|
1749
|
+
try {
|
|
1750
|
+
input = inputText.trim() ? JSON.parse(inputText) : {};
|
|
1751
|
+
} catch (error) {
|
|
1752
|
+
console.error('[stop-verify] invalid stdin JSON: ' + String(error));
|
|
1753
|
+
process.exit(0);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
if (input.stop_hook_active === true) {
|
|
1757
|
+
process.exit(0);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
const context = [
|
|
1761
|
+
'OMK final response checklist.',
|
|
1762
|
+
'- Changed files: list authored files and note any ignored local runtime files refreshed.',
|
|
1763
|
+
'- Commands run: include exact verification commands and pass/fail/not-run status.',
|
|
1764
|
+
'- Deployment status: do not claim push, release, npm publish, or production deploy unless that command actually ran and evidence was read.',
|
|
1765
|
+
'- Remaining risk: state known gaps instead of saying complete without evidence.',
|
|
1766
|
+
].join('\\n');
|
|
1767
|
+
|
|
1768
|
+
process.stdout.write(JSON.stringify({
|
|
1769
|
+
systemMessage: context,
|
|
1770
|
+
}) + '\\n');
|
|
1771
|
+
NODE
|
|
1772
|
+
`,
|
|
1773
|
+
"release-check-before-stop.sh": `#!/usr/bin/env bash
|
|
1774
|
+
# OMK Release Guard — final checklist reminder for release/security work
|
|
1775
|
+
set +e
|
|
1776
|
+
|
|
1777
|
+
HOOK_INPUT="$(cat || true)"
|
|
1778
|
+
|
|
1779
|
+
if ! command -v node &>/dev/null; then
|
|
1780
|
+
exit 0
|
|
1781
|
+
fi
|
|
1782
|
+
|
|
1783
|
+
OMK_HOOK_INPUT="$HOOK_INPUT" \\
|
|
1784
|
+
node <<'NODE'
|
|
1785
|
+
const { execSync } = require('node:child_process');
|
|
1786
|
+
const inputText = process.env.OMK_HOOK_INPUT || '';
|
|
1787
|
+
|
|
1788
|
+
let input = {};
|
|
1789
|
+
try {
|
|
1790
|
+
input = inputText.trim() ? JSON.parse(inputText) : {};
|
|
1791
|
+
} catch (error) {
|
|
1792
|
+
console.error('[release-check-before-stop] invalid stdin JSON: ' + String(error));
|
|
1793
|
+
process.exit(0);
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
if (input.stop_hook_active === true) {
|
|
1797
|
+
process.exit(0);
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
function shell(command) {
|
|
1801
|
+
try {
|
|
1802
|
+
return execSync(command, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 }).trim();
|
|
1803
|
+
} catch {
|
|
1804
|
+
return '';
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
const changed = [
|
|
1809
|
+
shell('git diff --name-only HEAD 2>/dev/null'),
|
|
1810
|
+
shell('git diff --cached --name-only 2>/dev/null'),
|
|
1811
|
+
shell('git ls-files --others --exclude-standard 2>/dev/null'),
|
|
1812
|
+
].filter(Boolean).join('\\n');
|
|
1813
|
+
|
|
1814
|
+
const releaseTouched = /(^|\\n)(package\\.json|package-lock\\.json|pnpm-lock\\.yaml|yarn\\.lock|CHANGELOG\\.md|SECURITY\\.md|\\.npmrc|\\.github\\/workflows\\/release\\.ya?ml)(\\n|$)/.test(changed);
|
|
1815
|
+
const context = releaseTouched
|
|
1816
|
+
? 'OMK release guard: release/security files changed. Before final or publish, collect secret scan, security review, quality gate, npm audit summary, changelog/PR evidence, and do not publish/deploy without explicit user request.'
|
|
1817
|
+
: 'OMK release guard: no release file changes detected. Still do not claim push, release, npm publish, or production deploy without exact command evidence.';
|
|
1818
|
+
|
|
1819
|
+
process.stdout.write(JSON.stringify({
|
|
1820
|
+
systemMessage: context,
|
|
1821
|
+
}) + '\\n');
|
|
1822
|
+
NODE
|
|
1823
|
+
`,
|
|
1824
|
+
"npm-audit-summary.sh": `#!/usr/bin/env bash
|
|
1825
|
+
# OMK Release Guard — optional npm audit summary for release gates
|
|
1826
|
+
set +e
|
|
1827
|
+
|
|
1828
|
+
HOOK_INPUT="$(cat || true)"
|
|
1829
|
+
|
|
1830
|
+
if command -v node &>/dev/null; then
|
|
1831
|
+
OMK_HOOK_INPUT="$HOOK_INPUT" node <<'NODE'
|
|
1832
|
+
const inputText = process.env.OMK_HOOK_INPUT || '';
|
|
1833
|
+
try {
|
|
1834
|
+
const input = inputText.trim() ? JSON.parse(inputText) : {};
|
|
1835
|
+
if (input.stop_hook_active === true) process.exit(10);
|
|
1836
|
+
} catch (error) {
|
|
1837
|
+
console.error('[npm-audit-summary] invalid stdin JSON: ' + String(error));
|
|
1838
|
+
process.exit(11);
|
|
1839
|
+
}
|
|
1840
|
+
NODE
|
|
1841
|
+
case "$?" in
|
|
1842
|
+
10|11) exit 0 ;;
|
|
1843
|
+
esac
|
|
1844
|
+
fi
|
|
1845
|
+
|
|
1846
|
+
if [ ! -f "package.json" ]; then
|
|
1847
|
+
printf '{"systemMessage":"OMK npm audit summary: skipped because package.json is absent."}\\n'
|
|
1848
|
+
exit 0
|
|
1849
|
+
fi
|
|
1850
|
+
|
|
1851
|
+
if [ "$OMK_RUN_NPM_AUDIT_SUMMARY" != "1" ]; then
|
|
1852
|
+
printf '{"systemMessage":"OMK npm audit summary: not run automatically. For release/security claims, run npm audit or set OMK_RUN_NPM_AUDIT_SUMMARY=1 and capture the result."}\\n'
|
|
1853
|
+
exit 0
|
|
1854
|
+
fi
|
|
1855
|
+
|
|
1856
|
+
if ! command -v npm &>/dev/null || ! command -v node &>/dev/null; then
|
|
1857
|
+
printf '{"systemMessage":"OMK npm audit summary: skipped because npm or node is unavailable."}\\n'
|
|
1858
|
+
exit 0
|
|
1859
|
+
fi
|
|
1860
|
+
|
|
1861
|
+
TMP="$(mktemp)"
|
|
1862
|
+
npm audit --audit-level=high --omit=dev --json > "$TMP" 2>&1
|
|
1863
|
+
STATUS=$?
|
|
1864
|
+
|
|
1865
|
+
node - "$TMP" "$STATUS" <<'NODE'
|
|
1866
|
+
const fs = require('node:fs');
|
|
1867
|
+
const filePath = process.argv[2];
|
|
1868
|
+
const status = Number(process.argv[3] || 0);
|
|
1869
|
+
let raw = '';
|
|
1870
|
+
try {
|
|
1871
|
+
raw = fs.readFileSync(filePath, 'utf8');
|
|
1872
|
+
} catch {}
|
|
1873
|
+
|
|
1874
|
+
let context;
|
|
1875
|
+
try {
|
|
1876
|
+
const parsed = JSON.parse(raw);
|
|
1877
|
+
const total = parsed.metadata?.vulnerabilities?.total ?? 'unknown';
|
|
1878
|
+
const high = parsed.metadata?.vulnerabilities?.high ?? 'unknown';
|
|
1879
|
+
const critical = parsed.metadata?.vulnerabilities?.critical ?? 'unknown';
|
|
1880
|
+
context = status === 0
|
|
1881
|
+
? 'OMK npm audit summary: passed for high+ prod dependencies. total=' + total + ', high=' + high + ', critical=' + critical + '.'
|
|
1882
|
+
: 'OMK npm audit summary: attention required. total=' + total + ', high=' + high + ', critical=' + critical + '. Inspect npm audit output before release.';
|
|
1883
|
+
} catch {
|
|
1884
|
+
context = status === 0
|
|
1885
|
+
? 'OMK npm audit summary: command completed but JSON could not be parsed.'
|
|
1886
|
+
: 'OMK npm audit summary: npm audit failed or returned non-JSON output; inspect command output before release.';
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
process.stdout.write(JSON.stringify({
|
|
1890
|
+
systemMessage: context,
|
|
1891
|
+
}) + '\\n');
|
|
1892
|
+
NODE
|
|
1893
|
+
rm -f "$TMP"
|
|
1894
|
+
`,
|
|
1895
|
+
"post-init-mcp.sh": `#!/usr/bin/env bash
|
|
1896
|
+
# Post-init MCP validation — non-blocking health check after omk init
|
|
1897
|
+
set -uo pipefail
|
|
1898
|
+
|
|
1899
|
+
LOG_DIR=".omk/logs"
|
|
1900
|
+
mkdir -p "$LOG_DIR"
|
|
1901
|
+
LOG_FILE="$LOG_DIR/mcp-init-check.json"
|
|
1902
|
+
|
|
1903
|
+
# Run doctor silently and capture JSON output if available
|
|
1904
|
+
if command -v omk &>/dev/null; then
|
|
1905
|
+
omk mcp doctor --json 2>/dev/null > "$LOG_FILE" || true
|
|
1906
|
+
else
|
|
1907
|
+
echo '{"note":"omk not in PATH during hook execution"}' > "$LOG_FILE"
|
|
1908
|
+
fi
|
|
1909
|
+
`,
|
|
1910
|
+
};
|
|
1911
|
+
const KIMI_CONFIG_TOML = `# open-multi-agent-kit generated Kimi adapter config
|
|
1912
|
+
# Lifecycle hook settings
|
|
1913
|
+
|
|
1914
|
+
[[hooks]]
|
|
1915
|
+
event = "SessionStart"
|
|
1916
|
+
command = ".omk/hooks/session-context.sh"
|
|
1917
|
+
timeout = 5
|
|
1918
|
+
|
|
1919
|
+
[[hooks]]
|
|
1920
|
+
event = "PreCompact"
|
|
1921
|
+
command = ".omk/hooks/precompact-checkpoint.sh"
|
|
1922
|
+
timeout = 5
|
|
1923
|
+
|
|
1924
|
+
[[hooks]]
|
|
1925
|
+
event = "SubagentStop"
|
|
1926
|
+
command = ".omk/hooks/subagent-stop-audit.sh"
|
|
1927
|
+
timeout = 5
|
|
1928
|
+
|
|
1929
|
+
[[hooks]]
|
|
1930
|
+
event = "PreToolUse"
|
|
1931
|
+
matcher = "Shell"
|
|
1932
|
+
command = ".omk/hooks/pre-shell-guard.sh"
|
|
1933
|
+
timeout = 5
|
|
1934
|
+
|
|
1935
|
+
[[hooks]]
|
|
1936
|
+
event = "PreToolUse"
|
|
1937
|
+
matcher = "WriteFile|StrReplaceFile"
|
|
1938
|
+
command = ".omk/hooks/protect-secrets.sh"
|
|
1939
|
+
timeout = 5
|
|
1940
|
+
|
|
1941
|
+
[[hooks]]
|
|
1942
|
+
event = "Stop"
|
|
1943
|
+
command = ".omk/hooks/stop-verify.sh"
|
|
1944
|
+
timeout = 30
|
|
1945
|
+
`;
|
|
1946
|
+
const DEFAULT_PROJECT_MCP_COMMENT = "Project-local MCP config. omk-project is virtual runtime MCP injected; global MCP servers remain in ~/.kimi/mcp.json and must be imported explicitly only after secret review.";
|
|
1947
|
+
export function createOmkProjectMcpServer(projectRoot, options = {}) {
|
|
1948
|
+
// Use the concrete Node executable that launched init instead of a bare
|
|
1949
|
+
// `node` lookup. MCP clients often run with a reduced/isolated PATH, which
|
|
1950
|
+
// can accidentally pick a different Node ABI than the one used by npm install
|
|
1951
|
+
// and trigger native addon errors such as NODE_MODULE_VERSION mismatches.
|
|
1952
|
+
const isWin = (options.platform ?? process.platform) === "win32";
|
|
1953
|
+
const env = { OMK_PROJECT_ROOT: projectRoot };
|
|
1954
|
+
const node = stableNodeExecutable();
|
|
1955
|
+
return {
|
|
1956
|
+
command: isWin ? "omk" : "bash",
|
|
1957
|
+
args: isWin ? ["mcp", "serve", "omk-project"] : ["-lc", createUnixOmkProjectMcpScript(node)],
|
|
1958
|
+
env,
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
function createUnixOmkProjectMcpScript(node) {
|
|
1962
|
+
const quotedNode = shellQuote(node);
|
|
1963
|
+
const resolveRealpathScript = "const fs=require('fs');process.stdout.write(fs.realpathSync(process.argv[1]))";
|
|
1964
|
+
return [
|
|
1965
|
+
"set -e",
|
|
1966
|
+
'omk_bin="$(command -v omk 2>/dev/null || true)"',
|
|
1967
|
+
'if [ -n "$omk_bin" ]; then',
|
|
1968
|
+
` omk_cli="$(${quotedNode} -e ${shellQuote(resolveRealpathScript)} "$omk_bin" 2>/dev/null || true)"`,
|
|
1969
|
+
' if [ -n "$omk_cli" ]; then',
|
|
1970
|
+
` exec ${quotedNode} "$omk_cli" mcp serve omk-project`,
|
|
1971
|
+
" fi",
|
|
1972
|
+
"fi",
|
|
1973
|
+
'mcp_bin="$(command -v omk-project-mcp 2>/dev/null || true)"',
|
|
1974
|
+
'if [ -n "$mcp_bin" ]; then',
|
|
1975
|
+
` mcp_js="$(${quotedNode} -e ${shellQuote(resolveRealpathScript)} "$mcp_bin" 2>/dev/null || true)"`,
|
|
1976
|
+
' if [ -n "$mcp_js" ]; then',
|
|
1977
|
+
` exec ${quotedNode} "$mcp_js"`,
|
|
1978
|
+
" fi",
|
|
1979
|
+
"fi",
|
|
1980
|
+
'echo "omk-project MCP server not found; install OMK or rerun omk init" >&2',
|
|
1981
|
+
"exit 127",
|
|
1982
|
+
].join("\n");
|
|
1983
|
+
}
|
|
1984
|
+
function stableNodeExecutable() {
|
|
1985
|
+
try {
|
|
1986
|
+
return realpathSync(process.execPath);
|
|
1987
|
+
}
|
|
1988
|
+
catch {
|
|
1989
|
+
return process.execPath || "node";
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
function shellQuote(value) {
|
|
1993
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
1994
|
+
}
|
|
1995
|
+
function createMcpJson(_projectRoot) {
|
|
1996
|
+
return {
|
|
1997
|
+
mcpServers: {
|
|
1998
|
+
// omk-project is now auto-injected at runtime by injectKimiGlobals.
|
|
1999
|
+
// Project-local .omk/mcp.json only needs to hold user-added MCP servers.
|
|
2000
|
+
},
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
async function ensureProjectMcpConfig(path, fallback, options = {}) {
|
|
2004
|
+
const existing = await readFile(path, "utf-8").catch(() => null);
|
|
2005
|
+
if (!existing) {
|
|
2006
|
+
await writeFile(path, JSON.stringify(fallback, null, 2) + "\n");
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
try {
|
|
2010
|
+
const parsed = JSON.parse(existing);
|
|
2011
|
+
if (options.removeRuntimeManagedOmkProject && parsed.mcpServers?.["omk-project"]) {
|
|
2012
|
+
delete parsed.mcpServers["omk-project"];
|
|
2013
|
+
await writeFile(path, JSON.stringify(parsed, null, 2) + "\n");
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
catch {
|
|
2017
|
+
// Preserve malformed user-owned MCP config rather than overwriting custom entries.
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
function getConfigToml(options) {
|
|
2021
|
+
const { mcpScope, skillsScope, hooksScope } = options;
|
|
2022
|
+
return `# OMK project settings
|
|
2023
|
+
[project]
|
|
2024
|
+
name = "my-project"
|
|
2025
|
+
description = ""
|
|
2026
|
+
|
|
2027
|
+
[orchestration]
|
|
2028
|
+
default_workers = 4
|
|
2029
|
+
max_retries = 3
|
|
2030
|
+
approval_policy = "yolo" # low-friction SWE/benchmark mode: auto-allow tool use
|
|
2031
|
+
execution_prompt = "ask" # ask | auto | parallel | sequential
|
|
2032
|
+
yolo_mode = true # minimal hard stops only; avoid benchmark-stalling prompts
|
|
2033
|
+
|
|
2034
|
+
[runtime]
|
|
2035
|
+
# auto chooses lite on <=18GB RAM hosts to make 16GB laptops usable.
|
|
2036
|
+
resource_profile = "auto" # auto | lite | standard
|
|
2037
|
+
mcp_scope = "${mcpScope}" # all | project | none — all also reads user ~/.kimi/mcp.json at runtime
|
|
2038
|
+
skills_scope = "${skillsScope}" # all | project | none — all reads user ~/.kimi/skills without copying them
|
|
2039
|
+
hooks_scope = "${hooksScope}" # all | project | none — all reads user ~/.kimi hooks without copying them
|
|
2040
|
+
max_workers = 4 # can override with OMK_MAX_WORKERS
|
|
2041
|
+
max_output_mb = 4 # cap buffered shell/quality output
|
|
2042
|
+
wire_output_mb = 1 # cap per-task retained wire output
|
|
2043
|
+
|
|
2044
|
+
[ensemble]
|
|
2045
|
+
# Role-aware agent ensemble. Keep max_parallel=1 for 16GB/WSL safety.
|
|
2046
|
+
enabled = true
|
|
2047
|
+
max_candidates_per_node = 2
|
|
2048
|
+
max_parallel = 2
|
|
2049
|
+
quorum_ratio = 0.5
|
|
2050
|
+
|
|
2051
|
+
[quality]
|
|
2052
|
+
lint = "auto" # auto | command
|
|
2053
|
+
test = "auto"
|
|
2054
|
+
typecheck = "auto"
|
|
2055
|
+
build = "auto"
|
|
2056
|
+
|
|
2057
|
+
[memory]
|
|
2058
|
+
# Project-local ontology graph is the default source of truth for project/session memory.
|
|
2059
|
+
# Use backend = "kuzu" for the embedded Kuzu ontology graph backend.
|
|
2060
|
+
backend = "local_graph" # local_graph | kuzu
|
|
2061
|
+
scope = "project-session"
|
|
2062
|
+
strict = true # fail memory writes if the selected graph backend is unavailable
|
|
2063
|
+
mirror_files = true # keep .omk/memory/*.md as readable mirrors
|
|
2064
|
+
migrate_files = true # seed the graph from existing .omk/memory files on first read
|
|
2065
|
+
|
|
2066
|
+
[local_graph]
|
|
2067
|
+
path = ".omk/memory/graph-state.json"
|
|
2068
|
+
ontology = "omk-ontology-mindmap-v1"
|
|
2069
|
+
query = "graphql-lite"
|
|
2070
|
+
|
|
2071
|
+
|
|
2072
|
+
[locale]
|
|
2073
|
+
# UI language: en (default) | ko | ja
|
|
2074
|
+
language = "en"
|
|
2075
|
+
|
|
2076
|
+
[theme]
|
|
2077
|
+
# Optional custom logo image path for terminal welcome banner.
|
|
2078
|
+
# omk init does not create or copy image assets; add your own asset first, then uncomment.
|
|
2079
|
+
# Relative paths are resolved from project root; absolute paths require OMK_TRUST_ABSOLUTE_LOGO_PATH=1.
|
|
2080
|
+
# Supported formats: PNG, JPEG, GIF, WEBP (high-res on iTerm/Konsole, else ANSI block).
|
|
2081
|
+
# logo_image = "assets/omk-logo.png"
|
|
2082
|
+
|
|
2083
|
+
[router]
|
|
2084
|
+
default_model = "kimi-k2.6"
|
|
2085
|
+
# off | medium | high | xhigh | max
|
|
2086
|
+
research_thinking = "off"
|
|
2087
|
+
coding_thinking = "high"
|
|
2088
|
+
`;
|
|
2089
|
+
}
|
|
2090
|
+
const MEMORY_FILES = {
|
|
2091
|
+
"project.md": "# Project Memory\n\nProject-local graph memory is the source of truth; this file is a human-readable mirror.\n\n## Runtime Surfaces\n\n- Follow AGENTS.md and .kimi/AGENTS.md for active agent policy.\n- Use chat-agent-harness.json when present for MCP/skills/hooks inventory, worker limits, authority boundaries, and gates.\n- Keep .omk/memory mirrors free of secrets and private user data.\n",
|
|
2092
|
+
"decisions.md": "# Decisions\n\nRecord durable architecture, release, runtime, and safety decisions.\n\nFor each decision, include:\n\n- date and short title\n- affected files or surfaces\n- evidence commands or artifacts\n- rollback or revisit trigger\n\nNever store secrets, raw MCP env, tokens, or private user data.\n",
|
|
2093
|
+
"commands.md": "# Frequently Used Commands\n\nCommand mirror maintained alongside the local graph memory.\n\n```bash\nnpm run yaml:check\nnpm run lint\nnpm run secret:scan\nnpm run check\nnpm run build:clean\nnpm test\nnpm run audit:package\nnpm run pack:dry\nomk mcp doctor --json\nomk verify --json\n```\n\nUse targeted `npm test -- --match <pattern>` for focused regression loops before the full gate.\n",
|
|
2094
|
+
"risks.md": "# Known Risks\n\n- Do not store secrets, API keys, tokens, credentials, MCP env/header values, or private user data in memory.\n- `--local-user` and all-scope MCP/skills are runtime-only; do not copy global resources unless the user explicitly opts into `--import-user-skills`.\n- `chat-agent-harness.json` can contain private run inventory; summarize counts and gates, not full global inventories.\n- Working trees can contain unrelated edits; inspect `git status --short` before changes and avoid reverting user work.\n- Completion claims require evidence: tests, `omk verify --json`, replay/cockpit artifacts, or an explicit not-run reason.\n",
|
|
2095
|
+
};
|
|
2096
|
+
export async function initCommand(options) {
|
|
2097
|
+
const root = getProjectRoot();
|
|
2098
|
+
const initHomeDir = normalizeUserHomePath(options.homeDir) ?? getUserHome(options.env ?? process.env);
|
|
2099
|
+
const mcpJson = createMcpJson(root);
|
|
2100
|
+
console.log(header(`OMK init (profile: ${options.profile})`));
|
|
2101
|
+
const localUserRuntime = await resolveLocalUserRuntime(options, initHomeDir);
|
|
2102
|
+
// 1. Create directories (parallel)
|
|
2103
|
+
const dirs = [
|
|
2104
|
+
".omk/memory",
|
|
2105
|
+
".omk/runs",
|
|
2106
|
+
".omk/checkpoints",
|
|
2107
|
+
".omk/agents/roles",
|
|
2108
|
+
".omk/prompts/role-addons",
|
|
2109
|
+
".omk/hooks",
|
|
2110
|
+
".omk/worktrees",
|
|
2111
|
+
".omk/logs",
|
|
2112
|
+
".omk/snippets",
|
|
2113
|
+
".kimi/skills",
|
|
2114
|
+
".kimi/hooks",
|
|
2115
|
+
".agents/skills",
|
|
2116
|
+
];
|
|
2117
|
+
await Promise.all(dirs.map((d) => mkdir(join(root, d), { recursive: true })));
|
|
2118
|
+
// 2. Write AGENTS.md (skip if exists)
|
|
2119
|
+
const agentsMdPath = join(root, "AGENTS.md");
|
|
2120
|
+
if (await pathExists(agentsMdPath)) {
|
|
2121
|
+
console.log(t("init.agentsMdExists"));
|
|
2122
|
+
}
|
|
2123
|
+
else {
|
|
2124
|
+
const agentsMdContent = await readFile(join(packageRoot, "templates", "AGENTS.md"), "utf8");
|
|
2125
|
+
await writeFile(agentsMdPath, agentsMdContent);
|
|
2126
|
+
}
|
|
2127
|
+
// 2.5 Write .kimi/AGENTS.md (Kimi-specific rules)
|
|
2128
|
+
const kimiAgentsMdPath = join(root, ".kimi", "AGENTS.md");
|
|
2129
|
+
if (await pathExists(kimiAgentsMdPath)) {
|
|
2130
|
+
console.log(t("init.kimiAgentsMdExists"));
|
|
2131
|
+
}
|
|
2132
|
+
else {
|
|
2133
|
+
const kimiAgentsMdContent = await readFile(join(packageRoot, "templates", ".kimi", "AGENTS.md"), "utf8");
|
|
2134
|
+
await writeFile(kimiAgentsMdPath, kimiAgentsMdContent);
|
|
2135
|
+
}
|
|
2136
|
+
// 3. Write / migrate agents (parallel)
|
|
2137
|
+
const okabeYamlPath = join(root, ".omk/agents/okabe.yaml");
|
|
2138
|
+
await writeFile(okabeYamlPath, OKABE_AGENT_YAML);
|
|
2139
|
+
const rootYamlPath = join(root, ".omk/agents/root.yaml");
|
|
2140
|
+
if (await pathExists(rootYamlPath)) {
|
|
2141
|
+
// Existing root.yaml migration: fix relative path bug
|
|
2142
|
+
const existing = await readFile(rootYamlPath, "utf8");
|
|
2143
|
+
if (existing.includes("system_prompt_path: ./prompts/root.md")) {
|
|
2144
|
+
const migrated = existing.replace(/system_prompt_path:\s*\.\/prompts\/root\.md/, "system_prompt_path: ../prompts/root.md");
|
|
2145
|
+
await writeFile(rootYamlPath, migrated);
|
|
2146
|
+
console.log(status.ok(t("init.rootYamlMigrated")));
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
else {
|
|
2150
|
+
const rootAgentYaml = await readTemplateFile(join(".omk", "agents", "root.yaml"), ROOT_AGENT_YAML);
|
|
2151
|
+
await writeFile(rootYamlPath, rootAgentYaml);
|
|
2152
|
+
}
|
|
2153
|
+
await Promise.all(Object.entries(ROLE_YAMLS).map(async ([name, content]) => {
|
|
2154
|
+
const roleYaml = await readTemplateFile(join(".omk", "agents", "roles", `${name}.yaml`), content);
|
|
2155
|
+
await writeFile(join(root, ".omk/agents/roles", `${name}.yaml`), roleYaml);
|
|
2156
|
+
}));
|
|
2157
|
+
// 4. Write prompts
|
|
2158
|
+
const rootPromptMd = await readTemplateFile(join(".omk", "prompts", "root.md"), ROOT_PROMPT_MD);
|
|
2159
|
+
await writeFile(join(root, ".omk/prompts/root.md"), rootPromptMd);
|
|
2160
|
+
// 5+6. Copy package skill templates by default.
|
|
2161
|
+
// Fresh open-source init should reference only the maintainer-packaged OMK
|
|
2162
|
+
// skills. Local maintainers can explicitly opt into importing personal skills
|
|
2163
|
+
// with --import-user-skills or OMK_INIT_IMPORT_USER_SKILLS=1.
|
|
2164
|
+
const kimiSkillsSrc = join(packageRoot, "templates", "skills", "kimi");
|
|
2165
|
+
const agentsSkillsSrc = join(packageRoot, "templates", "skills", "agents");
|
|
2166
|
+
const skillCopies = [];
|
|
2167
|
+
const importUserSkills = shouldImportUserSkills(options);
|
|
2168
|
+
if (importUserSkills) {
|
|
2169
|
+
const personalSkillSources = [
|
|
2170
|
+
{
|
|
2171
|
+
label: "~/.kimi/skills",
|
|
2172
|
+
src: join(initHomeDir, ".kimi", "skills"),
|
|
2173
|
+
dest: join(root, ".kimi", "skills"),
|
|
2174
|
+
},
|
|
2175
|
+
{
|
|
2176
|
+
label: "~/.codex/skills",
|
|
2177
|
+
src: join(initHomeDir, ".codex", "skills"),
|
|
2178
|
+
dest: join(root, ".kimi", "skills"),
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
label: "~/.agents/skills",
|
|
2182
|
+
src: join(initHomeDir, ".agents", "skills"),
|
|
2183
|
+
dest: join(root, ".agents", "skills"),
|
|
2184
|
+
},
|
|
2185
|
+
];
|
|
2186
|
+
for (const source of personalSkillSources) {
|
|
2187
|
+
if (await pathExists(source.src)) {
|
|
2188
|
+
console.log(style.purple(` 📦 Importing ${source.label} (trusted local opt-in)...`));
|
|
2189
|
+
skillCopies.push(copySafeSkillRoot(source.src, source.dest).then((stats) => {
|
|
2190
|
+
if (stats.skippedUnsafe > 0) {
|
|
2191
|
+
console.log(status.warn(`Skipped ${stats.skippedUnsafe} secret-bearing skills from ${source.label}`));
|
|
2192
|
+
}
|
|
2193
|
+
if (stats.skippedUnavailable > 0) {
|
|
2194
|
+
console.log(status.warn(`Skipped ${stats.skippedUnavailable} unavailable skills from ${source.label}`));
|
|
2195
|
+
}
|
|
2196
|
+
}));
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
// Global skills symlink for local-user init
|
|
2201
|
+
let globalSkillsSymlinked = false;
|
|
2202
|
+
if (localUserRuntime && initHomeDir) {
|
|
2203
|
+
const globalKimiSkills = join(initHomeDir, ".kimi", "skills");
|
|
2204
|
+
if (await pathExists(globalKimiSkills)) {
|
|
2205
|
+
const dest = join(root, ".kimi", "skills");
|
|
2206
|
+
if (!(await pathExists(dest))) {
|
|
2207
|
+
console.log(style.purple(" 📦 Symlinking global ~/.kimi/skills..."));
|
|
2208
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
2209
|
+
try {
|
|
2210
|
+
await symlink(globalKimiSkills, dest, "dir");
|
|
2211
|
+
globalSkillsSymlinked = true;
|
|
2212
|
+
}
|
|
2213
|
+
catch (err) {
|
|
2214
|
+
console.warn(status.warn(`Failed to symlink global skills: ${err.message}`));
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
if (!globalSkillsSymlinked && await pathExists(kimiSkillsSrc)) {
|
|
2220
|
+
console.log(style.purple(t("init.copyKimiSkills")));
|
|
2221
|
+
skillCopies.push(copySafeSkillRoot(kimiSkillsSrc, join(root, ".kimi", "skills")).then(() => undefined));
|
|
2222
|
+
}
|
|
2223
|
+
else if (!globalSkillsSymlinked) {
|
|
2224
|
+
console.log(status.warn(t("init.kimiSkillsMissing")));
|
|
2225
|
+
}
|
|
2226
|
+
if (await pathExists(agentsSkillsSrc)) {
|
|
2227
|
+
console.log(style.purple(t("init.copyPortableSkills")));
|
|
2228
|
+
skillCopies.push(copySafeSkillRoot(agentsSkillsSrc, join(root, ".agents", "skills")).then(() => undefined));
|
|
2229
|
+
}
|
|
2230
|
+
else {
|
|
2231
|
+
console.log(status.warn(t("init.portableSkillsMissing")));
|
|
2232
|
+
}
|
|
2233
|
+
if (skillCopies.length > 0)
|
|
2234
|
+
await Promise.all(skillCopies);
|
|
2235
|
+
// 7. Write hooks (parallel)
|
|
2236
|
+
await Promise.all(Object.entries(HOOK_SCRIPTS).map(async ([name, content]) => {
|
|
2237
|
+
const hookPath = join(root, ".omk/hooks", name);
|
|
2238
|
+
await writeFile(hookPath, content, { mode: 0o755 });
|
|
2239
|
+
}));
|
|
2240
|
+
// 8. Write configs
|
|
2241
|
+
const runtimeScope = localUserRuntime ? "all" : "project";
|
|
2242
|
+
let configTomlContent = getConfigToml({
|
|
2243
|
+
mcpScope: runtimeScope,
|
|
2244
|
+
skillsScope: runtimeScope,
|
|
2245
|
+
hooksScope: runtimeScope,
|
|
2246
|
+
});
|
|
2247
|
+
if (localUserRuntime && initHomeDir) {
|
|
2248
|
+
const globalConfigPath = join(initHomeDir, ".omk", "config.toml");
|
|
2249
|
+
const globalConfig = await readFile(globalConfigPath, "utf-8").catch(() => null);
|
|
2250
|
+
if (globalConfig) {
|
|
2251
|
+
configTomlContent = globalConfig
|
|
2252
|
+
.replace(/^mcp_scope\s*=.*$/gm, `mcp_scope = "${runtimeScope}"`)
|
|
2253
|
+
.replace(/^skills_scope\s*=.*$/gm, `skills_scope = "${runtimeScope}"`)
|
|
2254
|
+
.replace(/^hooks_scope\s*=.*$/gm, `hooks_scope = "${runtimeScope}"`);
|
|
2255
|
+
console.log(style.purple(" 📦 Inheriting global .omk/config.toml defaults..."));
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
await writeFile(join(root, ".omk/config.toml"), configTomlContent);
|
|
2259
|
+
let kimiConfigContent = KIMI_CONFIG_TOML;
|
|
2260
|
+
if (localUserRuntime && initHomeDir) {
|
|
2261
|
+
const globalKimiConfigPath = join(initHomeDir, ".kimi", "config.toml");
|
|
2262
|
+
const globalKimiConfig = await readFile(globalKimiConfigPath, "utf-8").catch(() => null);
|
|
2263
|
+
if (globalKimiConfig) {
|
|
2264
|
+
kimiConfigContent = globalKimiConfig;
|
|
2265
|
+
console.log(style.purple(" 📦 Inheriting global ~/.kimi/config.toml..."));
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
await writeFile(join(root, ".omk/kimi.config.toml"), kimiConfigContent);
|
|
2269
|
+
await ensureProjectMcpConfig(join(root, ".omk/mcp.json"), mcpJson, { removeRuntimeManagedOmkProject: true });
|
|
2270
|
+
await writeFile(join(root, ".omk/theme.json"), createThemeJson());
|
|
2271
|
+
await writeFile(join(root, ".omk/runtime-preset.json"), JSON.stringify(OMK_CORE_VERIFIED_PRESET, null, 2) + "\n");
|
|
2272
|
+
await writeFile(join(root, ".omk/runtime-presets.json"), createRuntimePresetsJson());
|
|
2273
|
+
// Project-local server config must not import global definitions by default.
|
|
2274
|
+
const projectMcpPath = join(root, ".kimi", "mcp.json");
|
|
2275
|
+
const globalMcpPath = join(initHomeDir, ".kimi", "mcp.json");
|
|
2276
|
+
const hasGlobalMcp = localUserRuntime && initHomeDir && await pathExists(globalMcpPath);
|
|
2277
|
+
const mcpComment = hasGlobalMcp
|
|
2278
|
+
? "Project-local server config. Global entries are inherited from ~/.kimi/mcp.json at runtime when scope = 'all'."
|
|
2279
|
+
: DEFAULT_PROJECT_MCP_COMMENT;
|
|
2280
|
+
await ensureProjectMcpConfig(projectMcpPath, { _comment: mcpComment, mcpServers: {} }, { removeRuntimeManagedOmkProject: true });
|
|
2281
|
+
await writeFile(join(root, ".omk/lsp.json"), defaultLspConfigJson());
|
|
2282
|
+
// 9. Write memory files (parallel)
|
|
2283
|
+
await Promise.all(Object.entries(MEMORY_FILES).map(([name, content]) => writeFile(join(root, ".omk/memory", name), content)));
|
|
2284
|
+
// 9.5. Copy default snippet templates if they exist
|
|
2285
|
+
const snippetsSrc = join(packageRoot, "templates", "snippets");
|
|
2286
|
+
const snippetsDest = join(root, ".omk", "snippets");
|
|
2287
|
+
if (await pathExists(snippetsSrc)) {
|
|
2288
|
+
console.log(style.purple(" 📦 Copying snippet templates..."));
|
|
2289
|
+
await copyTemplateDir(snippetsSrc, snippetsDest);
|
|
2290
|
+
}
|
|
2291
|
+
// 9.6. Copy spec-kit OMK preset template
|
|
2292
|
+
const presetSrc = join(packageRoot, "templates", "spec-kit-omk-preset");
|
|
2293
|
+
const presetDest = join(root, ".omk", "templates", "spec-kit-omk-preset");
|
|
2294
|
+
if (await pathExists(presetSrc)) {
|
|
2295
|
+
console.log(style.purple(" 📦 Copying spec-kit OMK preset..."));
|
|
2296
|
+
await copyTemplateDir(presetSrc, presetDest);
|
|
2297
|
+
}
|
|
2298
|
+
// 10. Write project docs (skip if already exist)
|
|
2299
|
+
const docs = {
|
|
2300
|
+
"DESIGN.md": getDesignMd(getOmkVersionSync()),
|
|
2301
|
+
"GEMINI.md": GEMINI_MD,
|
|
2302
|
+
"CLAUDE.md": CLAUDE_MD,
|
|
2303
|
+
"ROADMAP.md": ROADMAP_MD,
|
|
2304
|
+
"SECURITY.md": SECURITY_MD,
|
|
2305
|
+
};
|
|
2306
|
+
for (const [name, content] of Object.entries(docs)) {
|
|
2307
|
+
const docPath = join(root, name);
|
|
2308
|
+
if (await pathExists(docPath)) {
|
|
2309
|
+
console.log(` ℹ️ ${name} already exists — skipping`);
|
|
2310
|
+
}
|
|
2311
|
+
else {
|
|
2312
|
+
await writeFile(docPath, content);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
console.log(status.success("OMK initialized."));
|
|
2316
|
+
console.log();
|
|
2317
|
+
console.log("Created:");
|
|
2318
|
+
console.log("- AGENTS.md");
|
|
2319
|
+
console.log("- .kimi/AGENTS.md");
|
|
2320
|
+
console.log("- DESIGN.md");
|
|
2321
|
+
console.log("- .omk/agents/root.yaml");
|
|
2322
|
+
console.log("- .omk/agents/roles/");
|
|
2323
|
+
console.log("- .omk/prompts/root.md");
|
|
2324
|
+
console.log("- .omk/config.toml");
|
|
2325
|
+
console.log("- .omk/kimi.config.toml");
|
|
2326
|
+
console.log("- .omk/lsp.json");
|
|
2327
|
+
console.log("- .omk/hooks/");
|
|
2328
|
+
console.log("- .omk/snippets/");
|
|
2329
|
+
console.log("- .kimi/mcp.json");
|
|
2330
|
+
console.log("- .omk/mcp.json");
|
|
2331
|
+
console.log("- .omk/theme.json");
|
|
2332
|
+
console.log("- .omk/runtime-preset.json");
|
|
2333
|
+
console.log("- .omk/runtime-presets.json");
|
|
2334
|
+
console.log("- .kimi/skills/");
|
|
2335
|
+
console.log("- .agents/skills/");
|
|
2336
|
+
console.log("- .omk/memory/");
|
|
2337
|
+
console.log("- .omk/templates/spec-kit-omk-preset/");
|
|
2338
|
+
console.log();
|
|
2339
|
+
console.log("Default behavior:");
|
|
2340
|
+
console.log("- AGENTS.md is loaded into Kimi root prompt.");
|
|
2341
|
+
console.log("- Todo list is required for multi-step work.");
|
|
2342
|
+
console.log("- Subagents are required for non-trivial work.");
|
|
2343
|
+
console.log("- Project skills are auto-discovered from .kimi/skills and .agents/skills.");
|
|
2344
|
+
console.log("- Runtime presets include omk-core-verified, omk-ts-product, omk-worktree-team, and omk-release-guard.");
|
|
2345
|
+
if (localUserRuntime) {
|
|
2346
|
+
console.log("- Local user runtime enabled: global ~/.kimi/mcp.json and ~/.kimi/skills are used at runtime.");
|
|
2347
|
+
console.log("- Personal/global MCP servers and skills are not copied into the project.");
|
|
2348
|
+
}
|
|
2349
|
+
else {
|
|
2350
|
+
console.log("- omk-project is virtual runtime MCP injected; project MCP files are for user-added servers, remote/global MCPs are explicit opt-in.");
|
|
2351
|
+
}
|
|
2352
|
+
console.log("- Built-in tools: SearchWeb, FetchURL (no config required).");
|
|
2353
|
+
console.log(style.gray(" Fresh init does not copy user-global skills or MCP servers into the project."));
|
|
2354
|
+
console.log(style.gray(" Trusted local users can add --local-user --home-dir <~/.kimi/mcp.json> for runtime-only global MCP/skills, or --import-user-skills to copy reviewed personal skills."));
|
|
2355
|
+
await runInitInteractiveSetup(options, initHomeDir);
|
|
2356
|
+
// Warn about environment variable files — OMK prefers config.toml for stability
|
|
2357
|
+
for (const envFile of [".env", ".env.local", ".env.development"]) {
|
|
2358
|
+
if (await pathExists(join(root, envFile))) {
|
|
2359
|
+
console.log(style.orange(`⚠️ Found ${envFile}. OMK recommends using .omk/config.toml instead of environment variable files for stability.`));
|
|
2360
|
+
break;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
// ── Shell integration & PATH check ──
|
|
2364
|
+
const pathCheck = await checkOmkInPath();
|
|
2365
|
+
if (!pathCheck.inPath) {
|
|
2366
|
+
console.log("");
|
|
2367
|
+
console.log(style.orange("⚠️ omk is not in PATH."));
|
|
2368
|
+
console.log(style.gray(" Run one of the following:"));
|
|
2369
|
+
console.log(style.gray(" 1) npm install -g @omk/cli"));
|
|
2370
|
+
console.log(style.gray(" 2) npm link (for development)"));
|
|
2371
|
+
console.log(style.gray(" 3) alias omk='npx -p @omk/cli omk'"));
|
|
2372
|
+
}
|
|
2373
|
+
else {
|
|
2374
|
+
await maybeInstallShellCompletion(root);
|
|
2375
|
+
}
|
|
2376
|
+
console.log("");
|
|
2377
|
+
console.log(style.purpleBold(" Next steps: ") + style.cream("omk doctor → omk chat"));
|
|
2378
|
+
}
|
|
2379
|
+
function isDisabledEnvValue(value) {
|
|
2380
|
+
return ["0", "false", "off", "no", "never"].includes(value?.trim().toLowerCase() ?? "");
|
|
2381
|
+
}
|
|
2382
|
+
function isEnabledEnvValue(value) {
|
|
2383
|
+
return ["1", "true", "on", "yes", "always"].includes(value?.trim().toLowerCase() ?? "");
|
|
2384
|
+
}
|
|
2385
|
+
function shouldImportUserSkills(options) {
|
|
2386
|
+
const env = options.env ?? process.env;
|
|
2387
|
+
return Boolean(options.importUserSkills) || isEnabledEnvValue(env.OMK_INIT_IMPORT_USER_SKILLS);
|
|
2388
|
+
}
|
|
2389
|
+
function explicitLocalUserRuntime(options) {
|
|
2390
|
+
const env = options.env ?? process.env;
|
|
2391
|
+
const profile = options.profile?.trim().toLowerCase() ?? "";
|
|
2392
|
+
if (Boolean(options.localUser)
|
|
2393
|
+
|| isEnabledEnvValue(env.OMK_INIT_LOCAL_USER)
|
|
2394
|
+
|| ["local", "personal", "trusted-local"].includes(profile)) {
|
|
2395
|
+
return true;
|
|
2396
|
+
}
|
|
2397
|
+
if (isDisabledEnvValue(env.OMK_INIT_LOCAL_USER))
|
|
2398
|
+
return false;
|
|
2399
|
+
return undefined;
|
|
2400
|
+
}
|
|
2401
|
+
async function resolveLocalUserRuntime(options, homeDir) {
|
|
2402
|
+
const explicit = explicitLocalUserRuntime(options);
|
|
2403
|
+
if (explicit !== undefined)
|
|
2404
|
+
return explicit;
|
|
2405
|
+
if (!isInitInteractiveSetupEligible(options))
|
|
2406
|
+
return false;
|
|
2407
|
+
return askLocalUserRuntimeDuringInit(options, homeDir);
|
|
2408
|
+
}
|
|
2409
|
+
async function askLocalUserRuntimeDuringInit(options, homeDir) {
|
|
2410
|
+
try {
|
|
2411
|
+
const useLocalGlobal = options.promptLocalUserRuntime
|
|
2412
|
+
? await options.promptLocalUserRuntime({ homeDir })
|
|
2413
|
+
: await confirm({
|
|
2414
|
+
message: "MCP 설정: 기존 로컬 글로벌 ~/.kimi MCP/skills를 그대로 사용할까요? (No = omk-project만 시작하고 여기서 MCP를 추가)",
|
|
2415
|
+
default: false,
|
|
2416
|
+
});
|
|
2417
|
+
if (useLocalGlobal) {
|
|
2418
|
+
console.log(status.ok("Init MCP mode: using local/global ~/.kimi MCP and skills at runtime."));
|
|
2419
|
+
}
|
|
2420
|
+
else {
|
|
2421
|
+
console.log(style.gray("Init MCP mode: project only; start with omk-project and add MCPs here later."));
|
|
2422
|
+
}
|
|
2423
|
+
return useLocalGlobal;
|
|
2424
|
+
}
|
|
2425
|
+
catch (error) {
|
|
2426
|
+
if (error instanceof ExitPromptError)
|
|
2427
|
+
return false;
|
|
2428
|
+
console.log(status.warn(`MCP runtime prompt failed; falling back to project-only mode: ${redactSecretishText(error)}`));
|
|
2429
|
+
return false;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
function isInitInteractiveSetupEligible(options) {
|
|
2433
|
+
const env = options.env ?? process.env;
|
|
2434
|
+
const stdin = options.stdin ?? process.stdin;
|
|
2435
|
+
const stdout = options.stdout ?? process.stdout;
|
|
2436
|
+
if (options.interactiveSetup === false)
|
|
2437
|
+
return false;
|
|
2438
|
+
if (isDisabledEnvValue(env.OMK_INIT_PROMPTS))
|
|
2439
|
+
return false;
|
|
2440
|
+
if (env.CI || env.GITHUB_ACTIONS)
|
|
2441
|
+
return false;
|
|
2442
|
+
return Boolean(stdin.isTTY && stdout.isTTY);
|
|
2443
|
+
}
|
|
2444
|
+
async function runMcpServerSelectionDuringInit(options) {
|
|
2445
|
+
if (!isInitInteractiveSetupEligible(options))
|
|
2446
|
+
return;
|
|
2447
|
+
const env = options.env ?? process.env;
|
|
2448
|
+
if (isDisabledEnvValue(env.OMK_INIT_MCP_SERVERS))
|
|
2449
|
+
return;
|
|
2450
|
+
try {
|
|
2451
|
+
const defaultSelections = getDefaultSelections();
|
|
2452
|
+
const choices = RECOMMENDED_MCP_SERVERS.map((server) => ({
|
|
2453
|
+
name: `${server.name} — ${server.description} [${server.category}]`,
|
|
2454
|
+
value: server,
|
|
2455
|
+
checked: defaultSelections.includes(server.name),
|
|
2456
|
+
}));
|
|
2457
|
+
const { checkbox: checkboxPrompt } = await import("@inquirer/prompts");
|
|
2458
|
+
const selected = await checkboxPrompt({
|
|
2459
|
+
message: "Select additional MCP servers to install (Space to toggle, Enter to confirm):",
|
|
2460
|
+
choices,
|
|
2461
|
+
});
|
|
2462
|
+
if (!selected || selected.length === 0) {
|
|
2463
|
+
console.log(style.gray("No additional MCP servers selected."));
|
|
2464
|
+
return;
|
|
2465
|
+
}
|
|
2466
|
+
console.log(style.purple(` 📦 Installing ${selected.length} MCP server(s) in parallel...`));
|
|
2467
|
+
const root = getProjectRoot();
|
|
2468
|
+
const entries = selected.map((server) => ({
|
|
2469
|
+
name: server.name,
|
|
2470
|
+
command: server.command,
|
|
2471
|
+
args: server.args.map((arg) => arg.replace("${PROJECT_ROOT}", root).replace("${DB_PATH}", join(root, ".omk", "memory", "graph.db"))),
|
|
2472
|
+
env: server.env,
|
|
2473
|
+
startupTimeoutSec: server.startupTimeoutSec,
|
|
2474
|
+
}));
|
|
2475
|
+
const result = await mcpBulkInstallCommand(entries);
|
|
2476
|
+
for (const name of result.installed) {
|
|
2477
|
+
console.log(status.ok(`Installed MCP server: ${name}`));
|
|
2478
|
+
}
|
|
2479
|
+
for (const name of result.skipped) {
|
|
2480
|
+
console.log(style.gray(`Skipped (already exists): ${name}`));
|
|
2481
|
+
}
|
|
2482
|
+
for (const { name, error } of result.failed) {
|
|
2483
|
+
console.log(status.warn(`Failed to install ${name}: ${error}`));
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
catch (error) {
|
|
2487
|
+
if (error instanceof ExitPromptError)
|
|
2488
|
+
return;
|
|
2489
|
+
console.log(status.warn(`MCP server selection failed: ${redactSecretishText(error)}`));
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
async function runInitInteractiveSetup(options, homeDir) {
|
|
2493
|
+
if (!isInitInteractiveSetupEligible(options))
|
|
2494
|
+
return;
|
|
2495
|
+
await maybeAskForGitHubStar({
|
|
2496
|
+
version: getOmkVersionSync(),
|
|
2497
|
+
homeDir,
|
|
2498
|
+
env: options.env,
|
|
2499
|
+
argv: options.argv ?? ["node", "omk", "init"],
|
|
2500
|
+
stdin: options.stdin,
|
|
2501
|
+
stdout: options.stdout,
|
|
2502
|
+
commandName: "init",
|
|
2503
|
+
prompt: options.promptGitHubStar,
|
|
2504
|
+
starRepo: options.starRepo,
|
|
2505
|
+
});
|
|
2506
|
+
await runMcpServerSelectionDuringInit(options);
|
|
2507
|
+
await maybeAskForDeepSeekApiKeyDuringInit(options, homeDir);
|
|
2508
|
+
}
|
|
2509
|
+
async function maybeAskForDeepSeekApiKeyDuringInit(options, homeDir) {
|
|
2510
|
+
const env = options.env ?? process.env;
|
|
2511
|
+
if (isDisabledEnvValue(env.OMK_INIT_DEEPSEEK_PROMPT))
|
|
2512
|
+
return;
|
|
2513
|
+
try {
|
|
2514
|
+
const providerOptions = { env, homeDir };
|
|
2515
|
+
const currentStatus = await getDeepSeekProviderStatus(providerOptions);
|
|
2516
|
+
if (currentStatus.apiKeySet) {
|
|
2517
|
+
console.log(style.gray(t("init.deepseekAlreadyConfigured")));
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
const shouldConfigure = options.promptDeepSeekSetup
|
|
2521
|
+
? await options.promptDeepSeekSetup()
|
|
2522
|
+
: await confirm({
|
|
2523
|
+
message: t("init.deepseekPrompt"),
|
|
2524
|
+
default: false,
|
|
2525
|
+
});
|
|
2526
|
+
if (!shouldConfigure)
|
|
2527
|
+
return;
|
|
2528
|
+
const enteredCredential = options.promptDeepSeekApiKey
|
|
2529
|
+
? await options.promptDeepSeekApiKey()
|
|
2530
|
+
: await password({
|
|
2531
|
+
message: t("init.deepseekKeyPrompt"),
|
|
2532
|
+
mask: "*",
|
|
2533
|
+
});
|
|
2534
|
+
await setDeepSeekApiKey(enteredCredential, providerOptions);
|
|
2535
|
+
console.log(status.ok(t("init.deepseekSaved")));
|
|
2536
|
+
}
|
|
2537
|
+
catch (error) {
|
|
2538
|
+
if (error instanceof ExitPromptError)
|
|
2539
|
+
return;
|
|
2540
|
+
console.log(status.warn(t("init.deepseekSetupFailed", redactSecretishText(error))));
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
function redactSecretishText(error) {
|
|
2544
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2545
|
+
return message
|
|
2546
|
+
.replace(/sk-[A-Za-z0-9_-]{12,}/g, "[redacted]")
|
|
2547
|
+
.replace(/Bearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, "Bearer [redacted]");
|
|
2548
|
+
}
|
|
2549
|
+
async function checkOmkInPath() {
|
|
2550
|
+
try {
|
|
2551
|
+
const result = await import("../util/shell.js").then((m) => m.runShell("which", ["omk"], { timeout: 3000 }));
|
|
2552
|
+
return { inPath: !result.failed && result.stdout.trim().length > 0 };
|
|
2553
|
+
}
|
|
2554
|
+
catch {
|
|
2555
|
+
return { inPath: false };
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
async function maybeInstallShellCompletion(_root) {
|
|
2559
|
+
const bashrc = join(process.env.HOME || process.env.USERPROFILE || "", ".bashrc");
|
|
2560
|
+
const zshrc = join(process.env.HOME || process.env.USERPROFILE || "", ".zshrc");
|
|
2561
|
+
const omkAliasBlock = `# >>> omk shell integration
|
|
2562
|
+
export OMK_STAR_PROMPT=1
|
|
2563
|
+
export OMK_RENDER_LOGO=1
|
|
2564
|
+
# <<< end omk shell integration`;
|
|
2565
|
+
for (const rcFile of [bashrc, zshrc]) {
|
|
2566
|
+
if (!(await pathExists(rcFile)))
|
|
2567
|
+
continue;
|
|
2568
|
+
try {
|
|
2569
|
+
const content = await readFile(rcFile, "utf-8");
|
|
2570
|
+
if (content.includes("omk shell integration"))
|
|
2571
|
+
continue;
|
|
2572
|
+
const tmpRc = rcFile + ".omk.tmp";
|
|
2573
|
+
await writeFile(tmpRc, content.trimEnd() + "\n\n" + omkAliasBlock + "\n");
|
|
2574
|
+
await rename(tmpRc, rcFile);
|
|
2575
|
+
console.log(status.ok(`Shell integration added: ${rcFile}`));
|
|
2576
|
+
}
|
|
2577
|
+
catch {
|
|
2578
|
+
// ignore
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|