@prestyj/cli 5.28.0 → 5.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/assets/motion/THIRD-PARTY.md +14 -19
- package/assets/motion/bin/contact-sheet.mjs +9 -3
- package/assets/motion/bin/cues.mjs +337 -0
- package/assets/motion/bin/flash-check.mjs +314 -0
- package/assets/motion/bin/fonts.mjs +17 -13
- package/assets/motion/bin/library.mjs +61 -18
- package/assets/motion/bin/motion-blur.mjs +943 -0
- package/assets/motion/bin/motion-check.mjs +366 -9
- package/assets/motion/bin/music-fit.mjs +436 -0
- package/assets/motion/bin/pdf-extract.mjs +22 -10
- package/assets/motion/bin/reference-study.mjs +346 -0
- package/assets/motion/bin/score-synth.mjs +1052 -93
- package/assets/motion/fonts/finger-paint/OFL.txt +93 -0
- package/assets/motion/fonts/finger-paint/finger-paint-normal.woff2 +0 -0
- package/assets/motion/fonts/fonts.json +56 -0
- package/assets/motion/fonts/short-stack/OFL.txt +94 -0
- package/assets/motion/fonts/short-stack/short-stack-normal.woff2 +0 -0
- package/assets/motion/fonts/sora/OFL.txt +93 -0
- package/assets/motion/fonts/sora/sora-normal.woff2 +0 -0
- package/assets/motion/fonts/specimen.jpg +0 -0
- package/assets/motion/fonts/unbounded/OFL.txt +93 -0
- package/assets/motion/fonts/unbounded/unbounded-normal.woff2 +0 -0
- package/assets/motion/library/README.md +52 -14
- package/assets/motion/library/kit/moves.js +1981 -0
- package/assets/motion/library/library.json +232 -0
- package/assets/motion/library/pieces/camera-rig/meta.json +13 -0
- package/assets/motion/library/pieces/camera-rig/piece.html +153 -0
- package/assets/motion/library/pieces/camera-rig/preview.jpg +0 -0
- package/assets/motion/library/pieces/chain-knock/meta.json +13 -0
- package/assets/motion/library/pieces/chain-knock/piece.html +195 -0
- package/assets/motion/library/pieces/chain-knock/preview.jpg +0 -0
- package/assets/motion/library/pieces/gather-to-logo/meta.json +13 -0
- package/assets/motion/library/pieces/gather-to-logo/piece.html +159 -0
- package/assets/motion/library/pieces/gather-to-logo/preview.jpg +0 -0
- package/assets/motion/library/pieces/morph-carry/meta.json +13 -0
- package/assets/motion/library/pieces/morph-carry/piece.html +173 -0
- package/assets/motion/library/pieces/morph-carry/preview.jpg +0 -0
- package/assets/motion/library/pieces/one-shape-journey/meta.json +13 -0
- package/assets/motion/library/pieces/one-shape-journey/piece.html +195 -0
- package/assets/motion/library/pieces/one-shape-journey/preview.jpg +0 -0
- package/assets/motion/library/pieces/open-from-subject/meta.json +13 -0
- package/assets/motion/library/pieces/open-from-subject/piece.html +168 -0
- package/assets/motion/library/pieces/open-from-subject/preview.jpg +0 -0
- package/assets/motion/library/pieces/request-to-result/meta.json +13 -0
- package/assets/motion/library/pieces/request-to-result/piece.html +212 -0
- package/assets/motion/library/pieces/request-to-result/preview.jpg +0 -0
- package/assets/motion/library/pieces/scale-dive/meta.json +13 -0
- package/assets/motion/library/pieces/scale-dive/piece.html +321 -0
- package/assets/motion/library/pieces/scale-dive/preview.jpg +0 -0
- package/assets/motion/library/pieces/screen-replica-steps/meta.json +13 -0
- package/assets/motion/library/pieces/screen-replica-steps/piece.html +366 -0
- package/assets/motion/library/pieces/screen-replica-steps/preview.jpg +0 -0
- package/assets/motion/library/pieces/zoom-into-card/meta.json +13 -0
- package/assets/motion/library/pieces/zoom-into-card/piece.html +179 -0
- package/assets/motion/library/pieces/zoom-into-card/preview.jpg +0 -0
- package/assets/motion/library/sheets/diagram.jpg +0 -0
- package/assets/motion/library/sheets/frame.jpg +0 -0
- package/assets/motion/library/sheets/transition.jpg +0 -0
- package/assets/motion/library/sheets/ui.jpg +0 -0
- package/assets/motion/plugin.json +1 -1
- package/assets/motion/references/build-sheet.md +206 -0
- package/assets/motion/references/runtime/determinism-rules.md +3 -3
- package/assets/motion/references/runtime/gsap-easing-and-stagger.md +28 -28
- package/assets/motion/references/runtime/gsap.md +3 -3
- package/assets/motion/references/runtime/inputs-and-assets.md +21 -16
- package/assets/motion/references/runtime/lint-validate-inspect.md +3 -3
- package/assets/motion/references/runtime/minimal-composition.md +6 -0
- package/assets/motion/references/runtime/preview-render.md +3 -3
- package/assets/motion/skills/app-walkthrough/SKILL.md +66 -0
- package/assets/motion/skills/before-after/SKILL.md +53 -0
- package/assets/motion/skills/brand-kit/SKILL.md +17 -16
- package/assets/motion/skills/dev-tool-video/SKILL.md +57 -0
- package/assets/motion/skills/launch-video/SKILL.md +62 -0
- package/assets/motion/skills/match-reference/SKILL.md +58 -0
- package/assets/motion/skills/motion/SKILL.md +167 -98
- package/assets/motion/skills/source-ingest/SKILL.md +23 -15
- package/assets/motion/skills/website-video/SKILL.md +59 -0
- package/assets/skills/bulletproof/SKILL.md +36 -11
- package/assets/skills/bulletproof/references/agent-surface.md +19 -9
- package/assets/skills/bulletproof/references/audit-protocol.md +20 -5
- package/assets/skills/bulletproof/references/platform-playbooks.md +5 -4
- package/assets/skills/bulletproof/references/provenance.md +26 -1
- package/assets/skills/bulletproof/references/secure-defaults.md +6 -5
- package/assets/skills/bulletproof/references/supply-chain.md +21 -17
- package/assets/skills/bulletproof/references/threat-landscape.md +28 -26
- package/assets/skills/bulletproof/references/verification.md +2 -0
- package/assets/skills/clarify/SKILL.md +25 -16
- package/assets/skills/code-review/SKILL.md +71 -13
- package/assets/skills/code-review/references/agent-diffs.md +27 -0
- package/assets/skills/code-review/references/tests.md +19 -0
- package/assets/skills/compliance-guard/SKILL.md +20 -5
- package/assets/skills/compliance-guard/references/artifacts.md +1 -1
- package/assets/skills/compliance-guard/references/eu-uk.md +16 -16
- package/assets/skills/compliance-guard/references/lawsuit-vectors.md +5 -5
- package/assets/skills/compliance-guard/references/provenance.md +41 -2
- package/assets/skills/compliance-guard/references/sector-gates.md +3 -3
- package/assets/skills/compliance-guard/references/security-baseline.md +2 -2
- package/assets/skills/compliance-guard/references/trigger-map.md +5 -5
- package/assets/skills/compliance-guard/references/us.md +27 -21
- package/assets/skills/durable/SKILL.md +87 -79
- package/assets/skills/durable/references/agent-db-safety.md +69 -0
- package/assets/skills/durable/references/backups-and-runtime.md +19 -12
- package/assets/skills/durable/references/migrations-and-schema.md +13 -6
- package/assets/skills/evidence-led-ui/SKILL.md +69 -127
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +107 -208
- package/assets/skills/evidence-led-ui/references/direction.md +124 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +8 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +24 -1
- package/assets/skills/lean/SKILL.md +90 -71
- package/assets/skills/lean/references/memory-and-processes.md +3 -2
- package/assets/skills/lean/references/playbooks.md +37 -12
- package/assets/skills/refactoring/SKILL.md +24 -3
- package/assets/skills/refactoring/references/agent-pitfalls.md +4 -1
- package/assets/skills/refactoring/references/legacy.md +21 -0
- package/assets/skills/root-cause/SKILL.md +20 -10
- package/assets/skills/shared-language/SKILL.md +16 -14
- package/assets/skills/tdd/SKILL.md +27 -15
- package/dist/app-sidecar.js +203 -47
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +20 -28
- package/dist/cli.js.map +1 -1
- package/dist/core/acceptance-checks.d.ts +48 -0
- package/dist/core/acceptance-checks.js +144 -0
- package/dist/core/acceptance-checks.js.map +1 -0
- package/dist/core/agent-session.d.ts +119 -75
- package/dist/core/agent-session.js +561 -395
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +6 -5
- package/dist/core/agents.js +12 -3
- package/dist/core/agents.js.map +1 -1
- package/dist/core/ask-user.d.ts +90 -8
- package/dist/core/ask-user.js +124 -13
- package/dist/core/ask-user.js.map +1 -1
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/autopilot-verdict.d.ts +5 -1
- package/dist/core/autopilot-verdict.js +30 -13
- package/dist/core/autopilot-verdict.js.map +1 -1
- package/dist/core/bundled-agents.js +1 -3
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/cache-diagnostics.d.ts +68 -0
- package/dist/core/cache-diagnostics.js +196 -0
- package/dist/core/cache-diagnostics.js.map +1 -0
- package/dist/core/cache-expiry.d.ts +87 -0
- package/dist/core/cache-expiry.js +111 -0
- package/dist/core/cache-expiry.js.map +1 -0
- package/dist/core/compaction/compactor.js +78 -48
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/plan-step-policy.d.ts +46 -0
- package/dist/core/compaction/plan-step-policy.js +57 -0
- package/dist/core/compaction/plan-step-policy.js.map +1 -0
- package/dist/core/destructive-git-guard.d.ts +90 -0
- package/dist/core/destructive-git-guard.js +871 -0
- package/dist/core/destructive-git-guard.js.map +1 -0
- package/dist/core/event-bus.d.ts +3 -0
- package/dist/core/event-bus.js +5 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/fast-apply-benchmark.d.ts +1 -1
- package/dist/core/fast-apply-benchmark.js +2 -2
- package/dist/core/fast-apply-benchmark.js.map +1 -1
- package/dist/core/injection-detect.d.ts +38 -0
- package/dist/core/injection-detect.js +232 -0
- package/dist/core/injection-detect.js.map +1 -0
- package/dist/core/keep-awake.d.ts +88 -0
- package/dist/core/keep-awake.js +251 -0
- package/dist/core/keep-awake.js.map +1 -0
- package/dist/core/mcp/client.d.ts +72 -0
- package/dist/core/mcp/client.js +264 -41
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/content.js +6 -2
- package/dist/core/mcp/content.js.map +1 -1
- package/dist/core/mcp/store.d.ts +6 -1
- package/dist/core/mcp/store.js +12 -1
- package/dist/core/mcp/store.js.map +1 -1
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/model-unavailable.d.ts +14 -0
- package/dist/core/model-unavailable.js +23 -0
- package/dist/core/model-unavailable.js.map +1 -0
- package/dist/core/node-debugger.d.ts +148 -0
- package/dist/core/node-debugger.js +642 -0
- package/dist/core/node-debugger.js.map +1 -0
- package/dist/core/nolan-context.d.ts +7 -5
- package/dist/core/nolan-context.js +106 -16
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-prompt.js +24 -21
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/package-threats.d.ts +18 -0
- package/dist/core/package-threats.js +168 -0
- package/dist/core/package-threats.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +58 -6
- package/dist/core/persistent-shell.js +331 -49
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager.d.ts +14 -0
- package/dist/core/process-manager.js +61 -0
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/progress/git-xp.js +8 -14
- package/dist/core/progress/git-xp.js.map +1 -1
- package/dist/core/project-discovery.js +77 -26
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/semantic-search-benchmark.d.ts +1 -1
- package/dist/core/semantic-search-benchmark.js +2 -2
- package/dist/core/semantic-search-benchmark.js.map +1 -1
- package/dist/core/session-history.d.ts +12 -0
- package/dist/core/session-history.js +27 -0
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.js +38 -18
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-summary-index.d.ts +37 -0
- package/dist/core/session-summary-index.js +172 -0
- package/dist/core/session-summary-index.js.map +1 -0
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.js +10 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/shell-threats-popular-packages.d.ts +11 -0
- package/dist/core/shell-threats-popular-packages.js +675 -0
- package/dist/core/shell-threats-popular-packages.js.map +1 -0
- package/dist/core/shell-threats.d.ts +8 -0
- package/dist/core/shell-threats.js +186 -0
- package/dist/core/shell-threats.js.map +1 -0
- package/dist/core/skills.js +16 -4
- package/dist/core/skills.js.map +1 -1
- package/dist/core/stream-rules.d.ts +30 -0
- package/dist/core/stream-rules.js +151 -0
- package/dist/core/stream-rules.js.map +1 -0
- package/dist/core/subagent-manager.d.ts +23 -6
- package/dist/core/subagent-manager.js +25 -9
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-policy.js +1 -1
- package/dist/core/subagent-policy.js.map +1 -1
- package/dist/core/subagent-receipt.d.ts +54 -0
- package/dist/core/subagent-receipt.js +276 -0
- package/dist/core/subagent-receipt.js.map +1 -0
- package/dist/core/subagent-turn-record.d.ts +2 -0
- package/dist/core/subagent-turn-record.js.map +1 -1
- package/dist/core/test-impact.d.ts +73 -0
- package/dist/core/test-impact.js +467 -0
- package/dist/core/test-impact.js.map +1 -0
- package/dist/core/thinking-level.d.ts +1 -1
- package/dist/core/thinking-level.js +1 -1
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/verification-gate.d.ts +2 -0
- package/dist/core/verification-gate.js +4 -0
- package/dist/core/verification-gate.js.map +1 -1
- package/dist/core/verification-snapshot.js +3 -5
- package/dist/core/verification-snapshot.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +18 -7
- package/dist/core/workspace-guard.js +227 -60
- package/dist/core/workspace-guard.js.map +1 -1
- package/dist/core/worktree-setup.d.ts +23 -0
- package/dist/core/worktree-setup.js +128 -9
- package/dist/core/worktree-setup.js.map +1 -1
- package/dist/core/worktree.d.ts +20 -2
- package/dist/core/worktree.js +74 -31
- package/dist/core/worktree.js.map +1 -1
- package/dist/interactive.js +2 -1
- package/dist/interactive.js.map +1 -1
- package/dist/modes/json-mode.js +11 -2
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +36 -1
- package/dist/modes/subagent-worker-mode.js +100 -42
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/motion-agent/motion-agent.d.ts +7 -3
- package/dist/motion-agent/motion-agent.js +6 -8
- package/dist/motion-agent/motion-agent.js.map +1 -1
- package/dist/motion-agent/motion-prompt.d.ts +1 -1
- package/dist/motion-agent/motion-prompt.js +16 -25
- package/dist/motion-agent/motion-prompt.js.map +1 -1
- package/dist/motion-agent/motion-review-session.js +1 -1
- package/dist/motion-agent/motion-review-session.js.map +1 -1
- package/dist/motion-agent/motion-review.d.ts +10 -3
- package/dist/motion-agent/motion-review.js +15 -7
- package/dist/motion-agent/motion-review.js.map +1 -1
- package/dist/motion-agent/motion-studio-context.js +1 -1
- package/dist/motion-agent/motion-studio-context.js.map +1 -1
- package/dist/system-prompt.d.ts +2 -1
- package/dist/system-prompt.js +15 -4
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/keep-alive.d.ts +14 -0
- package/dist/test-support/keep-alive.js +17 -0
- package/dist/test-support/keep-alive.js.map +1 -0
- package/dist/tools/ask-user.js +3 -3
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash-read-evidence.d.ts +10 -0
- package/dist/tools/bash-read-evidence.js +133 -0
- package/dist/tools/bash-read-evidence.js.map +1 -0
- package/dist/tools/bash.d.ts +10 -1
- package/dist/tools/bash.js +179 -7
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/debug.d.ts +54 -0
- package/dist/tools/debug.js +233 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/edit.js +13 -5
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/goals.d.ts +1 -1
- package/dist/tools/index.d.ts +25 -2
- package/dist/tools/index.js +48 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.js +2 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-tracker.d.ts +35 -2
- package/dist/tools/read-tracker.js +108 -11
- package/dist/tools/read-tracker.js.map +1 -1
- package/dist/tools/read.js +39 -7
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/skill.js +5 -0
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +44 -8
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +48 -8
- package/dist/tools/subagent-shared.js +75 -14
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +8 -2
- package/dist/tools/subagent.js +28 -10
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +3 -2
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.d.ts +1 -1
- package/dist/tools/task-send.js +15 -1
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +2 -2
- package/dist/tools/tool-tiers.js +3 -2
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/truncate.d.ts +21 -0
- package/dist/tools/truncate.js +187 -0
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/ui-adopt.js +2 -0
- package/dist/tools/ui-adopt.js.map +1 -1
- package/dist/tools/write.js +4 -3
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.d.ts +0 -4
- package/dist/ui/App.js +5 -28
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/Footer.js +1 -1
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +1 -8
- package/dist/ui/hooks/useAgentLoop.js +1 -119
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/render.d.ts +2 -4
- package/dist/ui/render.js +3 -2
- package/dist/ui/render.js.map +1 -1
- package/dist/utils/git.d.ts +77 -0
- package/dist/utils/git.js +285 -21
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/github-ci.js +2 -1
- package/dist/utils/github-ci.js.map +1 -1
- package/dist/utils/github.js +11 -9
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +16 -0
- package/dist/utils/image.js.map +1 -1
- package/dist/utils/process.d.ts +20 -0
- package/dist/utils/process.js +98 -0
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.js +11 -0
- package/dist/utils/text.js.map +1 -1
- package/package.json +6 -6
- package/assets/motion/skills/mixkit-split-text-617/SKILL.md +0 -115
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-480.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-494.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-5.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-508.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6525.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6539.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6647.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6663.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6677.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6691.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6706.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6722.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6736.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6750.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6764.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6780.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6794.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6810.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6823.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6872.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6936.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-76.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/manifest.json +0 -495
- package/assets/motion/skills/mixkit-split-text-617/references/RECONSTRUCTION.md +0 -201
- package/assets/motion/skills/mixkit-split-text-617/references/VERIFICATION.md +0 -107
- package/assets/motion/skills/mixkit-split-text-617/tools/inspect_motion.py +0 -130
- package/assets/motion/skills/video-qa/SKILL.md +0 -66
- package/dist/core/ideal-review-subagent.d.ts +0 -42
- package/dist/core/ideal-review-subagent.js +0 -95
- package/dist/core/ideal-review-subagent.js.map +0 -1
- package/dist/core/ideal-review.d.ts +0 -82
- package/dist/core/ideal-review.js +0 -242
- package/dist/core/ideal-review.js.map +0 -1
- package/dist/motion-agent/motion-check-tool.d.ts +0 -21
- package/dist/motion-agent/motion-check-tool.js +0 -206
- package/dist/motion-agent/motion-check-tool.js.map +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local, deterministic shell-threat rules. Run against every command the
|
|
3
|
+
* agent is about to execute (bash tool, task_send input) and refuse the
|
|
4
|
+
* clearly-dangerous shapes: pipe-to-shell installers, reverse shells, secret
|
|
5
|
+
* exfiltration, lookalike (IDN/punycode) hosts and terminal-escape tricks.
|
|
6
|
+
*
|
|
7
|
+
* These are regexes over the full command text, not a shell parser. Known
|
|
8
|
+
* trade-off: quoted text inside `echo`/`printf` (e.g. `echo "curl x | sh"`)
|
|
9
|
+
* may be flagged too. That false positive is acceptable — the agent can write
|
|
10
|
+
* such text to a file with the write tool instead.
|
|
11
|
+
*/
|
|
12
|
+
import { extractCommandHosts, hostFromUrl } from "./network-guard.js";
|
|
13
|
+
const SHELLS = "(?:sudo\\s+)?(?:[\\w./-]*/)?(?:sh|bash|zsh|dash|ksh|python[\\d.]*|node|perl|ruby)\\b";
|
|
14
|
+
const FETCHERS = "\\b(?:curl|wget)\\b";
|
|
15
|
+
const PIPE_TO_SHELL = [
|
|
16
|
+
// curl … | sh (any number of intermediate pipeline stages)
|
|
17
|
+
// An interpreter given an inline script (-c/-e/-m/-p) or a script file reads
|
|
18
|
+
// stdin as data (`curl … | python -m json.tool`), so that is not flagged.
|
|
19
|
+
new RegExp(`${FETCHERS}[^;&\\n]*\\|\\s*${SHELLS}(?!\\s+(?:-[cmepE]\\b|--eval\\b|--print\\b|[^-\\s|;&]))`, "i"),
|
|
20
|
+
// bash <(curl …)
|
|
21
|
+
new RegExp(`${SHELLS}\\s+<\\(\\s*(?:curl|wget)\\b`, "i"),
|
|
22
|
+
// sh -c "$(curl …)" / $(wget …) / `curl …` executed
|
|
23
|
+
new RegExp(`${SHELLS}\\s+(?:-\\w+\\s+)*["']?\\$\\(\\s*(?:curl|wget)\\b`, "i"),
|
|
24
|
+
new RegExp(`${SHELLS}\\s+(?:-\\w+\\s+)*["']?\`\\s*(?:curl|wget)\\b`, "i"),
|
|
25
|
+
// eval "$(curl …)"
|
|
26
|
+
/\beval\s+["']?\$\(\s*(?:curl|wget)\b/i,
|
|
27
|
+
// PowerShell: iex (iwr …) / irm … | iex / Invoke-Expression
|
|
28
|
+
/\b(?:iex|invoke-expression)\b[\s(]*(?:\(?\s*)(?:iwr|irm|invoke-webrequest|invoke-restmethod|\(?new-object\s+net\.webclient)/i,
|
|
29
|
+
/\b(?:iwr|irm|invoke-webrequest|invoke-restmethod)\b[^\n]*\|\s*(?:iex|invoke-expression)\b/i,
|
|
30
|
+
/\binvoke-expression\b/i,
|
|
31
|
+
];
|
|
32
|
+
const REVERSE_SHELL = [
|
|
33
|
+
/\/dev\/(?:tcp|udp)\//i,
|
|
34
|
+
// Case-sensitive: nc flags are case-significant (`-C` is CRLF, not `-c`).
|
|
35
|
+
/\b(?:nc|ncat|netcat)\b[^|;&\n]*\s(?:-[a-zA-Z]*[ec]\b|--exec\b|--sh-exec\b|-e\S|-c\S)/,
|
|
36
|
+
/\bsocat\b[^\n]*\b(?:exec|system):/i,
|
|
37
|
+
/\bbash\s+-i\s*>&/i,
|
|
38
|
+
];
|
|
39
|
+
/** python -c / perl -e one-liners that open a socket and connect/spawn. */
|
|
40
|
+
function isScriptReverseShell(command) {
|
|
41
|
+
if (!/\b(?:python[\d.]*\s+-c|perl\s+-e)\b/i.test(command))
|
|
42
|
+
return false;
|
|
43
|
+
return /\bsocket\b/i.test(command) && /\b(?:connect|subprocess|exec)\b/i.test(command);
|
|
44
|
+
}
|
|
45
|
+
const SECRET_SOURCES = [
|
|
46
|
+
/~\/\.ssh\//,
|
|
47
|
+
/\.ssh\//,
|
|
48
|
+
/\bid_(?:rsa|ed25519|ecdsa|dsa)\b/,
|
|
49
|
+
/\.aws\/credentials\b/,
|
|
50
|
+
/\.ezcoder\/auth\.json\b/,
|
|
51
|
+
/\.netrc\b/,
|
|
52
|
+
/\.npmrc\b/,
|
|
53
|
+
// `.env` / `.env.local` as a path component, but not `.env.example`/`.env.sample`.
|
|
54
|
+
/(?:^|[\s/'"=@<])\.env(?!\.(?:example|sample|template|dist)\b)(?:\.[\w-]+)?(?=$|[\s'"|;&)>])/,
|
|
55
|
+
/\bsecurity\s+find-(?:generic|internet)-password\b/,
|
|
56
|
+
/(?:^|[;&|(]\s*)(?:printenv|env)\s*(?:\||$)/m,
|
|
57
|
+
];
|
|
58
|
+
const NETWORK_SINKS = [
|
|
59
|
+
// Case-sensitive: `-f`/`-t`/`-D` are not upload flags. A short cluster such
|
|
60
|
+
// as `-sd` counts only when the data flag is last (it takes the value).
|
|
61
|
+
/\bcurl\b[^\n]*\s(?:-[a-zA-Z]*[dFT]|--data(?:-\w+)?|--form(?:-string)?|--upload-file)(?=[\s=@'"]|$)/,
|
|
62
|
+
/\bcurl\b[^\n]*\s@\S/i,
|
|
63
|
+
/\bwget\b[^\n]*--post-(?:data|file)\b/i,
|
|
64
|
+
/\b(?:nc|ncat|netcat)\s/i,
|
|
65
|
+
/\b(?:scp|rsync)\b[^\n]*\s[\w.@-]+:/i,
|
|
66
|
+
/\bxargs\b[^\n]*\b(?:curl|wget)\b/i,
|
|
67
|
+
/\bfind\b[^\n]*-exec\s+(?:curl|wget)\b/i,
|
|
68
|
+
];
|
|
69
|
+
// eslint-disable-next-line no-control-regex -- matching ESC is the point
|
|
70
|
+
const TERMINAL_TRICK = /[\u001b\u202a-\u202e\u2066-\u2069\u200b-\u200d\u2060\ufeff]/u;
|
|
71
|
+
function codepoint(ch) {
|
|
72
|
+
return `U+${(ch.codePointAt(0) ?? 0).toString(16).toUpperCase().padStart(4, "0")}`;
|
|
73
|
+
}
|
|
74
|
+
/** Programs whose bare dotted operands are hostnames (`ping аpple.com`). */
|
|
75
|
+
const NETWORK_PROGRAMS = new Set([
|
|
76
|
+
"curl",
|
|
77
|
+
"wget",
|
|
78
|
+
"ping",
|
|
79
|
+
"ssh",
|
|
80
|
+
"scp",
|
|
81
|
+
"sftp",
|
|
82
|
+
"rsync",
|
|
83
|
+
"git",
|
|
84
|
+
"nc",
|
|
85
|
+
"ncat",
|
|
86
|
+
"netcat",
|
|
87
|
+
"telnet",
|
|
88
|
+
"ftp",
|
|
89
|
+
"dig",
|
|
90
|
+
"nslookup",
|
|
91
|
+
"host",
|
|
92
|
+
"http",
|
|
93
|
+
"https",
|
|
94
|
+
]);
|
|
95
|
+
/**
|
|
96
|
+
* Candidate hostnames: URL authorities anywhere, plus bare dotted operands of
|
|
97
|
+
* network programs only — so non-ASCII file names (`cat résumé.pdf`) pass.
|
|
98
|
+
*/
|
|
99
|
+
function candidateHosts(command) {
|
|
100
|
+
const out = new Set();
|
|
101
|
+
for (const m of command.matchAll(/[a-z][a-z0-9+.-]*:\/\/(?:[^@\s/'"]*@)?([^\s/:'"?#]+)/giu)) {
|
|
102
|
+
if (m[1])
|
|
103
|
+
out.add(m[1].toLowerCase());
|
|
104
|
+
}
|
|
105
|
+
for (const segment of command.split(/(?:&&|\|\||[;|\n])/)) {
|
|
106
|
+
const tokens = segment.split(/[\s'"()<>]+/).filter((t) => t.length > 0);
|
|
107
|
+
if (tokens[0] === "sudo")
|
|
108
|
+
tokens.shift();
|
|
109
|
+
const program = (tokens[0] ?? "").split("/").pop() ?? "";
|
|
110
|
+
if (!NETWORK_PROGRAMS.has(program))
|
|
111
|
+
continue;
|
|
112
|
+
for (const token of tokens.slice(1)) {
|
|
113
|
+
const bare = token.replace(/^[\w.-]*@/, "").split(/[/:?#]/)[0] ?? "";
|
|
114
|
+
if (/^[\p{L}\p{N}-]+(?:\.[\p{L}\p{N}-]+)+$/u.test(bare) && /\p{L}/u.test(bare)) {
|
|
115
|
+
out.add(bare.toLowerCase());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const host of extractCommandHosts(command))
|
|
120
|
+
out.add(host);
|
|
121
|
+
return [...out];
|
|
122
|
+
}
|
|
123
|
+
function lookalikeThreats(command) {
|
|
124
|
+
const threats = [];
|
|
125
|
+
const seen = new Set();
|
|
126
|
+
for (const host of candidateHosts(command)) {
|
|
127
|
+
const nonAscii = /[^\p{ASCII}]/u.test(host);
|
|
128
|
+
const punycodeLabel = host.split(".").some((label) => label.startsWith("xn--"));
|
|
129
|
+
if (!nonAscii && !punycodeLabel)
|
|
130
|
+
continue;
|
|
131
|
+
const ascii = nonAscii ? (hostFromUrl(`http://${host}`) ?? host) : host;
|
|
132
|
+
if (seen.has(ascii))
|
|
133
|
+
continue;
|
|
134
|
+
seen.add(ascii);
|
|
135
|
+
threats.push({
|
|
136
|
+
rule: "lookalike-host",
|
|
137
|
+
severity: "block",
|
|
138
|
+
detail: nonAscii
|
|
139
|
+
? `host "${host}" contains non-ASCII characters (resolves as ${ascii}) — likely a lookalike of a real domain`
|
|
140
|
+
: `host "${host}" uses a punycode (xn--) label — likely a lookalike of a real domain`,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return threats;
|
|
144
|
+
}
|
|
145
|
+
export function checkShellThreats(command) {
|
|
146
|
+
const threats = [];
|
|
147
|
+
const trick = TERMINAL_TRICK.exec(command);
|
|
148
|
+
if (trick) {
|
|
149
|
+
threats.push({
|
|
150
|
+
rule: "terminal-tricks",
|
|
151
|
+
severity: "block",
|
|
152
|
+
detail: `command contains invisible/control character ${codepoint(trick[0])} (ANSI escape, bidi override or zero-width) that can hide what actually runs`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (PIPE_TO_SHELL.some((re) => re.test(command))) {
|
|
156
|
+
threats.push({
|
|
157
|
+
rule: "pipe-to-shell",
|
|
158
|
+
severity: "block",
|
|
159
|
+
detail: "remote content is executed directly by a shell/interpreter. Download it to a file first " +
|
|
160
|
+
"(e.g. `curl -fsSL -o install.sh <url>`), read it, then run it.",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (REVERSE_SHELL.some((re) => re.test(command)) || isScriptReverseShell(command)) {
|
|
164
|
+
threats.push({
|
|
165
|
+
rule: "reverse-shell",
|
|
166
|
+
severity: "block",
|
|
167
|
+
detail: "command matches a reverse-shell pattern (remote shell access over a socket)",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (SECRET_SOURCES.some((re) => re.test(command)) &&
|
|
171
|
+
NETWORK_SINKS.some((re) => re.test(command))) {
|
|
172
|
+
threats.push({
|
|
173
|
+
rule: "secret-exfil",
|
|
174
|
+
severity: "block",
|
|
175
|
+
detail: "command reads secret material (keys, credentials, .env, environment) and sends data over the network",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
threats.push(...lookalikeThreats(command));
|
|
179
|
+
return threats;
|
|
180
|
+
}
|
|
181
|
+
/** First blocking threat as a refusal message, or null when the command may run. */
|
|
182
|
+
export function shellThreatBlockMessage(command) {
|
|
183
|
+
const threat = checkShellThreats(command).find((t) => t.severity === "block");
|
|
184
|
+
return threat ? `Blocked by shell safety check (${threat.rule}): ${threat.detail}` : null;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=shell-threats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-threats.js","sourceRoot":"","sources":["../../src/core/shell-threats.ts"],"names":[],"mappings":"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"}
|
package/dist/core/skills.js
CHANGED
|
@@ -2,8 +2,9 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { clampToBytes, CONTEXT_LIMITS } from "./context-limits.js";
|
|
5
|
-
import {
|
|
5
|
+
import { cleanInstructionText } from "../utils/text.js";
|
|
6
6
|
import { parseFrontmatter } from "./frontmatter.js";
|
|
7
|
+
import { log } from "./logger.js";
|
|
7
8
|
const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
8
9
|
export const BUNDLED_SKILLS_DIRS = [
|
|
9
10
|
// Single-file desktop sidecar: resources live beside app-sidecar.mjs.
|
|
@@ -121,10 +122,19 @@ async function loadSkillsFromDir(dir, source) {
|
|
|
121
122
|
* Frontmatter values may be quoted or YAML block scalars (`description: >`).
|
|
122
123
|
*/
|
|
123
124
|
export function parseSkillFile(rawInput, source) {
|
|
124
|
-
// A BOM before `---` would otherwise silently kill frontmatter parsing
|
|
125
|
-
|
|
125
|
+
// A BOM before `---` would otherwise silently kill frontmatter parsing, and a
|
|
126
|
+
// skill or command shipped in a repo can hide instructions in invisible text.
|
|
127
|
+
const cleaned = cleanInstructionText(rawInput);
|
|
128
|
+
const { fields, body: content } = parseFrontmatter(cleaned.text);
|
|
126
129
|
const name = fields.name ?? "";
|
|
127
130
|
const description = fields.description ?? "";
|
|
131
|
+
if (cleaned.stripped > 0) {
|
|
132
|
+
log("WARN", "skills", "Stripped invisible characters from a skill file", {
|
|
133
|
+
name,
|
|
134
|
+
source,
|
|
135
|
+
stripped: cleaned.stripped,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
128
138
|
return { name, description, content, source };
|
|
129
139
|
}
|
|
130
140
|
/**
|
|
@@ -173,7 +183,9 @@ export function formatSkillsForPrompt(skills, limits = CONTEXT_LIMITS) {
|
|
|
173
183
|
`Respect explicit exclusions in the description. Matching skill instructions specialize this prompt but do not override project or file/module rules.\n\n` +
|
|
174
184
|
`Match the work, not the topic: a skill's subject matter appearing in the request is not a match when the actual change falls outside its scope. ` +
|
|
175
185
|
`Skip the skill when the task is routine, narrow, or already covered by existing patterns in the codebase \u2014 an unnecessary invocation costs context and slows the task. ` +
|
|
176
|
-
`Invoke at most one skill unless the task genuinely spans
|
|
186
|
+
`Invoke at most one skill unless the task genuinely spans several, and do not re-invoke a skill whose instructions are already in this conversation. ` +
|
|
187
|
+
`Launch-readiness asks span every listed skill in scope, in order durable, bulletproof, compliance-guard, lean, evidence-led-ui: ` +
|
|
188
|
+
`one report-only child per skill in a single spawn_agent call; a failed child is reported as not checked, never as clean.\n\n` +
|
|
177
189
|
list +
|
|
178
190
|
overflow);
|
|
179
191
|
}
|
package/dist/core/skills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads stream rules (regex guards matched against the model's streaming
|
|
3
|
+
* output — see @prestyj/agent `stream-rules.ts`) from markdown files:
|
|
4
|
+
*
|
|
5
|
+
* ~/.ezcoder/rules/*.md user rules (trusted)
|
|
6
|
+
* <cwd>/.ezcoder/rules/*.md project rules (untrusted; override user rules by name)
|
|
7
|
+
*
|
|
8
|
+
* No rules ship built in. Example `.ezcoder/rules/no-console-log.md`:
|
|
9
|
+
*
|
|
10
|
+
* ---
|
|
11
|
+
* name: no-console-log
|
|
12
|
+
* trigger: console\.log\(
|
|
13
|
+
* scope: tool # text | tool | both (default both)
|
|
14
|
+
* tools: [edit, write] # optional; restricts tool-scope matching
|
|
15
|
+
* ---
|
|
16
|
+
* Do not add console.log calls. Use the project logger (`log()` from
|
|
17
|
+
* core/logger.ts) instead.
|
|
18
|
+
*
|
|
19
|
+
* `trigger` is a JavaScript regex source; `/source/flags` form is accepted
|
|
20
|
+
* with flags from `imsu`. The body is the reminder shown to the model when the
|
|
21
|
+
* rule fires (trimmed, capped at 1,000 chars). Project triggers longer than
|
|
22
|
+
* 300 chars or with nested quantifiers (catastrophic-backtracking risk) are
|
|
23
|
+
* skipped. Invalid files are skipped with a WARN log; loading never throws.
|
|
24
|
+
*/
|
|
25
|
+
import type { StreamRule } from "@prestyj/agent";
|
|
26
|
+
export declare const MAX_STREAM_RULES = 50;
|
|
27
|
+
export declare const MAX_STREAM_RULE_REMINDER_CHARS = 1000;
|
|
28
|
+
export declare const MAX_PROJECT_TRIGGER_CHARS = 300;
|
|
29
|
+
/** Load user + project stream rules. Project rules override user rules with the same name. */
|
|
30
|
+
export declare function loadStreamRules(cwd: string, home?: string): Promise<StreamRule[]>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads stream rules (regex guards matched against the model's streaming
|
|
3
|
+
* output — see @prestyj/agent `stream-rules.ts`) from markdown files:
|
|
4
|
+
*
|
|
5
|
+
* ~/.ezcoder/rules/*.md user rules (trusted)
|
|
6
|
+
* <cwd>/.ezcoder/rules/*.md project rules (untrusted; override user rules by name)
|
|
7
|
+
*
|
|
8
|
+
* No rules ship built in. Example `.ezcoder/rules/no-console-log.md`:
|
|
9
|
+
*
|
|
10
|
+
* ---
|
|
11
|
+
* name: no-console-log
|
|
12
|
+
* trigger: console\.log\(
|
|
13
|
+
* scope: tool # text | tool | both (default both)
|
|
14
|
+
* tools: [edit, write] # optional; restricts tool-scope matching
|
|
15
|
+
* ---
|
|
16
|
+
* Do not add console.log calls. Use the project logger (`log()` from
|
|
17
|
+
* core/logger.ts) instead.
|
|
18
|
+
*
|
|
19
|
+
* `trigger` is a JavaScript regex source; `/source/flags` form is accepted
|
|
20
|
+
* with flags from `imsu`. The body is the reminder shown to the model when the
|
|
21
|
+
* rule fires (trimmed, capped at 1,000 chars). Project triggers longer than
|
|
22
|
+
* 300 chars or with nested quantifiers (catastrophic-backtracking risk) are
|
|
23
|
+
* skipped. Invalid files are skipped with a WARN log; loading never throws.
|
|
24
|
+
*/
|
|
25
|
+
import fs from "node:fs/promises";
|
|
26
|
+
import os from "node:os";
|
|
27
|
+
import path from "node:path";
|
|
28
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
29
|
+
import { log } from "./logger.js";
|
|
30
|
+
export const MAX_STREAM_RULES = 50;
|
|
31
|
+
export const MAX_STREAM_RULE_REMINDER_CHARS = 1000;
|
|
32
|
+
export const MAX_PROJECT_TRIGGER_CHARS = 300;
|
|
33
|
+
/** Heuristic for nested quantifiers like `(a+)+`, `(\w*)*`, `(x+){2,}`. */
|
|
34
|
+
const NESTED_QUANTIFIER = /\([^)]*[+*][^)]*\)[+*{]/;
|
|
35
|
+
const REGEX_LITERAL = /^\/(.+)\/([imsu]*)$/s;
|
|
36
|
+
async function listRuleFiles(dir) {
|
|
37
|
+
try {
|
|
38
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
39
|
+
return entries
|
|
40
|
+
.filter((e) => e.isFile() && e.name.toLowerCase().endsWith(".md"))
|
|
41
|
+
.map((e) => path.join(dir, e.name))
|
|
42
|
+
.sort();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function parseTools(raw) {
|
|
49
|
+
if (raw === undefined)
|
|
50
|
+
return undefined;
|
|
51
|
+
const tools = raw
|
|
52
|
+
.replace(/^\[|\]$/g, "")
|
|
53
|
+
.split(/[\s,]+/)
|
|
54
|
+
.map((t) => t
|
|
55
|
+
.replace(/^-+$/, "")
|
|
56
|
+
.replace(/^["']|["']$/g, "")
|
|
57
|
+
.trim())
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
return tools.length > 0 ? tools : undefined;
|
|
60
|
+
}
|
|
61
|
+
function parseScope(raw) {
|
|
62
|
+
if (raw === undefined || raw.trim() === "")
|
|
63
|
+
return "both";
|
|
64
|
+
const scope = raw.trim().toLowerCase();
|
|
65
|
+
return scope === "text" || scope === "tool" || scope === "both" ? scope : null;
|
|
66
|
+
}
|
|
67
|
+
function compileTrigger(trigger, origin) {
|
|
68
|
+
if (origin === "project") {
|
|
69
|
+
if (trigger.length > MAX_PROJECT_TRIGGER_CHARS) {
|
|
70
|
+
return `trigger exceeds ${MAX_PROJECT_TRIGGER_CHARS} chars`;
|
|
71
|
+
}
|
|
72
|
+
if (NESTED_QUANTIFIER.test(trigger))
|
|
73
|
+
return "trigger has nested quantifiers";
|
|
74
|
+
}
|
|
75
|
+
const literal = REGEX_LITERAL.exec(trigger);
|
|
76
|
+
try {
|
|
77
|
+
return literal ? new RegExp(literal[1], literal[2]) : new RegExp(trigger);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
return `invalid regex: ${err instanceof Error ? err.message : String(err)}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function readRule(file, origin) {
|
|
84
|
+
const skip = (reason) => {
|
|
85
|
+
log("WARN", "stream-rules", `Skipping stream rule ${file}: ${reason}`);
|
|
86
|
+
return null;
|
|
87
|
+
};
|
|
88
|
+
let raw;
|
|
89
|
+
try {
|
|
90
|
+
raw = await fs.readFile(file, "utf8");
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
return skip(`unreadable (${err instanceof Error ? err.message : String(err)})`);
|
|
94
|
+
}
|
|
95
|
+
const { fields, body, hasFrontmatter } = parseFrontmatter(raw);
|
|
96
|
+
if (!hasFrontmatter)
|
|
97
|
+
return skip("missing frontmatter");
|
|
98
|
+
const name = fields.name?.trim();
|
|
99
|
+
if (!name)
|
|
100
|
+
return skip("missing name");
|
|
101
|
+
const trigger = fields.trigger?.trim();
|
|
102
|
+
if (!trigger)
|
|
103
|
+
return skip("missing trigger");
|
|
104
|
+
const scope = parseScope(fields.scope);
|
|
105
|
+
if (!scope)
|
|
106
|
+
return skip(`invalid scope "${fields.scope ?? ""}"`);
|
|
107
|
+
const pattern = compileTrigger(trigger, origin);
|
|
108
|
+
if (typeof pattern === "string")
|
|
109
|
+
return skip(pattern);
|
|
110
|
+
const reminder = body.trim().slice(0, MAX_STREAM_RULE_REMINDER_CHARS);
|
|
111
|
+
if (!reminder)
|
|
112
|
+
return skip("empty reminder body");
|
|
113
|
+
const tools = parseTools(fields.tools);
|
|
114
|
+
return { name, pattern, scope, reminder, ...(tools ? { tools } : {}) };
|
|
115
|
+
}
|
|
116
|
+
async function loadDir(dir, origin) {
|
|
117
|
+
const rules = [];
|
|
118
|
+
for (const file of await listRuleFiles(dir)) {
|
|
119
|
+
const rule = await readRule(file, origin);
|
|
120
|
+
if (rule)
|
|
121
|
+
rules.push(rule);
|
|
122
|
+
}
|
|
123
|
+
return rules;
|
|
124
|
+
}
|
|
125
|
+
/** Load user + project stream rules. Project rules override user rules with the same name. */
|
|
126
|
+
export async function loadStreamRules(cwd, home = os.homedir()) {
|
|
127
|
+
try {
|
|
128
|
+
const byName = new Map();
|
|
129
|
+
for (const rule of await loadDir(path.join(home, ".ezcoder", "rules"), "user")) {
|
|
130
|
+
byName.set(rule.name, rule);
|
|
131
|
+
}
|
|
132
|
+
const projectDir = path.join(cwd, ".ezcoder", "rules");
|
|
133
|
+
// cwd === home would load the same dir twice and apply untrusted limits to user rules.
|
|
134
|
+
if (path.resolve(projectDir) !== path.resolve(home, ".ezcoder", "rules")) {
|
|
135
|
+
for (const rule of await loadDir(projectDir, "project")) {
|
|
136
|
+
byName.delete(rule.name);
|
|
137
|
+
byName.set(rule.name, rule);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const rules = [...byName.values()];
|
|
141
|
+
if (rules.length > MAX_STREAM_RULES) {
|
|
142
|
+
log("WARN", "stream-rules", `Only the first ${MAX_STREAM_RULES} of ${rules.length} stream rules are used`);
|
|
143
|
+
}
|
|
144
|
+
return rules.slice(0, MAX_STREAM_RULES);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
log("WARN", "stream-rules", `Failed to load stream rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=stream-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-rules.js","sourceRoot":"","sources":["../../src/core/stream-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { Message, Provider
|
|
1
|
+
import type { Message, Provider } from "@prestyj/ai";
|
|
2
2
|
import { type AgentDefinition } from "./agents.js";
|
|
3
3
|
import { SubAgentStore } from "./subagent-store.js";
|
|
4
4
|
import type { AgentNotificationQueue } from "./agent-notifications.js";
|
|
5
|
+
import type { AcceptanceCheck } from "./acceptance-checks.js";
|
|
5
6
|
import { type SubAgentTokenUsage } from "../tools/subagent-shared.js";
|
|
6
7
|
export type SubAgentState = "starting" | "running" | "completed" | "failed" | "interrupted" | "closed" | "reaped";
|
|
7
8
|
export interface SubAgentSnapshot {
|
|
@@ -16,6 +17,18 @@ export interface SubAgentSnapshot {
|
|
|
16
17
|
tool_use_count: number;
|
|
17
18
|
token_usage: SubAgentTokenUsage;
|
|
18
19
|
output?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Engine-built receipt of the last turn's tool calls plus any paths the
|
|
22
|
+
* report names that the child never opened. Kept apart from `output` so
|
|
23
|
+
* wait()'s head truncation can never cut it and output parsers (the ideal
|
|
24
|
+
* reviewer) see the child's prose unchanged.
|
|
25
|
+
*/
|
|
26
|
+
receipt?: string;
|
|
27
|
+
/**
|
|
28
|
+
* One-line verdict of the parent's acceptance checks for the last turn
|
|
29
|
+
* (`2/3 passed, 1 unverified`); the per-check lines ride in `receipt`.
|
|
30
|
+
*/
|
|
31
|
+
acceptance?: string;
|
|
19
32
|
error?: string;
|
|
20
33
|
agent_name?: string;
|
|
21
34
|
provider?: string;
|
|
@@ -30,12 +43,11 @@ export interface SubAgentManagerOptions {
|
|
|
30
43
|
agents: AgentDefinition[];
|
|
31
44
|
getProvider: () => Provider;
|
|
32
45
|
getModel: () => string;
|
|
33
|
-
getThinkingLevel: () => ThinkingLevel | undefined;
|
|
34
46
|
getCacheKey?: () => string | undefined;
|
|
35
47
|
getBaseUrl?: () => string | undefined;
|
|
36
48
|
/** Optional per-model concurrency cap (subagentMaxPerModel setting). Counted
|
|
37
|
-
* against the RESOLVED child model —
|
|
38
|
-
*
|
|
49
|
+
* against the RESOLVED child model — an agent pinned to its own model id
|
|
50
|
+
* counts under that model, not the parent's. Only ever
|
|
39
51
|
* reduces concurrency below the global ACTIVE_LIMIT. */
|
|
40
52
|
getMaxPerModel?: () => number | undefined;
|
|
41
53
|
onState?: (snapshot: SubAgentSnapshot) => void;
|
|
@@ -53,6 +65,8 @@ export interface SubAgentManagerOptions {
|
|
|
53
65
|
store?: SubAgentStore;
|
|
54
66
|
sessionRootDir?: string;
|
|
55
67
|
}
|
|
68
|
+
/** Children that may be starting or running at once. */
|
|
69
|
+
export declare const ACTIVE_LIMIT = 8;
|
|
56
70
|
/**
|
|
57
71
|
* Wait budgets, aligned with the child's own `SUB_AGENT_TIMEOUT_MS` (10 min).
|
|
58
72
|
* The previous 30s default and 5-min ceiling meant a parent waiting on a
|
|
@@ -101,13 +115,16 @@ export declare class SubAgentManager {
|
|
|
101
115
|
waitForPersistence(): Promise<void>;
|
|
102
116
|
/** Explicit per-spawn overrides. Used by harness-owned children (the
|
|
103
117
|
* independent Ideal reviewer): a read-only tool list and/or a forced model —
|
|
104
|
-
* bypassing agent-definition routing entirely
|
|
118
|
+
* bypassing agent-definition routing entirely — and a shorter turn time
|
|
119
|
+
* limit, after which the child answers from what it has gathered. */
|
|
105
120
|
spawn(taskName: string, task: string, agentName?: string, overrides?: {
|
|
106
121
|
model?: string;
|
|
107
122
|
tools?: readonly string[];
|
|
123
|
+
turnTimeoutMs?: number;
|
|
124
|
+
checks?: readonly AcceptanceCheck[];
|
|
108
125
|
}): Promise<SubAgentSnapshot>;
|
|
109
126
|
sendMessage(agentId: string, message: string): Promise<number>;
|
|
110
|
-
followup(agentId: string, task: string): Promise<SubAgentSnapshot>;
|
|
127
|
+
followup(agentId: string, task: string, checks?: readonly AcceptanceCheck[]): Promise<SubAgentSnapshot>;
|
|
111
128
|
interrupt(agentId: string, collectResult?: boolean): Promise<SubAgentSnapshot>;
|
|
112
129
|
subscribe(listener: (snapshot: SubAgentSnapshot) => void): () => void;
|
|
113
130
|
list(): SubAgentSnapshot[];
|