oc-pilot 0.5.1 → 0.88.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +683 -0
- package/CONTRIBUTING.md +4 -2
- package/README.md +588 -20
- package/README.ru.md +572 -10
- package/dist/cli.js +185 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +1211 -1
- package/dist/cli.test.js.map +1 -1
- package/dist/commands/anti-regression.js +97 -0
- package/dist/commands/anti-regression.js.map +1 -0
- package/dist/commands/arch-diff.js +80 -0
- package/dist/commands/arch-diff.js.map +1 -0
- package/dist/commands/authz.js +167 -0
- package/dist/commands/authz.js.map +1 -0
- package/dist/commands/autopsy.js +64 -0
- package/dist/commands/autopsy.js.map +1 -0
- package/dist/commands/bankruptcy.js +60 -0
- package/dist/commands/bankruptcy.js.map +1 -0
- package/dist/commands/battle.js +119 -0
- package/dist/commands/battle.js.map +1 -0
- package/dist/commands/boundaries.js +114 -0
- package/dist/commands/boundaries.js.map +1 -0
- package/dist/commands/bounty.js +56 -0
- package/dist/commands/bounty.js.map +1 -0
- package/dist/commands/brag.js +62 -0
- package/dist/commands/brag.js.map +1 -0
- package/dist/commands/cache.js +62 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/cinema.js +61 -0
- package/dist/commands/cinema.js.map +1 -0
- package/dist/commands/cleanup.js +110 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/commit.js +177 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/commit.test.js +160 -0
- package/dist/commands/commit.test.js.map +1 -0
- package/dist/commands/compliance.js +121 -0
- package/dist/commands/compliance.js.map +1 -0
- package/dist/commands/contract-drift.js +97 -0
- package/dist/commands/contract-drift.js.map +1 -0
- package/dist/commands/coverage.js +137 -0
- package/dist/commands/coverage.js.map +1 -0
- package/dist/commands/day.js +116 -0
- package/dist/commands/day.js.map +1 -0
- package/dist/commands/day.test.js +45 -0
- package/dist/commands/day.test.js.map +1 -0
- package/dist/commands/deps.js +245 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/docgen.js +4 -2
- package/dist/commands/docgen.js.map +1 -1
- package/dist/commands/doctor.js +146 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +69 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/echo.js +78 -0
- package/dist/commands/echo.js.map +1 -0
- package/dist/commands/ecosystem-verify.js +113 -0
- package/dist/commands/ecosystem-verify.js.map +1 -0
- package/dist/commands/env-sync.js +102 -0
- package/dist/commands/env-sync.js.map +1 -0
- package/dist/commands/explain.js +115 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/fix.js +145 -3
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/flaky.js +111 -0
- package/dist/commands/flaky.js.map +1 -0
- package/dist/commands/fuzz.js +119 -0
- package/dist/commands/fuzz.js.map +1 -0
- package/dist/commands/hivemind.js +124 -0
- package/dist/commands/hivemind.js.map +1 -0
- package/dist/commands/impact.js +73 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/init.js +73 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/init.test.js +138 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/install-hook.js +161 -0
- package/dist/commands/install-hook.js.map +1 -0
- package/dist/commands/install-hook.test.js +100 -0
- package/dist/commands/install-hook.test.js.map +1 -0
- package/dist/commands/invariants.js +103 -0
- package/dist/commands/invariants.js.map +1 -0
- package/dist/commands/mock-leak.js +97 -0
- package/dist/commands/mock-leak.js.map +1 -0
- package/dist/commands/mutate.js +99 -0
- package/dist/commands/mutate.js.map +1 -0
- package/dist/commands/pack.js +144 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/preflight.js +137 -0
- package/dist/commands/preflight.js.map +1 -0
- package/dist/commands/query.js +57 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/ready.js +152 -0
- package/dist/commands/ready.js.map +1 -0
- package/dist/commands/receipt.js +289 -0
- package/dist/commands/receipt.js.map +1 -0
- package/dist/commands/replay.js +112 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/replay.test.js +125 -0
- package/dist/commands/replay.test.js.map +1 -0
- package/dist/commands/restore.js +54 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/review.js +263 -4
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/review.test.js +160 -0
- package/dist/commands/review.test.js.map +1 -0
- package/dist/commands/reviewers.js +86 -0
- package/dist/commands/reviewers.js.map +1 -0
- package/dist/commands/roast.js +102 -0
- package/dist/commands/roast.js.map +1 -0
- package/dist/commands/sandbox.js +82 -0
- package/dist/commands/sandbox.js.map +1 -0
- package/dist/commands/sast.js +162 -0
- package/dist/commands/sast.js.map +1 -0
- package/dist/commands/scan.js +47 -12
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/slop.js +145 -0
- package/dist/commands/slop.js.map +1 -0
- package/dist/commands/slop.test.js +135 -0
- package/dist/commands/slop.test.js.map +1 -0
- package/dist/commands/stats.js +61 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/test-gen.js +372 -0
- package/dist/commands/test-gen.js.map +1 -0
- package/dist/commands/test-guard.js +89 -0
- package/dist/commands/test-guard.js.map +1 -0
- package/dist/commands/test-plan.js +133 -0
- package/dist/commands/test-plan.js.map +1 -0
- package/dist/commands/zoom-symbol.js +52 -0
- package/dist/commands/zoom-symbol.js.map +1 -0
- package/dist/core/agent-rules.js +35 -0
- package/dist/core/agent-rules.js.map +1 -0
- package/dist/core/anthropic.test.js +116 -0
- package/dist/core/anthropic.test.js.map +1 -0
- package/dist/core/anti-regression.js +161 -0
- package/dist/core/anti-regression.js.map +1 -0
- package/dist/core/anti-regression.test.js +154 -0
- package/dist/core/anti-regression.test.js.map +1 -0
- package/dist/core/aql.js +220 -0
- package/dist/core/aql.js.map +1 -0
- package/dist/core/aql.test.js +64 -0
- package/dist/core/aql.test.js.map +1 -0
- package/dist/core/arch-diff.js +122 -0
- package/dist/core/arch-diff.js.map +1 -0
- package/dist/core/arch-diff.test.js +93 -0
- package/dist/core/arch-diff.test.js.map +1 -0
- package/dist/core/authz.js +292 -0
- package/dist/core/authz.js.map +1 -0
- package/dist/core/authz.test.js +115 -0
- package/dist/core/authz.test.js.map +1 -0
- package/dist/core/autopsy.js +230 -0
- package/dist/core/autopsy.js.map +1 -0
- package/dist/core/autopsy.test.js +106 -0
- package/dist/core/autopsy.test.js.map +1 -0
- package/dist/core/bankruptcy.js +232 -0
- package/dist/core/bankruptcy.js.map +1 -0
- package/dist/core/bankruptcy.test.js +91 -0
- package/dist/core/bankruptcy.test.js.map +1 -0
- package/dist/core/baseline.js +131 -0
- package/dist/core/baseline.js.map +1 -0
- package/dist/core/baseline.test.js +91 -0
- package/dist/core/baseline.test.js.map +1 -0
- package/dist/core/battle.js +213 -0
- package/dist/core/battle.js.map +1 -0
- package/dist/core/battle.test.js +116 -0
- package/dist/core/battle.test.js.map +1 -0
- package/dist/core/boundaries.js +200 -0
- package/dist/core/boundaries.js.map +1 -0
- package/dist/core/boundaries.test.js +62 -0
- package/dist/core/boundaries.test.js.map +1 -0
- package/dist/core/bounty.js +128 -0
- package/dist/core/bounty.js.map +1 -0
- package/dist/core/bounty.test.js +82 -0
- package/dist/core/bounty.test.js.map +1 -0
- package/dist/core/brag.js +174 -0
- package/dist/core/brag.js.map +1 -0
- package/dist/core/brag.test.js +43 -0
- package/dist/core/brag.test.js.map +1 -0
- package/dist/core/cache.js +189 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/cache.test.js +159 -0
- package/dist/core/cache.test.js.map +1 -0
- package/dist/core/cinema.js +242 -0
- package/dist/core/cinema.js.map +1 -0
- package/dist/core/cinema.test.js +73 -0
- package/dist/core/cinema.test.js.map +1 -0
- package/dist/core/cleanup.js +107 -0
- package/dist/core/cleanup.js.map +1 -0
- package/dist/core/compliance.js +193 -0
- package/dist/core/compliance.js.map +1 -0
- package/dist/core/compliance.test.js +123 -0
- package/dist/core/compliance.test.js.map +1 -0
- package/dist/core/config.js +78 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/config.test.js +66 -0
- package/dist/core/config.test.js.map +1 -1
- package/dist/core/contract-drift.js +296 -0
- package/dist/core/contract-drift.js.map +1 -0
- package/dist/core/contract-drift.test.js +166 -0
- package/dist/core/contract-drift.test.js.map +1 -0
- package/dist/core/cost.test.js +103 -0
- package/dist/core/cost.test.js.map +1 -0
- package/dist/core/coverage.js +335 -0
- package/dist/core/coverage.js.map +1 -0
- package/dist/core/coverage.test.js +190 -0
- package/dist/core/coverage.test.js.map +1 -0
- package/dist/core/deps-fix.js +169 -0
- package/dist/core/deps-fix.js.map +1 -0
- package/dist/core/deps-fix.test.js +176 -0
- package/dist/core/deps-fix.test.js.map +1 -0
- package/dist/core/deps-health.js +353 -0
- package/dist/core/deps-health.js.map +1 -0
- package/dist/core/deps-health.test.js +230 -0
- package/dist/core/deps-health.test.js.map +1 -0
- package/dist/core/deps-why.js +260 -0
- package/dist/core/deps-why.js.map +1 -0
- package/dist/core/deps-why.test.js +175 -0
- package/dist/core/deps-why.test.js.map +1 -0
- package/dist/core/deps.js +179 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/deps.test.js +88 -0
- package/dist/core/deps.test.js.map +1 -0
- package/dist/core/diff-source.js +4 -2
- package/dist/core/diff-source.js.map +1 -1
- package/dist/core/echo.js +151 -0
- package/dist/core/echo.js.map +1 -0
- package/dist/core/echo.test.js +90 -0
- package/dist/core/echo.test.js.map +1 -0
- package/dist/core/ecosystem-verify.js +331 -0
- package/dist/core/ecosystem-verify.js.map +1 -0
- package/dist/core/ecosystem-verify.test.js +158 -0
- package/dist/core/ecosystem-verify.test.js.map +1 -0
- package/dist/core/engine-preset.test.js +60 -0
- package/dist/core/engine-preset.test.js.map +1 -0
- package/dist/core/engine.js +278 -32
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engine.test.js +63 -0
- package/dist/core/engine.test.js.map +1 -1
- package/dist/core/env-sync.js +122 -0
- package/dist/core/env-sync.js.map +1 -0
- package/dist/core/env-sync.test.js +99 -0
- package/dist/core/env-sync.test.js.map +1 -0
- package/dist/core/file-context.js +4 -2
- package/dist/core/file-context.js.map +1 -1
- package/dist/core/findings-baseline.js +60 -0
- package/dist/core/findings-baseline.js.map +1 -0
- package/dist/core/findings-baseline.test.js +77 -0
- package/dist/core/findings-baseline.test.js.map +1 -0
- package/dist/core/findings.js +68 -21
- package/dist/core/findings.js.map +1 -1
- package/dist/core/flaky.js +137 -0
- package/dist/core/flaky.js.map +1 -0
- package/dist/core/flaky.test.js +97 -0
- package/dist/core/flaky.test.js.map +1 -0
- package/dist/core/format.js +5 -3
- package/dist/core/format.js.map +1 -1
- package/dist/core/fuzz.js +306 -0
- package/dist/core/fuzz.js.map +1 -0
- package/dist/core/fuzz.test.js +121 -0
- package/dist/core/fuzz.test.js.map +1 -0
- package/dist/core/git.js +22 -0
- package/dist/core/git.js.map +1 -1
- package/dist/core/gitlab.js +176 -0
- package/dist/core/gitlab.js.map +1 -0
- package/dist/core/gitlab.test.js +199 -0
- package/dist/core/gitlab.test.js.map +1 -0
- package/dist/core/hivemind.js +250 -0
- package/dist/core/hivemind.js.map +1 -0
- package/dist/core/hivemind.test.js +79 -0
- package/dist/core/hivemind.test.js.map +1 -0
- package/dist/core/hologram.js +463 -0
- package/dist/core/hologram.js.map +1 -0
- package/dist/core/hologram.test.js +124 -0
- package/dist/core/hologram.test.js.map +1 -0
- package/dist/core/impact.js +240 -0
- package/dist/core/impact.js.map +1 -0
- package/dist/core/impact.test.js +105 -0
- package/dist/core/impact.test.js.map +1 -0
- package/dist/core/import-graph.js +170 -0
- package/dist/core/import-graph.js.map +1 -0
- package/dist/core/import-graph.test.js +52 -0
- package/dist/core/import-graph.test.js.map +1 -0
- package/dist/core/injection.js +55 -0
- package/dist/core/injection.js.map +1 -0
- package/dist/core/injection.test.js +45 -0
- package/dist/core/injection.test.js.map +1 -0
- package/dist/core/invariants.js +286 -0
- package/dist/core/invariants.js.map +1 -0
- package/dist/core/invariants.test.js +87 -0
- package/dist/core/invariants.test.js.map +1 -0
- package/dist/core/last-review.js +92 -0
- package/dist/core/last-review.js.map +1 -0
- package/dist/core/last-review.test.js +97 -0
- package/dist/core/last-review.test.js.map +1 -0
- package/dist/core/lockfile-support.test.js +112 -0
- package/dist/core/lockfile-support.test.js.map +1 -0
- package/dist/core/lockfile.js +284 -0
- package/dist/core/lockfile.js.map +1 -0
- package/dist/core/lockfile.test.js +203 -0
- package/dist/core/lockfile.test.js.map +1 -0
- package/dist/core/mock-leak.js +120 -0
- package/dist/core/mock-leak.js.map +1 -0
- package/dist/core/mock-leak.test.js +79 -0
- package/dist/core/mock-leak.test.js.map +1 -0
- package/dist/core/mutation.js +206 -0
- package/dist/core/mutation.js.map +1 -0
- package/dist/core/mutation.test.js +104 -0
- package/dist/core/mutation.test.js.map +1 -0
- package/dist/core/opencode.js +15 -2
- package/dist/core/opencode.js.map +1 -1
- package/dist/core/opencode.test.js +10 -1
- package/dist/core/opencode.test.js.map +1 -1
- package/dist/core/options.js +51 -3
- package/dist/core/options.js.map +1 -1
- package/dist/core/osv.js +202 -0
- package/dist/core/osv.js.map +1 -0
- package/dist/core/osv.test.js +173 -0
- package/dist/core/osv.test.js.map +1 -0
- package/dist/core/output-format.test.js +102 -0
- package/dist/core/output-format.test.js.map +1 -0
- package/dist/core/pack.js +212 -0
- package/dist/core/pack.js.map +1 -0
- package/dist/core/pack.test.js +129 -0
- package/dist/core/pack.test.js.map +1 -0
- package/dist/core/phantom.js +155 -0
- package/dist/core/phantom.js.map +1 -0
- package/dist/core/phantom.test.js +58 -0
- package/dist/core/phantom.test.js.map +1 -0
- package/dist/core/pr-comment.js +116 -0
- package/dist/core/pr-comment.js.map +1 -0
- package/dist/core/pr-comment.test.js +53 -0
- package/dist/core/pr-comment.test.js.map +1 -0
- package/dist/core/pr-review.js +160 -0
- package/dist/core/pr-review.js.map +1 -0
- package/dist/core/pr-review.test.js +62 -0
- package/dist/core/pr-review.test.js.map +1 -0
- package/dist/core/preflight-run.js +106 -0
- package/dist/core/preflight-run.js.map +1 -0
- package/dist/core/preflight.js +173 -0
- package/dist/core/preflight.js.map +1 -0
- package/dist/core/preflight.test.js +187 -0
- package/dist/core/preflight.test.js.map +1 -0
- package/dist/core/presets.js +408 -0
- package/dist/core/presets.js.map +1 -0
- package/dist/core/presets.test.js +79 -0
- package/dist/core/presets.test.js.map +1 -0
- package/dist/core/prompt.golden.test.js +74 -0
- package/dist/core/prompt.golden.test.js.map +1 -0
- package/dist/core/prompt.js +43 -4
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/prompt.test.js +16 -0
- package/dist/core/prompt.test.js.map +1 -1
- package/dist/core/readiness-fix.js +111 -0
- package/dist/core/readiness-fix.js.map +1 -0
- package/dist/core/readiness-fix.test.js +99 -0
- package/dist/core/readiness-fix.test.js.map +1 -0
- package/dist/core/readiness.js +189 -0
- package/dist/core/readiness.js.map +1 -0
- package/dist/core/readiness.test.js +199 -0
- package/dist/core/readiness.test.js.map +1 -0
- package/dist/core/receipt.js +193 -0
- package/dist/core/receipt.js.map +1 -0
- package/dist/core/receipt.test.js +193 -0
- package/dist/core/receipt.test.js.map +1 -0
- package/dist/core/reviewers.js +179 -0
- package/dist/core/reviewers.js.map +1 -0
- package/dist/core/reviewers.test.js +105 -0
- package/dist/core/reviewers.test.js.map +1 -0
- package/dist/core/roast.js +27 -0
- package/dist/core/roast.js.map +1 -0
- package/dist/core/roast.test.js +19 -0
- package/dist/core/roast.test.js.map +1 -0
- package/dist/core/router.js +8 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/router.test.js +157 -0
- package/dist/core/router.test.js.map +1 -0
- package/dist/core/rules.js +2 -2
- package/dist/core/rules.js.map +1 -1
- package/dist/core/run.js +322 -20
- package/dist/core/run.js.map +1 -1
- package/dist/core/sarif.js +125 -0
- package/dist/core/sarif.js.map +1 -0
- package/dist/core/sarif.test.js +60 -0
- package/dist/core/sarif.test.js.map +1 -0
- package/dist/core/sast.js +324 -0
- package/dist/core/sast.js.map +1 -0
- package/dist/core/sast.test.js +105 -0
- package/dist/core/sast.test.js.map +1 -0
- package/dist/core/sbom.js +121 -0
- package/dist/core/sbom.js.map +1 -0
- package/dist/core/sbom.test.js +81 -0
- package/dist/core/sbom.test.js.map +1 -0
- package/dist/core/second-opinion.js +88 -0
- package/dist/core/second-opinion.js.map +1 -0
- package/dist/core/second-opinion.test.js +89 -0
- package/dist/core/second-opinion.test.js.map +1 -0
- package/dist/core/secrets.js +120 -5
- package/dist/core/secrets.js.map +1 -1
- package/dist/core/secrets.test.js +74 -1
- package/dist/core/secrets.test.js.map +1 -1
- package/dist/core/shadow.js +94 -0
- package/dist/core/shadow.js.map +1 -0
- package/dist/core/shadow.test.js +50 -0
- package/dist/core/shadow.test.js.map +1 -0
- package/dist/core/slicing.js +110 -0
- package/dist/core/slicing.js.map +1 -0
- package/dist/core/slicing.test.js +287 -0
- package/dist/core/slicing.test.js.map +1 -0
- package/dist/core/slop/churn.js +49 -0
- package/dist/core/slop/churn.js.map +1 -0
- package/dist/core/slop/collect.js +186 -0
- package/dist/core/slop/collect.js.map +1 -0
- package/dist/core/slop/dead-exports.js +101 -0
- package/dist/core/slop/dead-exports.js.map +1 -0
- package/dist/core/slop/duplicates.js +155 -0
- package/dist/core/slop/duplicates.js.map +1 -0
- package/dist/core/slop/index.js +72 -0
- package/dist/core/slop/index.js.map +1 -0
- package/dist/core/slop/model.js +2 -0
- package/dist/core/slop/model.js.map +1 -0
- package/dist/core/slop/score.js +185 -0
- package/dist/core/slop/score.js.map +1 -0
- package/dist/core/slop/slop.test.js +160 -0
- package/dist/core/slop/slop.test.js.map +1 -0
- package/dist/core/slop/source.js +129 -0
- package/dist/core/slop/source.js.map +1 -0
- package/dist/core/slop/test-debt.js +178 -0
- package/dist/core/slop/test-debt.js.map +1 -0
- package/dist/core/slop/test-debt.test.js +114 -0
- package/dist/core/slop/test-debt.test.js.map +1 -0
- package/dist/core/slop/todos.js +117 -0
- package/dist/core/slop/todos.js.map +1 -0
- package/dist/core/snapshot.js +214 -0
- package/dist/core/snapshot.js.map +1 -0
- package/dist/core/snapshot.test.js +101 -0
- package/dist/core/snapshot.test.js.map +1 -0
- package/dist/core/stats.js +119 -0
- package/dist/core/stats.js.map +1 -0
- package/dist/core/stats.test.js +86 -0
- package/dist/core/stats.test.js.map +1 -0
- package/dist/core/suppressions.js +96 -0
- package/dist/core/suppressions.js.map +1 -0
- package/dist/core/suppressions.test.js +90 -0
- package/dist/core/suppressions.test.js.map +1 -0
- package/dist/core/test-delta.js +53 -0
- package/dist/core/test-delta.js.map +1 -0
- package/dist/core/test-delta.test.js +41 -0
- package/dist/core/test-delta.test.js.map +1 -0
- package/dist/core/test-plan.js +212 -0
- package/dist/core/test-plan.js.map +1 -0
- package/dist/core/test-plan.test.js +94 -0
- package/dist/core/test-plan.test.js.map +1 -0
- package/dist/core/test-weakening.js +191 -0
- package/dist/core/test-weakening.js.map +1 -0
- package/dist/core/test-weakening.test.js +114 -0
- package/dist/core/test-weakening.test.js.map +1 -0
- package/dist/core/tree-scan.js +77 -0
- package/dist/core/tree-scan.js.map +1 -0
- package/dist/core/tree-scan.test.js +58 -0
- package/dist/core/tree-scan.test.js.map +1 -0
- package/dist/mcp-prompts.test.js +133 -0
- package/dist/mcp-prompts.test.js.map +1 -0
- package/dist/mcp.js +3303 -240
- package/dist/mcp.js.map +1 -1
- package/dist/mcp.test.js +1739 -1
- package/dist/mcp.test.js.map +1 -1
- package/dist/skills.test.js +221 -0
- package/dist/skills.test.js.map +1 -0
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/integrations.md +151 -7
- package/package.json +2 -1
- package/prompts/oc-pilot.en.md +8 -1
- package/prompts/oc-pilot.ru.md +8 -1
- package/server.json +2 -2
- package/skills/agent-self-review/SKILL.md +87 -0
- package/skills/commit-discipline/SKILL.md +86 -0
- package/skills/oc-pilot/SKILL.md +86 -0
- package/skills/secure-diff-gate/SKILL.md +101 -0
- package/skills/stack-review-packs/SKILL.md +76 -0
- package/skills/test-failure-triage/SKILL.md +88 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { PilotError } from "../core/errors.js";
|
|
4
|
+
import { initIdentity, readIdentity, readPeers, sendMessage, startServer, trustPeer, validatePayload, } from "../core/hivemind.js";
|
|
5
|
+
import { writeOutput } from "../core/io.js";
|
|
6
|
+
import { log } from "../core/log.js";
|
|
7
|
+
import { COMMON_HELP, parseCommandArgs, resolveContext, withCommon } from "../core/options.js";
|
|
8
|
+
import { asBoolean, asString } from "../core/parse.js";
|
|
9
|
+
const OPTIONS = withCommon({
|
|
10
|
+
port: { type: "string" },
|
|
11
|
+
host: { type: "string" },
|
|
12
|
+
type: { type: "string" },
|
|
13
|
+
payload: { type: "string" },
|
|
14
|
+
force: { type: "boolean" },
|
|
15
|
+
});
|
|
16
|
+
const HELP = `Использование:
|
|
17
|
+
oc-pilot hivemind init [--force]
|
|
18
|
+
oc-pilot hivemind trust <public-key|file>
|
|
19
|
+
oc-pilot hivemind status [--json]
|
|
20
|
+
oc-pilot hivemind serve [--port 41337]
|
|
21
|
+
oc-pilot hivemind send --port 41337 --type diff --payload @changes.diff
|
|
22
|
+
|
|
23
|
+
P2P-сеть агентов на встроенном node:net. Узлы обмениваются только
|
|
24
|
+
диффами, AST и запросами к LLM; исполняемые команды запрещены. Каждое
|
|
25
|
+
соединение проходит подписанный ed25519 handshake и ECDH X25519, а
|
|
26
|
+
сообщения шифруются AES-256-GCM. Без ключа проекта и явного trust
|
|
27
|
+
пакеты дропаются.
|
|
28
|
+
|
|
29
|
+
Опции:
|
|
30
|
+
--port <n> порт (по умолчанию 41337)
|
|
31
|
+
--host <addr> адрес (по умолчанию 127.0.0.1)
|
|
32
|
+
--type <type> diff, ast, llm-request или ping
|
|
33
|
+
--payload <text|@file> тело сообщения
|
|
34
|
+
--force перевыпустить identity
|
|
35
|
+
${COMMON_HELP}
|
|
36
|
+
|
|
37
|
+
Примеры:
|
|
38
|
+
oc-pilot hivemind init
|
|
39
|
+
oc-pilot hivemind trust "-----BEGIN PUBLIC KEY-----..."
|
|
40
|
+
oc-pilot hivemind serve --port 41337
|
|
41
|
+
oc-pilot hivemind send --port 41337 --type diff --payload @changes.diff`;
|
|
42
|
+
function fingerprint(publicKey) {
|
|
43
|
+
return createHash("sha256").update(publicKey).digest("hex").slice(0, 16);
|
|
44
|
+
}
|
|
45
|
+
export async function runHivemind(argv) {
|
|
46
|
+
const { values, positionals } = parseCommandArgs(argv, OPTIONS);
|
|
47
|
+
if (asBoolean(values, "help")) {
|
|
48
|
+
process.stdout.write(HELP);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const [subcommand, argument] = positionals;
|
|
52
|
+
const ctx = resolveContext(values);
|
|
53
|
+
if (subcommand === "init") {
|
|
54
|
+
const identity = initIdentity(ctx.cwd, asBoolean(values, "force"));
|
|
55
|
+
log.success("Hivemind identity готова.");
|
|
56
|
+
process.stdout.write(`public key:\n${identity.publicKey}\nfingerprint: ${fingerprint(identity.publicKey)}\n`);
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
if (subcommand === "trust") {
|
|
60
|
+
if (!argument)
|
|
61
|
+
throw new PilotError("Укажите публичный ключ или файл", { exitCode: 2 });
|
|
62
|
+
const key = existsSync(argument) ? readFileSync(argument, "utf8") : argument;
|
|
63
|
+
const peers = trustPeer(ctx.cwd, key);
|
|
64
|
+
log.success(`Доверенных узлов: ${String(peers.length)}.`);
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
if (subcommand === "status") {
|
|
68
|
+
const identity = readIdentity(ctx.cwd);
|
|
69
|
+
const peers = readPeers(ctx.cwd);
|
|
70
|
+
if (ctx.flags.json) {
|
|
71
|
+
writeOutput(JSON.stringify({ identity: identity ? { fingerprint: fingerprint(identity.publicKey), publicKey: identity.publicKey, createdAt: identity.createdAt } : null, peers }, null, 2), ctx.flags.output);
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
if (!identity) {
|
|
75
|
+
log.warn("Identity не создана: oc-pilot hivemind init.");
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
process.stdout.write(`fingerprint: ${fingerprint(identity.publicKey)}\npeers: ${String(peers.length)}\n`);
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
if (subcommand === "serve") {
|
|
82
|
+
const portRaw = asString(values, "port");
|
|
83
|
+
const port = portRaw ? Number(portRaw) : 41_337;
|
|
84
|
+
const server = await startServer(ctx.cwd, {
|
|
85
|
+
port,
|
|
86
|
+
host: asString(values, "host") ?? "127.0.0.1",
|
|
87
|
+
onMessage: (payload) => log.detail(`hivemind: ${payload.type} от узла`),
|
|
88
|
+
});
|
|
89
|
+
log.success(`Hivemind слушает ${String(server.port)}.`);
|
|
90
|
+
await new Promise((resolveStop) => {
|
|
91
|
+
process.once("SIGINT", () => {
|
|
92
|
+
void server.close().then(() => resolveStop());
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
if (subcommand === "send") {
|
|
98
|
+
const portRaw = asString(values, "port");
|
|
99
|
+
const port = portRaw ? Number(portRaw) : 41_337;
|
|
100
|
+
const raw = asString(values, "payload");
|
|
101
|
+
if (!raw)
|
|
102
|
+
throw new PilotError("Укажите --payload <text|@file>", { exitCode: 2 });
|
|
103
|
+
const body = raw.startsWith("@") ? readFileSync(raw.slice(1), "utf8") : raw;
|
|
104
|
+
const payload = { type: asString(values, "type") ?? "diff", body };
|
|
105
|
+
const check = validatePayload(payload);
|
|
106
|
+
if (!check.ok)
|
|
107
|
+
throw new PilotError(check.error ?? "Недопустимый payload", { exitCode: 2 });
|
|
108
|
+
const result = await sendMessage(ctx.cwd, {
|
|
109
|
+
host: asString(values, "host") ?? "127.0.0.1",
|
|
110
|
+
port,
|
|
111
|
+
payload,
|
|
112
|
+
});
|
|
113
|
+
if (ctx.flags.json)
|
|
114
|
+
writeOutput(JSON.stringify(result, null, 2), ctx.flags.output);
|
|
115
|
+
else
|
|
116
|
+
process.stdout.write(`${result.ok ? "ok" : "error"}: ${result.response?.type ?? result.error ?? "unknown"}\n`);
|
|
117
|
+
return result.ok ? 0 : 1;
|
|
118
|
+
}
|
|
119
|
+
throw new PilotError("Неизвестная подкоманда hivemind", {
|
|
120
|
+
hint: "Доступно: init, trust, status, serve, send.",
|
|
121
|
+
exitCode: 2,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=hivemind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hivemind.js","sourceRoot":"","sources":["../../src/commands/hivemind.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { loadDiff } from "../core/diff-source.js";
|
|
2
|
+
import { analyzeImpact, describeImpact } from "../core/impact.js";
|
|
3
|
+
import { writeOutput } from "../core/io.js";
|
|
4
|
+
import { log } from "../core/log.js";
|
|
5
|
+
import { COMMON_HELP, parseCommandArgs, resolveContext, withCommon } from "../core/options.js";
|
|
6
|
+
import { asBoolean } from "../core/parse.js";
|
|
7
|
+
const OPTIONS = withCommon({
|
|
8
|
+
staged: { type: "boolean" },
|
|
9
|
+
unstaged: { type: "boolean" },
|
|
10
|
+
base: { type: "string" },
|
|
11
|
+
diff: { type: "string" },
|
|
12
|
+
stdin: { type: "boolean" },
|
|
13
|
+
"include-untracked": { type: "boolean" },
|
|
14
|
+
});
|
|
15
|
+
const HELP = `Использование:
|
|
16
|
+
oc-pilot impact [пути] [опции]
|
|
17
|
+
|
|
18
|
+
Показывает, какие объявления изменил diff и где они ещё используются.
|
|
19
|
+
Файлы, которых diff не касался, но которые ссылаются на изменённое имя,
|
|
20
|
+
попадают в отчёт — это повод проверить, не забыт ли вызов или ренейм.
|
|
21
|
+
Поиск текстовый (без AST): быстро и без зависимостей, но возможны
|
|
22
|
+
совпадения в комментариях и строках.
|
|
23
|
+
|
|
24
|
+
Опции:
|
|
25
|
+
--staged изменения в индексе (git diff --cached)
|
|
26
|
+
--unstaged только unstaged-изменения
|
|
27
|
+
--base <ref> diff против ветки (например, main)
|
|
28
|
+
--diff <file|-> взять патч из файла или stdin
|
|
29
|
+
--stdin прочитать патч из стандартного ввода
|
|
30
|
+
--include-untracked добавить новые неотслеживаемые файлы
|
|
31
|
+
${COMMON_HELP}
|
|
32
|
+
|
|
33
|
+
Примеры:
|
|
34
|
+
oc-pilot impact --staged
|
|
35
|
+
oc-pilot impact --base main --json
|
|
36
|
+
`;
|
|
37
|
+
export async function runImpact(argv) {
|
|
38
|
+
const { values, positionals } = parseCommandArgs(argv, OPTIONS);
|
|
39
|
+
if (asBoolean(values, "help")) {
|
|
40
|
+
process.stdout.write(HELP);
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
const ctx = resolveContext(values);
|
|
44
|
+
const data = await loadDiff(values, ctx, positionals);
|
|
45
|
+
if (!data.diff.trim()) {
|
|
46
|
+
log.info("Изменений нет — анализировать нечего.");
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
const report = analyzeImpact(ctx.cwd, data.diff, data.changedFiles);
|
|
50
|
+
if (report.symbols.length === 0) {
|
|
51
|
+
log.info("В diff нет новых или изменённых объявлений функций, типов и классов.");
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
const untouched = report.references.length;
|
|
55
|
+
log.info(`Объявлений: ${report.symbols.length} · ссылок в нетронутых файлах: ${untouched} ` +
|
|
56
|
+
`(проверено файлов: ${report.scannedFiles}).`);
|
|
57
|
+
if (ctx.flags.json) {
|
|
58
|
+
const payload = {
|
|
59
|
+
symbols: report.symbols,
|
|
60
|
+
references: report.references,
|
|
61
|
+
scannedFiles: report.scannedFiles,
|
|
62
|
+
touchedFiles: report.touchedFiles,
|
|
63
|
+
};
|
|
64
|
+
writeOutput(JSON.stringify(payload, null, 2), ctx.flags.output);
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const text = describeImpact(report);
|
|
68
|
+
const wrote = writeOutput(text, ctx.flags.output);
|
|
69
|
+
if (wrote)
|
|
70
|
+
log.success(`Отчёт записан: ${wrote}`);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/commands/impact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAmB,MAAM,oBAAoB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,OAAO,GAAe,UAAU,CAAC;IACrC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC3B,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACxB,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC1B,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;CACzC,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;EAgBX,WAAW;;;;;CAKZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IAC5C,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACjF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;IAC3C,GAAG,CAAC,IAAI,CACN,eAAe,MAAM,CAAC,OAAO,CAAC,MAAM,kCAAkC,SAAS,GAAG;QAChF,sBAAsB,MAAM,CAAC,YAAY,IAAI,CAChD,CAAC;IAEF,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC;QACF,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,KAAK;QAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import { existsSync, statSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { configTemplate } from "../core/config.js";
|
|
4
4
|
import { PilotError } from "../core/errors.js";
|
|
5
5
|
import { log } from "../core/log.js";
|
|
6
6
|
import { parseCommandArgs } from "../core/options.js";
|
|
7
7
|
import { asBoolean, asString } from "../core/parse.js";
|
|
8
|
+
import { combinePresets, getPreset, presetIds } from "../core/presets.js";
|
|
9
|
+
import { installHook } from "./install-hook.js";
|
|
8
10
|
const OPTIONS = {
|
|
9
11
|
cwd: { type: "string", short: "C" },
|
|
10
12
|
force: { type: "boolean" },
|
|
13
|
+
hooks: { type: "boolean" },
|
|
14
|
+
preset: { type: "string" },
|
|
11
15
|
json: { type: "boolean" },
|
|
12
16
|
help: { type: "boolean", short: "h" },
|
|
13
17
|
};
|
|
14
18
|
const HELP = `Использование:
|
|
15
19
|
oc-pilot init [опции]
|
|
16
20
|
|
|
17
|
-
Создаёт .oc-pilot.json с настройками по
|
|
21
|
+
Создаёт .oc-pilot.json с настройками по умолчанию, а с --preset —
|
|
22
|
+
ещё и .oc-pilot/rules.md с готовыми правилами для стека.
|
|
18
23
|
|
|
19
24
|
Опции:
|
|
20
|
-
-C, --cwd <dir>
|
|
21
|
-
--force
|
|
22
|
-
--
|
|
23
|
-
|
|
25
|
+
-C, --cwd <dir> Директория проекта
|
|
26
|
+
--force Перезаписать существующие файлы
|
|
27
|
+
--hooks Установить git-хуки: preflight --staged на commit, review на push
|
|
28
|
+
--preset <a,b> Пресет правил, можно несколько через запятую:
|
|
29
|
+
${presetIds().join(", ")}
|
|
30
|
+
--json Вывести пути в JSON
|
|
31
|
+
-h, --help Показать помощь
|
|
24
32
|
`;
|
|
25
33
|
export function runInit(argv) {
|
|
26
34
|
const { values } = parseCommandArgs(argv, OPTIONS);
|
|
@@ -33,26 +41,80 @@ export function runInit(argv) {
|
|
|
33
41
|
if (!existsSync(cwd) || !statSync(cwd).isDirectory()) {
|
|
34
42
|
throw new PilotError(`Директория не найдена: ${cwd}`, { exitCode: 2 });
|
|
35
43
|
}
|
|
44
|
+
const rawPreset = asString(values, "preset");
|
|
45
|
+
let presets;
|
|
46
|
+
if (rawPreset !== undefined) {
|
|
47
|
+
const ids = rawPreset.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
|
|
48
|
+
const unknown = ids.filter((id) => getPreset(id) === undefined);
|
|
49
|
+
if (ids.length === 0 || unknown.length > 0) {
|
|
50
|
+
throw new PilotError(`Неизвестный пресет: ${unknown[0] ?? rawPreset}`, {
|
|
51
|
+
hint: `Доступны: ${presetIds().join(", ")}`,
|
|
52
|
+
exitCode: 2,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
presets = ids.map((id) => getPreset(id));
|
|
56
|
+
}
|
|
36
57
|
const path = join(cwd, ".oc-pilot.json");
|
|
37
|
-
|
|
58
|
+
const force = asBoolean(values, "force");
|
|
59
|
+
if (existsSync(path) && !force && !presets) {
|
|
38
60
|
throw new PilotError(`Конфиг уже существует: ${path}`, {
|
|
39
61
|
hint: "Используйте --force для перезаписи.",
|
|
40
62
|
exitCode: 2,
|
|
41
63
|
});
|
|
42
64
|
}
|
|
43
|
-
|
|
65
|
+
if (existsSync(path) && !force) {
|
|
66
|
+
log.info(`Конфиг уже существует: ${path} — оставлен без изменений.`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
writeFileSync(path, configTemplate(), "utf8");
|
|
70
|
+
log.success(`Создан ${path}`);
|
|
71
|
+
}
|
|
72
|
+
let rulesPath;
|
|
73
|
+
if (presets) {
|
|
74
|
+
rulesPath = join(cwd, ".oc-pilot", "rules.md");
|
|
75
|
+
if (existsSync(rulesPath) && !force) {
|
|
76
|
+
throw new PilotError(`Файл правил уже существует: ${rulesPath}`, {
|
|
77
|
+
hint: "Используйте --force для перезаписи.",
|
|
78
|
+
exitCode: 2,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
mkdirSync(join(cwd, ".oc-pilot"), { recursive: true });
|
|
82
|
+
const rulesText = presets.length === 1 ? presets[0].rules : combinePresets(presets);
|
|
83
|
+
writeFileSync(rulesPath, rulesText, "utf8");
|
|
84
|
+
const label = presets.length === 1
|
|
85
|
+
? `пресет ${presets[0].id}`
|
|
86
|
+
: `пресеты ${presets.map((preset) => preset.id).join(", ")}`;
|
|
87
|
+
log.success(`Создан ${rulesPath} (${label})`);
|
|
88
|
+
}
|
|
89
|
+
const hooks = [];
|
|
90
|
+
if (asBoolean(values, "hooks")) {
|
|
91
|
+
for (const kind of ["pre-commit", "pre-push"]) {
|
|
92
|
+
try {
|
|
93
|
+
const result = installHook(cwd, kind, force);
|
|
94
|
+
hooks.push({ kind, path: result.path });
|
|
95
|
+
log.success(`Установлен git-хук ${kind}: ${result.path}`);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
log.warn(`Хук ${kind} не установлен: ${error instanceof Error ? error.message : String(error)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
44
102
|
if (asBoolean(values, "json")) {
|
|
45
|
-
process.stdout.write(`${JSON.stringify({ created: path }, null, 2)}\n`);
|
|
103
|
+
process.stdout.write(`${JSON.stringify({ created: path, ...(rulesPath ? { rules: rulesPath } : {}), ...(hooks.length > 0 ? { hooks } : {}) }, null, 2)}\n`);
|
|
46
104
|
return 0;
|
|
47
105
|
}
|
|
48
|
-
log.success(`Создан ${path}`);
|
|
49
106
|
log.blank();
|
|
50
107
|
log.info("Дальше:");
|
|
51
108
|
log.detail("oc-pilot review");
|
|
52
109
|
log.detail("oc-pilot test-fix");
|
|
53
110
|
log.detail('oc-pilot docgen "src/**/*.ts"');
|
|
54
111
|
log.blank();
|
|
55
|
-
|
|
112
|
+
if (presets) {
|
|
113
|
+
log.info("Правила можно дополнять — они попадут в каждый запрос.");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
log.info("Правила проекта: создайте .oc-pilot/rules.md (или init --preset <name>) — они попадут в каждый запрос.");
|
|
117
|
+
}
|
|
56
118
|
log.info("Агент по умолчанию — oc-pilot с read-only доступом к файлам. Модель берётся из конфигурации OpenCode.");
|
|
57
119
|
return 0;
|
|
58
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { test } from "node:test";
|
|
6
|
+
import { runInit } from "./init.js";
|
|
7
|
+
import { HOOK_MARKER } from "./install-hook.js";
|
|
8
|
+
import { runGit } from "../core/git.js";
|
|
9
|
+
import { PilotError } from "../core/errors.js";
|
|
10
|
+
test("init --preset writes rules.md next to the config", () => {
|
|
11
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-preset-"));
|
|
12
|
+
try {
|
|
13
|
+
const code = runInit(["--cwd", dir, "--preset", "react"]);
|
|
14
|
+
assert.equal(code, 0);
|
|
15
|
+
assert.ok(existsSync(join(dir, ".oc-pilot.json")));
|
|
16
|
+
const rules = readFileSync(join(dir, ".oc-pilot", "rules.md"), "utf8");
|
|
17
|
+
assert.ok(rules.includes("# Project review rules"));
|
|
18
|
+
assert.ok(rules.includes("## Hooks"));
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
rmSync(dir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
test("init --hooks installs pre-commit and pre-push hooks", () => {
|
|
25
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-hooks-"));
|
|
26
|
+
try {
|
|
27
|
+
runGit(["init"], dir);
|
|
28
|
+
assert.equal(runInit(["--cwd", dir, "--hooks"]), 0);
|
|
29
|
+
const hooks = join(dir, ".git", "hooks");
|
|
30
|
+
assert.ok(readFileSync(join(hooks, "pre-commit"), "utf8").includes(HOOK_MARKER));
|
|
31
|
+
assert.match(readFileSync(join(hooks, "pre-commit"), "utf8"), /preflight --staged/);
|
|
32
|
+
assert.ok(readFileSync(join(hooks, "pre-push"), "utf8").includes(HOOK_MARKER));
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
rmSync(dir, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
test("init --json reports both created paths", () => {
|
|
39
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-json-"));
|
|
40
|
+
try {
|
|
41
|
+
const code = runInit(["--cwd", dir, "--preset", "node", "--json"]);
|
|
42
|
+
assert.equal(code, 0);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
rmSync(dir, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
test("an unknown preset is a usage error listing the options", () => {
|
|
49
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-unknown-"));
|
|
50
|
+
try {
|
|
51
|
+
assert.throws(() => runInit(["--cwd", dir, "--preset", "cobol"]), (error) => {
|
|
52
|
+
assert.ok(error instanceof PilotError);
|
|
53
|
+
assert.match(error.message, /Неизвестный пресет: cobol/);
|
|
54
|
+
assert.match(error.hint ?? "", /base, node, react, next/);
|
|
55
|
+
assert.match(error.hint ?? "", /security, devops/);
|
|
56
|
+
assert.equal(error.exitCode, 2);
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
assert.ok(!existsSync(join(dir, ".oc-pilot.json")));
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
rmSync(dir, { recursive: true, force: true });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
test("an existing rules.md requires --force", () => {
|
|
66
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-exists-"));
|
|
67
|
+
try {
|
|
68
|
+
assert.equal(runInit(["--cwd", dir, "--preset", "base"]), 0);
|
|
69
|
+
assert.throws(() => runInit(["--cwd", dir, "--preset", "base"]), (error) => {
|
|
70
|
+
assert.ok(error instanceof PilotError);
|
|
71
|
+
assert.match(error.message, /Файл правил уже существует/);
|
|
72
|
+
return true;
|
|
73
|
+
});
|
|
74
|
+
assert.equal(runInit(["--cwd", dir, "--preset", "go", "--force"]), 0);
|
|
75
|
+
assert.ok(readFileSync(join(dir, ".oc-pilot", "rules.md"), "utf8").includes("%w"));
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
rmSync(dir, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
test("a preset never overwrites an existing config without --force", () => {
|
|
82
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-config-"));
|
|
83
|
+
try {
|
|
84
|
+
writeFileSync(join(dir, ".oc-pilot.json"), '{ "engine": "openai" }\n', "utf8");
|
|
85
|
+
const code = runInit(["--cwd", dir, "--preset", "python"]);
|
|
86
|
+
assert.equal(code, 0);
|
|
87
|
+
assert.equal(readFileSync(join(dir, ".oc-pilot.json"), "utf8"), '{ "engine": "openai" }\n');
|
|
88
|
+
assert.ok(existsSync(join(dir, ".oc-pilot", "rules.md")));
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
rmSync(dir, { recursive: true, force: true });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
test("comma-separated presets combine into one rules file", () => {
|
|
95
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-multi-"));
|
|
96
|
+
try {
|
|
97
|
+
const code = runInit(["--cwd", dir, "--preset", "react, security"]);
|
|
98
|
+
assert.equal(code, 0);
|
|
99
|
+
const rules = readFileSync(join(dir, ".oc-pilot", "rules.md"), "utf8");
|
|
100
|
+
assert.equal(rules.split("# Project review rules").length - 1, 1);
|
|
101
|
+
assert.ok(rules.includes("## Hooks"));
|
|
102
|
+
assert.ok(rules.includes("constant-time"));
|
|
103
|
+
assert.ok(rules.includes("\n---\n"));
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
rmSync(dir, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
test("one unknown preset in a comma list fails the whole list", () => {
|
|
110
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-multi-unknown-"));
|
|
111
|
+
try {
|
|
112
|
+
assert.throws(() => runInit(["--cwd", dir, "--preset", "react,cobol"]), (error) => {
|
|
113
|
+
assert.ok(error instanceof PilotError);
|
|
114
|
+
assert.match(error.message, /Неизвестный пресет: cobol/);
|
|
115
|
+
assert.equal(error.exitCode, 2);
|
|
116
|
+
return true;
|
|
117
|
+
});
|
|
118
|
+
assert.ok(!existsSync(join(dir, ".oc-pilot", "rules.md")));
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
rmSync(dir, { recursive: true, force: true });
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
test("stack presets beyond the original five are accepted", () => {
|
|
125
|
+
const dir = mkdtempSync(join(tmpdir(), "oc-pilot-init-newstack-"));
|
|
126
|
+
try {
|
|
127
|
+
for (const id of ["rust", "vue", "csharp", "devops"]) {
|
|
128
|
+
assert.equal(runInit(["--cwd", dir, "--preset", id, "--force"]), 0, id);
|
|
129
|
+
assert.ok(existsSync(join(dir, ".oc-pilot", "rules.md")), id);
|
|
130
|
+
}
|
|
131
|
+
const devops = readFileSync(join(dir, ".oc-pilot", "rules.md"), "utf8");
|
|
132
|
+
assert.ok(devops.includes(":latest"));
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
rmSync(dir, { recursive: true, force: true });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=init.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../src/commands/init.test.ts"],"names":[],"mappings":"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"}
|