@code-yeongyu/senpi 2026.6.14 → 2026.6.16
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 +92 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +5 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js +3 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
- package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +24 -12
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/goal/command.d.ts +14 -0
- package/dist/core/extensions/builtin/goal/command.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/command.js +16 -0
- package/dist/core/extensions/builtin/goal/command.js.map +1 -0
- package/dist/core/extensions/builtin/goal/continuation.d.ts +4 -0
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/continuation.js +7 -0
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -0
- package/dist/core/extensions/builtin/goal/errors.d.ts +13 -0
- package/dist/core/extensions/builtin/goal/errors.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/errors.js +25 -0
- package/dist/core/extensions/builtin/goal/errors.js.map +1 -0
- package/dist/core/extensions/builtin/goal/format.d.ts +8 -0
- package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/format.js +71 -0
- package/dist/core/extensions/builtin/goal/format.js.map +1 -0
- package/dist/core/extensions/builtin/goal/index.d.ts +3 -0
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/index.js +322 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -0
- package/dist/core/extensions/builtin/goal/prompt.d.ts +3 -0
- package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/prompt.js +34 -0
- package/dist/core/extensions/builtin/goal/prompt.js.map +1 -0
- package/dist/core/extensions/builtin/goal/store.d.ts +9 -0
- package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/store.js +173 -0
- package/dist/core/extensions/builtin/goal/store.js.map +1 -0
- package/dist/core/extensions/builtin/goal/types.d.ts +50 -0
- package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/types.js +6 -0
- package/dist/core/extensions/builtin/goal/types.js.map +1 -0
- package/dist/core/extensions/builtin/goal/ui.d.ts +6 -0
- package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/ui.js +20 -0
- package/dist/core/extensions/builtin/goal/ui.js.map +1 -0
- package/dist/core/extensions/builtin/goal/validation.d.ts +3 -0
- package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/validation.js +13 -0
- package/dist/core/extensions/builtin/goal/validation.js.map +1 -0
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +10 -2
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/nested-agents-md/core/containment.d.ts +10 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/containment.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/containment.js +23 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/containment.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/errors.d.ts +5 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/errors.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/errors.js +9 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/errors.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.d.ts +7 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.js +44 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/find-agents-md-up.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/format.d.ts +7 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/format.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/format.js +7 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/format.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.d.ts +11 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.js +77 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/inject-directory-context.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.d.ts +11 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.js +33 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/injection-cache.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/session-key.d.ts +8 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/session-key.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/session-key.js +8 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/session-key.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/truncate.d.ts +8 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/truncate.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/truncate.js +26 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/truncate.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/types.d.ts +25 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/types.js +4 -0
- package/dist/core/extensions/builtin/nested-agents-md/core/types.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/index.d.ts +3 -0
- package/dist/core/extensions/builtin/nested-agents-md/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/index.js +102 -0
- package/dist/core/extensions/builtin/nested-agents-md/index.js.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.d.ts +32 -0
- package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.js +66 -0
- package/dist/core/extensions/builtin/nested-agents-md/ui/reporter.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/rules/commands.d.ts +4 -0
- package/dist/core/extensions/builtin/rules/commands.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/commands.js +87 -0
- package/dist/core/extensions/builtin/rules/commands.js.map +1 -0
- package/dist/core/extensions/builtin/rules/index.d.ts +3 -0
- package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/index.js +127 -0
- package/dist/core/extensions/builtin/rules/index.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/cache.d.ts +10 -0
- package/dist/core/extensions/builtin/rules/rules/cache.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/cache.js +51 -0
- package/dist/core/extensions/builtin/rules/rules/cache.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/constants.d.ts +57 -0
- package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/constants.js +96 -0
- package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/engine.d.ts +67 -0
- package/dist/core/extensions/builtin/rules/rules/engine.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/engine.js +443 -0
- package/dist/core/extensions/builtin/rules/rules/engine.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/errors.d.ts +7 -0
- package/dist/core/extensions/builtin/rules/rules/errors.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/errors.js +13 -0
- package/dist/core/extensions/builtin/rules/rules/errors.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/finder.d.ts +27 -0
- package/dist/core/extensions/builtin/rules/rules/finder.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/finder.js +241 -0
- package/dist/core/extensions/builtin/rules/rules/finder.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/formatter.d.ts +8 -0
- package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/formatter.js +44 -0
- package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/matcher.d.ts +25 -0
- package/dist/core/extensions/builtin/rules/rules/matcher.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/matcher.js +107 -0
- package/dist/core/extensions/builtin/rules/rules/matcher.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/ordering.d.ts +4 -0
- package/dist/core/extensions/builtin/rules/rules/ordering.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/ordering.js +28 -0
- package/dist/core/extensions/builtin/rules/rules/ordering.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/parser.d.ts +4 -0
- package/dist/core/extensions/builtin/rules/rules/parser.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/parser.js +290 -0
- package/dist/core/extensions/builtin/rules/rules/parser.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/project-root.d.ts +2 -0
- package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/project-root.js +24 -0
- package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/scanner.d.ts +14 -0
- package/dist/core/extensions/builtin/rules/rules/scanner.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/scanner.js +96 -0
- package/dist/core/extensions/builtin/rules/rules/scanner.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/tool-paths.d.ts +4 -0
- package/dist/core/extensions/builtin/rules/rules/tool-paths.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/tool-paths.js +37 -0
- package/dist/core/extensions/builtin/rules/rules/tool-paths.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/truncator.d.ts +18 -0
- package/dist/core/extensions/builtin/rules/rules/truncator.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/truncator.js +46 -0
- package/dist/core/extensions/builtin/rules/rules/truncator.js.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/types.d.ts +124 -0
- package/dist/core/extensions/builtin/rules/rules/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/rules/types.js +9 -0
- package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -0
- package/dist/core/extensions/builtin/rules/ui/dynamic-border.d.ts +8 -0
- package/dist/core/extensions/builtin/rules/ui/dynamic-border.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/ui/dynamic-border.js +10 -0
- package/dist/core/extensions/builtin/rules/ui/dynamic-border.js.map +1 -0
- package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts +22 -0
- package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rules/ui/rules-banner.js +51 -0
- package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/index.d.ts +10 -0
- package/dist/core/extensions/builtin/webfetch/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/index.js +53 -0
- package/dist/core/extensions/builtin/webfetch/index.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.d.ts +4 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.js +60 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/errors.d.ts +13 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/errors.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/errors.js +25 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/errors.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.d.ts +24 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.js +148 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/fetcher.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts +15 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js +110 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts +28 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +79 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/index.d.ts +3 -0
- package/dist/core/extensions/builtin/websearch/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/index.js +76 -0
- package/dist/core/extensions/builtin/websearch/index.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/config.d.ts +12 -0
- package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/config.js +245 -0
- package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +19 -0
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/native.js +65 -0
- package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts +5 -0
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +58 -0
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts +4 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers.js +464 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts +26 -0
- package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/renderers.js +66 -0
- package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +9 -0
- package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/search.js +261 -0
- package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts +18 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.js +88 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +115 -0
- package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/types.js +2 -0
- package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -0
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -4
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts +14 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +65 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +0 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +0 -4
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +87 -12
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +6 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/child-process.d.ts +7 -4
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +23 -5
- package/dist/utils/child-process.js.map +1 -1
- package/docs/containerization.md +36 -36
- package/docs/extensions.md +4 -4
- package/docs/index.md +1 -1
- package/docs/security.md +13 -13
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/question.ts +39 -18
- package/examples/extensions/questionnaire.ts +49 -28
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +5 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +140 -47
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +169 -122
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +4 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +18 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +20 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js +41 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +14 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/npm-shrinkwrap.json +45 -12
- package/package.json +8 -4
- package/dist/core/extensions/builtin/kimi-web-search/index.d.ts +0 -3
- package/dist/core/extensions/builtin/kimi-web-search/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/kimi-web-search/index.js +0 -208
- package/dist/core/extensions/builtin/kimi-web-search/index.js.map +0 -1
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join, posix, relative, resolve } from "node:path";
|
|
4
|
+
import { GLOBAL_DISTANCE, PROJECT_RULE_SUBDIRS, PROJECT_SINGLE_FILES, USER_HOME_RULE_SUBDIRS, USER_HOME_SINGLE_FILES, } from "./constants.js";
|
|
5
|
+
import { UnsupportedRuleSourceError } from "./errors.js";
|
|
6
|
+
import { scanRuleFiles } from "./scanner.js";
|
|
7
|
+
export function createRuleDiscoveryCache() {
|
|
8
|
+
return { scannedRuleFiles: new Map(), singleFileInfo: new Map() };
|
|
9
|
+
}
|
|
10
|
+
export function findRuleCandidates(options) {
|
|
11
|
+
const skipUserHome = options.skipUserHome ?? false;
|
|
12
|
+
if (options.projectRoot === null && skipUserHome) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const disabledSources = options.disabledSources ?? new Set();
|
|
16
|
+
const candidates = [];
|
|
17
|
+
const homeDirectory = resolve(options.homeDir ?? homedir());
|
|
18
|
+
if (options.projectRoot !== null) {
|
|
19
|
+
candidates.push(...findProjectCandidates(options.projectRoot, options.targetFile, disabledSources, options.cache));
|
|
20
|
+
}
|
|
21
|
+
if (!skipUserHome) {
|
|
22
|
+
candidates.push(...findUserHomeCandidates(homeDirectory, disabledSources, options.cache));
|
|
23
|
+
}
|
|
24
|
+
return candidates;
|
|
25
|
+
}
|
|
26
|
+
function findProjectCandidates(projectRoot, targetFile, disabledSources, cache) {
|
|
27
|
+
const rootDirectory = resolve(projectRoot);
|
|
28
|
+
const walkDirectories = getWalkDirectories(rootDirectory, targetFile);
|
|
29
|
+
const candidates = [];
|
|
30
|
+
for (const walkDirectory of walkDirectories) {
|
|
31
|
+
for (const [parentDirectory, subDirectory] of PROJECT_RULE_SUBDIRS) {
|
|
32
|
+
const source = toProjectRuleSource(parentDirectory, subDirectory);
|
|
33
|
+
if (disabledSources.has(source)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const ruleDirectory = join(walkDirectory.directory, parentDirectory, subDirectory);
|
|
37
|
+
for (const scannedFile of scanRuleFilesCached(ruleDirectory, cache)) {
|
|
38
|
+
candidates.push({
|
|
39
|
+
path: scannedFile.path,
|
|
40
|
+
realPath: resolveRealPath(scannedFile.path),
|
|
41
|
+
source,
|
|
42
|
+
distance: targetFile === null ? 0 : walkDirectory.distance,
|
|
43
|
+
isGlobal: false,
|
|
44
|
+
isSingleFile: false,
|
|
45
|
+
relativePath: toRelativePath(rootDirectory, scannedFile.path),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const walkDirectory of walkDirectories) {
|
|
51
|
+
for (const ruleFile of PROJECT_SINGLE_FILES) {
|
|
52
|
+
const source = toProjectSingleFileSource(ruleFile);
|
|
53
|
+
if (disabledSources.has(source)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const filePath = join(walkDirectory.directory, ruleFile);
|
|
57
|
+
const fileInfo = singleFileInfoCached(filePath, cache);
|
|
58
|
+
if (fileInfo === null) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
candidates.push({
|
|
62
|
+
path: fileInfo.path,
|
|
63
|
+
realPath: fileInfo.realPath,
|
|
64
|
+
source,
|
|
65
|
+
distance: targetFile === null ? 0 : walkDirectory.distance,
|
|
66
|
+
isGlobal: false,
|
|
67
|
+
isSingleFile: true,
|
|
68
|
+
relativePath: toRelativePath(rootDirectory, filePath),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return candidates;
|
|
73
|
+
}
|
|
74
|
+
function findUserHomeCandidates(homeDirectory, disabledSources, cache) {
|
|
75
|
+
const candidates = [];
|
|
76
|
+
for (const ruleSubdir of USER_HOME_RULE_SUBDIRS) {
|
|
77
|
+
const source = toUserHomeRuleSource(ruleSubdir);
|
|
78
|
+
if (disabledSources.has(source)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const ruleDirectory = join(homeDirectory, ruleSubdir);
|
|
82
|
+
for (const scannedFile of scanRuleFilesCached(ruleDirectory, cache)) {
|
|
83
|
+
candidates.push({
|
|
84
|
+
path: scannedFile.path,
|
|
85
|
+
realPath: resolveRealPath(scannedFile.path),
|
|
86
|
+
source,
|
|
87
|
+
distance: GLOBAL_DISTANCE,
|
|
88
|
+
isGlobal: true,
|
|
89
|
+
isSingleFile: false,
|
|
90
|
+
relativePath: toRelativePath(homeDirectory, scannedFile.path),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const ruleFile of USER_HOME_SINGLE_FILES) {
|
|
95
|
+
const source = toUserHomeSingleFileSource(ruleFile);
|
|
96
|
+
if (disabledSources.has(source)) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const filePath = join(homeDirectory, ruleFile);
|
|
100
|
+
const fileInfo = singleFileInfoCached(filePath, cache);
|
|
101
|
+
if (fileInfo === null) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
candidates.push({
|
|
105
|
+
path: fileInfo.path,
|
|
106
|
+
realPath: fileInfo.realPath,
|
|
107
|
+
source,
|
|
108
|
+
distance: GLOBAL_DISTANCE,
|
|
109
|
+
isGlobal: true,
|
|
110
|
+
isSingleFile: true,
|
|
111
|
+
relativePath: toRelativePath(homeDirectory, filePath),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return candidates;
|
|
115
|
+
}
|
|
116
|
+
function scanRuleFilesCached(rootDir, cache) {
|
|
117
|
+
if (cache === undefined) {
|
|
118
|
+
return scanRuleFiles({ rootDir });
|
|
119
|
+
}
|
|
120
|
+
const cached = cache.scannedRuleFiles.get(rootDir);
|
|
121
|
+
if (cached !== undefined) {
|
|
122
|
+
return cached;
|
|
123
|
+
}
|
|
124
|
+
const scannedFiles = scanRuleFiles({ rootDir });
|
|
125
|
+
cache.scannedRuleFiles.set(rootDir, scannedFiles);
|
|
126
|
+
return scannedFiles;
|
|
127
|
+
}
|
|
128
|
+
function singleFileInfoCached(filePath, cache) {
|
|
129
|
+
if (cache === undefined) {
|
|
130
|
+
return readSingleFileInfo(filePath);
|
|
131
|
+
}
|
|
132
|
+
const cached = cache.singleFileInfo.get(filePath);
|
|
133
|
+
if (cached !== undefined) {
|
|
134
|
+
return cached;
|
|
135
|
+
}
|
|
136
|
+
const fileInfo = readSingleFileInfo(filePath);
|
|
137
|
+
cache.singleFileInfo.set(filePath, fileInfo);
|
|
138
|
+
return fileInfo;
|
|
139
|
+
}
|
|
140
|
+
function getWalkDirectories(projectRoot, targetFile) {
|
|
141
|
+
if (targetFile === null) {
|
|
142
|
+
return [{ directory: projectRoot, distance: 0 }];
|
|
143
|
+
}
|
|
144
|
+
const startDirectory = dirname(resolve(targetFile));
|
|
145
|
+
if (!isSameOrChildPath(startDirectory, projectRoot)) {
|
|
146
|
+
return [{ directory: projectRoot, distance: 0 }];
|
|
147
|
+
}
|
|
148
|
+
const walkDirectories = [];
|
|
149
|
+
let currentDirectory = startDirectory;
|
|
150
|
+
let distance = 0;
|
|
151
|
+
while (true) {
|
|
152
|
+
walkDirectories.push({ directory: currentDirectory, distance });
|
|
153
|
+
if (currentDirectory === projectRoot) {
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
const parentDirectory = dirname(currentDirectory);
|
|
157
|
+
if (parentDirectory === currentDirectory) {
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
currentDirectory = parentDirectory;
|
|
161
|
+
distance += 1;
|
|
162
|
+
}
|
|
163
|
+
return walkDirectories;
|
|
164
|
+
}
|
|
165
|
+
function isSameOrChildPath(childPath, parentPath) {
|
|
166
|
+
const childRelativePath = relative(parentPath, childPath);
|
|
167
|
+
return childRelativePath === "" || (!childRelativePath.startsWith("..") && !childRelativePath.startsWith("/"));
|
|
168
|
+
}
|
|
169
|
+
function readSingleFileInfo(filePath) {
|
|
170
|
+
if (!existsSync(filePath)) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
if (!statSync(filePath).isFile()) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
path: filePath,
|
|
183
|
+
realPath: resolveRealPath(filePath),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function resolveRealPath(filePath) {
|
|
187
|
+
try {
|
|
188
|
+
return realpathSync.native(filePath);
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return filePath;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function toRelativePath(rootDirectory, filePath) {
|
|
195
|
+
return posix.normalize(relative(rootDirectory, filePath).replace(/\\/g, "/"));
|
|
196
|
+
}
|
|
197
|
+
function toProjectRuleSource(parentDirectory, subDirectory) {
|
|
198
|
+
const source = `${parentDirectory}/${subDirectory}`;
|
|
199
|
+
switch (source) {
|
|
200
|
+
case ".omo/rules":
|
|
201
|
+
case ".claude/rules":
|
|
202
|
+
case ".cursor/rules":
|
|
203
|
+
case ".github/instructions":
|
|
204
|
+
return source;
|
|
205
|
+
default:
|
|
206
|
+
throw new UnsupportedRuleSourceError(`Unsupported project rule source: ${source}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function toProjectSingleFileSource(ruleFile) {
|
|
210
|
+
switch (ruleFile) {
|
|
211
|
+
case ".github/copilot-instructions.md":
|
|
212
|
+
case "AGENTS.md":
|
|
213
|
+
case "CLAUDE.md":
|
|
214
|
+
case "CONTEXT.md":
|
|
215
|
+
return ruleFile;
|
|
216
|
+
default:
|
|
217
|
+
throw new UnsupportedRuleSourceError(`Unsupported project single-file source: ${ruleFile}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function toUserHomeRuleSource(ruleSubdir) {
|
|
221
|
+
const source = `~/${ruleSubdir}`;
|
|
222
|
+
switch (source) {
|
|
223
|
+
case "~/.omo/rules":
|
|
224
|
+
case "~/.opencode/rules":
|
|
225
|
+
case "~/.claude/rules":
|
|
226
|
+
return source;
|
|
227
|
+
default:
|
|
228
|
+
throw new UnsupportedRuleSourceError(`Unsupported user-home rule source: ${source}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function toUserHomeSingleFileSource(ruleFile) {
|
|
232
|
+
const source = `~/${ruleFile}`;
|
|
233
|
+
switch (source) {
|
|
234
|
+
case "~/.config/opencode/AGENTS.md":
|
|
235
|
+
case "~/.claude/CLAUDE.md":
|
|
236
|
+
return source;
|
|
237
|
+
default:
|
|
238
|
+
throw new UnsupportedRuleSourceError(`Unsupported user-home single-file source: ${source}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=finder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finder.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/finder.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, posix, relative, resolve } from \"node:path\";\n\nimport {\n\tGLOBAL_DISTANCE,\n\tPROJECT_RULE_SUBDIRS,\n\tPROJECT_SINGLE_FILES,\n\tUSER_HOME_RULE_SUBDIRS,\n\tUSER_HOME_SINGLE_FILES,\n} from \"./constants.ts\";\nimport { UnsupportedRuleSourceError } from \"./errors.ts\";\nimport { scanRuleFiles } from \"./scanner.ts\";\nimport type { RuleCandidate, RuleSource } from \"./types.ts\";\n\ninterface SingleFileInfo {\n\tpath: string;\n\trealPath: string;\n}\n\nexport interface RuleDiscoveryCache {\n\tscannedRuleFiles: Map<string, ReturnType<typeof scanRuleFiles>>;\n\tsingleFileInfo: Map<string, SingleFileInfo | null>;\n}\n\nexport interface FinderOptions {\n\t/** Project root absolute path (use findProjectRoot to get this). */\n\tprojectRoot: string | null;\n\t/** Target file path (used for distance calculation in dynamic injection mode). null for static mode. */\n\ttargetFile: string | null;\n\t/** User home directory (default: os.homedir()). Injectable for tests. */\n\thomeDir?: string;\n\t/** Set of disabled sources to omit from discovery. Empty by default. */\n\tdisabledSources?: ReadonlySet<string>;\n\t/** Whether to skip user-home rules. Default: false. */\n\tskipUserHome?: boolean;\n\tcache?: RuleDiscoveryCache;\n}\n\ninterface WalkDirectory {\n\tdirectory: string;\n\tdistance: number;\n}\n\nexport function createRuleDiscoveryCache(): RuleDiscoveryCache {\n\treturn { scannedRuleFiles: new Map(), singleFileInfo: new Map() };\n}\n\nexport function findRuleCandidates(options: FinderOptions): RuleCandidate[] {\n\tconst skipUserHome = options.skipUserHome ?? false;\n\tif (options.projectRoot === null && skipUserHome) {\n\t\treturn [];\n\t}\n\n\tconst disabledSources = options.disabledSources ?? new Set<string>();\n\tconst candidates: RuleCandidate[] = [];\n\tconst homeDirectory = resolve(options.homeDir ?? homedir());\n\n\tif (options.projectRoot !== null) {\n\t\tcandidates.push(\n\t\t\t...findProjectCandidates(options.projectRoot, options.targetFile, disabledSources, options.cache),\n\t\t);\n\t}\n\n\tif (!skipUserHome) {\n\t\tcandidates.push(...findUserHomeCandidates(homeDirectory, disabledSources, options.cache));\n\t}\n\n\treturn candidates;\n}\n\nfunction findProjectCandidates(\n\tprojectRoot: string,\n\ttargetFile: string | null,\n\tdisabledSources: ReadonlySet<string>,\n\tcache: RuleDiscoveryCache | undefined,\n): RuleCandidate[] {\n\tconst rootDirectory = resolve(projectRoot);\n\tconst walkDirectories = getWalkDirectories(rootDirectory, targetFile);\n\tconst candidates: RuleCandidate[] = [];\n\n\tfor (const walkDirectory of walkDirectories) {\n\t\tfor (const [parentDirectory, subDirectory] of PROJECT_RULE_SUBDIRS) {\n\t\t\tconst source = toProjectRuleSource(parentDirectory, subDirectory);\n\t\t\tif (disabledSources.has(source)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst ruleDirectory = join(walkDirectory.directory, parentDirectory, subDirectory);\n\t\t\tfor (const scannedFile of scanRuleFilesCached(ruleDirectory, cache)) {\n\t\t\t\tcandidates.push({\n\t\t\t\t\tpath: scannedFile.path,\n\t\t\t\t\trealPath: resolveRealPath(scannedFile.path),\n\t\t\t\t\tsource,\n\t\t\t\t\tdistance: targetFile === null ? 0 : walkDirectory.distance,\n\t\t\t\t\tisGlobal: false,\n\t\t\t\t\tisSingleFile: false,\n\t\t\t\t\trelativePath: toRelativePath(rootDirectory, scannedFile.path),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const walkDirectory of walkDirectories) {\n\t\tfor (const ruleFile of PROJECT_SINGLE_FILES) {\n\t\t\tconst source = toProjectSingleFileSource(ruleFile);\n\t\t\tif (disabledSources.has(source)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst filePath = join(walkDirectory.directory, ruleFile);\n\t\t\tconst fileInfo = singleFileInfoCached(filePath, cache);\n\t\t\tif (fileInfo === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcandidates.push({\n\t\t\t\tpath: fileInfo.path,\n\t\t\t\trealPath: fileInfo.realPath,\n\t\t\t\tsource,\n\t\t\t\tdistance: targetFile === null ? 0 : walkDirectory.distance,\n\t\t\t\tisGlobal: false,\n\t\t\t\tisSingleFile: true,\n\t\t\t\trelativePath: toRelativePath(rootDirectory, filePath),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn candidates;\n}\n\nfunction findUserHomeCandidates(\n\thomeDirectory: string,\n\tdisabledSources: ReadonlySet<string>,\n\tcache: RuleDiscoveryCache | undefined,\n): RuleCandidate[] {\n\tconst candidates: RuleCandidate[] = [];\n\n\tfor (const ruleSubdir of USER_HOME_RULE_SUBDIRS) {\n\t\tconst source = toUserHomeRuleSource(ruleSubdir);\n\t\tif (disabledSources.has(source)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst ruleDirectory = join(homeDirectory, ruleSubdir);\n\t\tfor (const scannedFile of scanRuleFilesCached(ruleDirectory, cache)) {\n\t\t\tcandidates.push({\n\t\t\t\tpath: scannedFile.path,\n\t\t\t\trealPath: resolveRealPath(scannedFile.path),\n\t\t\t\tsource,\n\t\t\t\tdistance: GLOBAL_DISTANCE,\n\t\t\t\tisGlobal: true,\n\t\t\t\tisSingleFile: false,\n\t\t\t\trelativePath: toRelativePath(homeDirectory, scannedFile.path),\n\t\t\t});\n\t\t}\n\t}\n\n\tfor (const ruleFile of USER_HOME_SINGLE_FILES) {\n\t\tconst source = toUserHomeSingleFileSource(ruleFile);\n\t\tif (disabledSources.has(source)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst filePath = join(homeDirectory, ruleFile);\n\t\tconst fileInfo = singleFileInfoCached(filePath, cache);\n\t\tif (fileInfo === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tcandidates.push({\n\t\t\tpath: fileInfo.path,\n\t\t\trealPath: fileInfo.realPath,\n\t\t\tsource,\n\t\t\tdistance: GLOBAL_DISTANCE,\n\t\t\tisGlobal: true,\n\t\t\tisSingleFile: true,\n\t\t\trelativePath: toRelativePath(homeDirectory, filePath),\n\t\t});\n\t}\n\n\treturn candidates;\n}\n\nfunction scanRuleFilesCached(rootDir: string, cache: RuleDiscoveryCache | undefined): ReturnType<typeof scanRuleFiles> {\n\tif (cache === undefined) {\n\t\treturn scanRuleFiles({ rootDir });\n\t}\n\n\tconst cached = cache.scannedRuleFiles.get(rootDir);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst scannedFiles = scanRuleFiles({ rootDir });\n\tcache.scannedRuleFiles.set(rootDir, scannedFiles);\n\treturn scannedFiles;\n}\n\nfunction singleFileInfoCached(filePath: string, cache: RuleDiscoveryCache | undefined): SingleFileInfo | null {\n\tif (cache === undefined) {\n\t\treturn readSingleFileInfo(filePath);\n\t}\n\n\tconst cached = cache.singleFileInfo.get(filePath);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst fileInfo = readSingleFileInfo(filePath);\n\tcache.singleFileInfo.set(filePath, fileInfo);\n\treturn fileInfo;\n}\n\nfunction getWalkDirectories(projectRoot: string, targetFile: string | null): WalkDirectory[] {\n\tif (targetFile === null) {\n\t\treturn [{ directory: projectRoot, distance: 0 }];\n\t}\n\n\tconst startDirectory = dirname(resolve(targetFile));\n\tif (!isSameOrChildPath(startDirectory, projectRoot)) {\n\t\treturn [{ directory: projectRoot, distance: 0 }];\n\t}\n\n\tconst walkDirectories: WalkDirectory[] = [];\n\tlet currentDirectory = startDirectory;\n\tlet distance = 0;\n\n\twhile (true) {\n\t\twalkDirectories.push({ directory: currentDirectory, distance });\n\t\tif (currentDirectory === projectRoot) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst parentDirectory = dirname(currentDirectory);\n\t\tif (parentDirectory === currentDirectory) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurrentDirectory = parentDirectory;\n\t\tdistance += 1;\n\t}\n\n\treturn walkDirectories;\n}\n\nfunction isSameOrChildPath(childPath: string, parentPath: string): boolean {\n\tconst childRelativePath = relative(parentPath, childPath);\n\treturn childRelativePath === \"\" || (!childRelativePath.startsWith(\"..\") && !childRelativePath.startsWith(\"/\"));\n}\n\nfunction readSingleFileInfo(filePath: string): SingleFileInfo | null {\n\tif (!existsSync(filePath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tif (!statSync(filePath).isFile()) {\n\t\t\treturn null;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tpath: filePath,\n\t\trealPath: resolveRealPath(filePath),\n\t};\n}\n\nfunction resolveRealPath(filePath: string): string {\n\ttry {\n\t\treturn realpathSync.native(filePath);\n\t} catch {\n\t\treturn filePath;\n\t}\n}\n\nfunction toRelativePath(rootDirectory: string, filePath: string): string {\n\treturn posix.normalize(relative(rootDirectory, filePath).replace(/\\\\/g, \"/\"));\n}\n\nfunction toProjectRuleSource(parentDirectory: string, subDirectory: string): RuleSource {\n\tconst source = `${parentDirectory}/${subDirectory}`;\n\tswitch (source) {\n\t\tcase \".omo/rules\":\n\t\tcase \".claude/rules\":\n\t\tcase \".cursor/rules\":\n\t\tcase \".github/instructions\":\n\t\t\treturn source;\n\t\tdefault:\n\t\t\tthrow new UnsupportedRuleSourceError(`Unsupported project rule source: ${source}`);\n\t}\n}\n\nfunction toProjectSingleFileSource(ruleFile: string): RuleSource {\n\tswitch (ruleFile) {\n\t\tcase \".github/copilot-instructions.md\":\n\t\tcase \"AGENTS.md\":\n\t\tcase \"CLAUDE.md\":\n\t\tcase \"CONTEXT.md\":\n\t\t\treturn ruleFile;\n\t\tdefault:\n\t\t\tthrow new UnsupportedRuleSourceError(`Unsupported project single-file source: ${ruleFile}`);\n\t}\n}\n\nfunction toUserHomeRuleSource(ruleSubdir: string): RuleSource {\n\tconst source = `~/${ruleSubdir}`;\n\tswitch (source) {\n\t\tcase \"~/.omo/rules\":\n\t\tcase \"~/.opencode/rules\":\n\t\tcase \"~/.claude/rules\":\n\t\t\treturn source;\n\t\tdefault:\n\t\t\tthrow new UnsupportedRuleSourceError(`Unsupported user-home rule source: ${source}`);\n\t}\n}\n\nfunction toUserHomeSingleFileSource(ruleFile: string): RuleSource {\n\tconst source = `~/${ruleFile}`;\n\tswitch (source) {\n\t\tcase \"~/.config/opencode/AGENTS.md\":\n\t\tcase \"~/.claude/CLAUDE.md\":\n\t\t\treturn source;\n\t\tdefault:\n\t\t\tthrow new UnsupportedRuleSourceError(`Unsupported user-home single-file source: ${source}`);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LoadedRule } from "./types.ts";
|
|
2
|
+
export interface FormatOptions {
|
|
3
|
+
maxRuleChars: number;
|
|
4
|
+
maxResultChars: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function formatStaticBlock(rules: ReadonlyArray<LoadedRule>, options: FormatOptions): string;
|
|
7
|
+
export declare function formatDynamicBlock(rules: ReadonlyArray<LoadedRule>, targetRelativePath: string, options: FormatOptions): string;
|
|
8
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACvB;AAyCD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAMlG;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,EAChC,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,aAAa,GACpB,MAAM,CAQR"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { truncateBudget, truncateRule } from "./truncator.js";
|
|
2
|
+
function formatRule(rule) {
|
|
3
|
+
return `Instructions from: ${rule.path}\n${rule.body}`;
|
|
4
|
+
}
|
|
5
|
+
function truncateRules(rules, options) {
|
|
6
|
+
const perRuleTruncated = rules.map((rule) => ({
|
|
7
|
+
path: rule.path,
|
|
8
|
+
relativePath: rule.relativePath,
|
|
9
|
+
body: truncateRule(rule.body, { maxChars: options.maxRuleChars, relativePath: rule.relativePath }).body,
|
|
10
|
+
}));
|
|
11
|
+
const budgetedRules = truncateBudget({
|
|
12
|
+
rules: perRuleTruncated.map((rule) => ({ body: rule.body, relativePath: rule.relativePath })),
|
|
13
|
+
maxResultChars: options.maxResultChars,
|
|
14
|
+
});
|
|
15
|
+
const truncatedRules = [];
|
|
16
|
+
for (let index = 0; index < budgetedRules.length; index += 1) {
|
|
17
|
+
const sourceRule = perRuleTruncated[index];
|
|
18
|
+
const budgetedRule = budgetedRules[index];
|
|
19
|
+
if (sourceRule === undefined || budgetedRule === undefined) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
truncatedRules.push({
|
|
23
|
+
path: sourceRule.path,
|
|
24
|
+
relativePath: budgetedRule.relativePath,
|
|
25
|
+
body: budgetedRule.body,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return truncatedRules;
|
|
29
|
+
}
|
|
30
|
+
export function formatStaticBlock(rules, options) {
|
|
31
|
+
if (rules.length === 0) {
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
return `\n\n## Project Instructions\n${truncateRules(rules, options).map(formatRule).join("\n\n")}`;
|
|
35
|
+
}
|
|
36
|
+
export function formatDynamicBlock(rules, targetRelativePath, options) {
|
|
37
|
+
if (rules.length === 0) {
|
|
38
|
+
return "";
|
|
39
|
+
}
|
|
40
|
+
return `\n\nAdditional project instructions matched for ${targetRelativePath}:\n\n${truncateRules(rules, options)
|
|
41
|
+
.map(formatRule)
|
|
42
|
+
.join("\n\n")}`;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAc9D,SAAS,UAAU,CAAC,IAAmB;IACtC,OAAO,sBAAsB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,aAAa,CAAC,KAAgC,EAAE,OAAsB;IAC9E,MAAM,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI;KACvG,CAAC,CAAC,CAAC;IACJ,MAAM,aAAa,GAAG,cAAc,CAAC;QACpC,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC7F,cAAc,EAAE,OAAO,CAAC,cAAc;KACtC,CAAC,CAAC;IACH,MAAM,cAAc,GAAoB,EAAE,CAAC;IAE3C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9D,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,UAAU,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC5D,SAAS;QACV,CAAC;QAED,cAAc,CAAC,IAAI,CAAC;YACnB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,YAAY,EAAE,YAAY,CAAC,YAAY;YACvC,IAAI,EAAE,YAAY,CAAC,IAAI;SACvB,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,cAAc,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgC,EAAE,OAAsB;IACzF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,gCAAgC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,kBAAkB,CACjC,KAAgC,EAChC,kBAA0B,EAC1B,OAAsB;IAEtB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,mDAAmD,kBAAkB,QAAQ,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC;SAC/G,GAAG,CAAC,UAAU,CAAC;SACf,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import { truncateBudget, truncateRule } from \"./truncator.ts\";\nimport type { LoadedRule } from \"./types.ts\";\n\nexport interface FormatOptions {\n\tmaxRuleChars: number;\n\tmaxResultChars: number;\n}\n\ntype TruncatedRule = {\n\tpath: string;\n\trelativePath: string;\n\tbody: string;\n};\n\nfunction formatRule(rule: TruncatedRule): string {\n\treturn `Instructions from: ${rule.path}\\n${rule.body}`;\n}\n\nfunction truncateRules(rules: ReadonlyArray<LoadedRule>, options: FormatOptions): TruncatedRule[] {\n\tconst perRuleTruncated = rules.map((rule) => ({\n\t\tpath: rule.path,\n\t\trelativePath: rule.relativePath,\n\t\tbody: truncateRule(rule.body, { maxChars: options.maxRuleChars, relativePath: rule.relativePath }).body,\n\t}));\n\tconst budgetedRules = truncateBudget({\n\t\trules: perRuleTruncated.map((rule) => ({ body: rule.body, relativePath: rule.relativePath })),\n\t\tmaxResultChars: options.maxResultChars,\n\t});\n\tconst truncatedRules: TruncatedRule[] = [];\n\n\tfor (let index = 0; index < budgetedRules.length; index += 1) {\n\t\tconst sourceRule = perRuleTruncated[index];\n\t\tconst budgetedRule = budgetedRules[index];\n\t\tif (sourceRule === undefined || budgetedRule === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttruncatedRules.push({\n\t\t\tpath: sourceRule.path,\n\t\t\trelativePath: budgetedRule.relativePath,\n\t\t\tbody: budgetedRule.body,\n\t\t});\n\t}\n\n\treturn truncatedRules;\n}\n\nexport function formatStaticBlock(rules: ReadonlyArray<LoadedRule>, options: FormatOptions): string {\n\tif (rules.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn `\\n\\n## Project Instructions\\n${truncateRules(rules, options).map(formatRule).join(\"\\n\\n\")}`;\n}\n\nexport function formatDynamicBlock(\n\trules: ReadonlyArray<LoadedRule>,\n\ttargetRelativePath: string,\n\toptions: FormatOptions,\n): string {\n\tif (rules.length === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn `\\n\\nAdditional project instructions matched for ${targetRelativePath}:\\n\\n${truncateRules(rules, options)\n\t\t.map(formatRule)\n\t\t.join(\"\\n\\n\")}`;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MatchReason, RuleFrontmatter } from "./types.ts";
|
|
2
|
+
export interface MatcherInput {
|
|
3
|
+
frontmatter: RuleFrontmatter;
|
|
4
|
+
isSingleFile: boolean;
|
|
5
|
+
/** Path bases to try matching against (POSIX-normalized). */
|
|
6
|
+
pathBases: {
|
|
7
|
+
projectRelative: string;
|
|
8
|
+
scopeRelative?: string;
|
|
9
|
+
basename: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface MatchResult {
|
|
13
|
+
matched: boolean;
|
|
14
|
+
reason: MatchReason;
|
|
15
|
+
}
|
|
16
|
+
export interface MatcherCacheStats {
|
|
17
|
+
entries: number;
|
|
18
|
+
compiledPatterns: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function matchRule(input: MatcherInput): MatchResult;
|
|
21
|
+
export declare function normalizeGlobs(frontmatter: RuleFrontmatter): string[];
|
|
22
|
+
export declare function hashContent(body: string): string;
|
|
23
|
+
export declare function resetMatcherCache(): void;
|
|
24
|
+
export declare function getMatcherCacheStats(): MatcherCacheStats;
|
|
25
|
+
//# sourceMappingURL=matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/matcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,eAAe,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,SAAS,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACjF;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACpB;AAOD,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAQD,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAqC1D;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM,EAAE,CAQrE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,wBAAgB,oBAAoB,IAAI,iBAAiB,CAOxD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import picomatch from "picomatch";
|
|
3
|
+
const PICOMATCH_OPTIONS = { bash: true, dot: true };
|
|
4
|
+
const MAX_COMPILED_PATTERN_SET_CACHE_ENTRIES = 256;
|
|
5
|
+
const compiledPatternSets = new Map();
|
|
6
|
+
export function matchRule(input) {
|
|
7
|
+
if (input.isSingleFile) {
|
|
8
|
+
return { matched: true, reason: "single-file" };
|
|
9
|
+
}
|
|
10
|
+
if (input.frontmatter.alwaysApply === true) {
|
|
11
|
+
return { matched: true, reason: "alwaysApply" };
|
|
12
|
+
}
|
|
13
|
+
const patterns = normalizeGlobs(input.frontmatter);
|
|
14
|
+
if (patterns.length === 0) {
|
|
15
|
+
return noMatch();
|
|
16
|
+
}
|
|
17
|
+
const pathBases = [
|
|
18
|
+
normalizePath(input.pathBases.projectRelative),
|
|
19
|
+
input.pathBases.scopeRelative ? normalizePath(input.pathBases.scopeRelative) : undefined,
|
|
20
|
+
normalizePath(input.pathBases.basename),
|
|
21
|
+
].filter((pathBase) => pathBase !== undefined);
|
|
22
|
+
const { positiveMatchers, negativeMatchers } = compiledPatternSetFor(patterns);
|
|
23
|
+
for (const { pattern, isMatch } of positiveMatchers) {
|
|
24
|
+
for (const pathBase of pathBases) {
|
|
25
|
+
if (!isMatch(pathBase)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (isExcluded(pathBase, negativeMatchers)) {
|
|
29
|
+
return noMatch();
|
|
30
|
+
}
|
|
31
|
+
return { matched: true, reason: { kind: "glob", pattern } };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return noMatch();
|
|
35
|
+
}
|
|
36
|
+
export function normalizeGlobs(frontmatter) {
|
|
37
|
+
const patterns = [
|
|
38
|
+
...normalizePatternList(frontmatter.globs),
|
|
39
|
+
...normalizePatternList(frontmatter.paths),
|
|
40
|
+
...normalizePatternList(frontmatter.applyTo),
|
|
41
|
+
];
|
|
42
|
+
return [...new Set(patterns.map(normalizePath))];
|
|
43
|
+
}
|
|
44
|
+
export function hashContent(body) {
|
|
45
|
+
return createHash("sha256").update(body).digest("hex");
|
|
46
|
+
}
|
|
47
|
+
export function resetMatcherCache() {
|
|
48
|
+
compiledPatternSets.clear();
|
|
49
|
+
}
|
|
50
|
+
export function getMatcherCacheStats() {
|
|
51
|
+
let compiledPatterns = 0;
|
|
52
|
+
for (const patternSet of compiledPatternSets.values()) {
|
|
53
|
+
compiledPatterns += patternSet.positiveMatchers.length + patternSet.negativeMatchers.length;
|
|
54
|
+
}
|
|
55
|
+
return { entries: compiledPatternSets.size, compiledPatterns };
|
|
56
|
+
}
|
|
57
|
+
function compiledPatternSetFor(patterns) {
|
|
58
|
+
const cacheKey = patterns.join("\0");
|
|
59
|
+
const cached = compiledPatternSets.get(cacheKey);
|
|
60
|
+
if (cached !== undefined) {
|
|
61
|
+
compiledPatternSets.delete(cacheKey);
|
|
62
|
+
compiledPatternSets.set(cacheKey, cached);
|
|
63
|
+
return cached;
|
|
64
|
+
}
|
|
65
|
+
const positiveMatchers = [];
|
|
66
|
+
const negativeMatchers = [];
|
|
67
|
+
for (const pattern of patterns) {
|
|
68
|
+
if (pattern.startsWith("!")) {
|
|
69
|
+
negativeMatchers.push(picomatch(pattern.slice(1), PICOMATCH_OPTIONS));
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
positiveMatchers.push({ pattern, isMatch: picomatch(pattern, PICOMATCH_OPTIONS) });
|
|
73
|
+
}
|
|
74
|
+
const compiledPatternSet = { positiveMatchers, negativeMatchers };
|
|
75
|
+
setCompiledPatternSet(cacheKey, compiledPatternSet);
|
|
76
|
+
return compiledPatternSet;
|
|
77
|
+
}
|
|
78
|
+
function setCompiledPatternSet(cacheKey, compiledPatternSet) {
|
|
79
|
+
if (compiledPatternSets.size >= MAX_COMPILED_PATTERN_SET_CACHE_ENTRIES) {
|
|
80
|
+
const oldestCacheKey = compiledPatternSets.keys().next().value;
|
|
81
|
+
if (oldestCacheKey !== undefined) {
|
|
82
|
+
compiledPatternSets.delete(oldestCacheKey);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
compiledPatternSets.set(cacheKey, compiledPatternSet);
|
|
86
|
+
}
|
|
87
|
+
function normalizePatternList(patterns) {
|
|
88
|
+
if (patterns === undefined) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return Array.isArray(patterns) ? patterns : [patterns];
|
|
92
|
+
}
|
|
93
|
+
function normalizePath(path) {
|
|
94
|
+
return path.replaceAll("\\", "/");
|
|
95
|
+
}
|
|
96
|
+
function isExcluded(pathBase, negativeMatchers) {
|
|
97
|
+
for (const isMatch of negativeMatchers) {
|
|
98
|
+
if (isMatch(pathBase)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
function noMatch() {
|
|
105
|
+
return { matched: false, reason: { kind: "no-match" } };
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/matcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport picomatch from \"picomatch\";\nimport type { MatchReason, RuleFrontmatter } from \"./types.ts\";\n\nexport interface MatcherInput {\n\tfrontmatter: RuleFrontmatter;\n\tisSingleFile: boolean;\n\t/** Path bases to try matching against (POSIX-normalized). */\n\tpathBases: { projectRelative: string; scopeRelative?: string; basename: string };\n}\n\nexport interface MatchResult {\n\tmatched: boolean;\n\treason: MatchReason;\n}\n\ninterface CompiledPatternSet {\n\tpositiveMatchers: ReadonlyArray<{ pattern: string; isMatch: PathMatcher }>;\n\tnegativeMatchers: ReadonlyArray<PathMatcher>;\n}\n\nexport interface MatcherCacheStats {\n\tentries: number;\n\tcompiledPatterns: number;\n}\n\ntype PathMatcher = (path: string) => boolean;\n\nconst PICOMATCH_OPTIONS = { bash: true, dot: true };\nconst MAX_COMPILED_PATTERN_SET_CACHE_ENTRIES = 256;\nconst compiledPatternSets = new Map<string, CompiledPatternSet>();\n\nexport function matchRule(input: MatcherInput): MatchResult {\n\tif (input.isSingleFile) {\n\t\treturn { matched: true, reason: \"single-file\" };\n\t}\n\n\tif (input.frontmatter.alwaysApply === true) {\n\t\treturn { matched: true, reason: \"alwaysApply\" };\n\t}\n\n\tconst patterns = normalizeGlobs(input.frontmatter);\n\tif (patterns.length === 0) {\n\t\treturn noMatch();\n\t}\n\n\tconst pathBases = [\n\t\tnormalizePath(input.pathBases.projectRelative),\n\t\tinput.pathBases.scopeRelative ? normalizePath(input.pathBases.scopeRelative) : undefined,\n\t\tnormalizePath(input.pathBases.basename),\n\t].filter((pathBase): pathBase is string => pathBase !== undefined);\n\n\tconst { positiveMatchers, negativeMatchers } = compiledPatternSetFor(patterns);\n\n\tfor (const { pattern, isMatch } of positiveMatchers) {\n\t\tfor (const pathBase of pathBases) {\n\t\t\tif (!isMatch(pathBase)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isExcluded(pathBase, negativeMatchers)) {\n\t\t\t\treturn noMatch();\n\t\t\t}\n\n\t\t\treturn { matched: true, reason: { kind: \"glob\", pattern } };\n\t\t}\n\t}\n\n\treturn noMatch();\n}\n\nexport function normalizeGlobs(frontmatter: RuleFrontmatter): string[] {\n\tconst patterns = [\n\t\t...normalizePatternList(frontmatter.globs),\n\t\t...normalizePatternList(frontmatter.paths),\n\t\t...normalizePatternList(frontmatter.applyTo),\n\t];\n\n\treturn [...new Set(patterns.map(normalizePath))];\n}\n\nexport function hashContent(body: string): string {\n\treturn createHash(\"sha256\").update(body).digest(\"hex\");\n}\n\nexport function resetMatcherCache(): void {\n\tcompiledPatternSets.clear();\n}\n\nexport function getMatcherCacheStats(): MatcherCacheStats {\n\tlet compiledPatterns = 0;\n\tfor (const patternSet of compiledPatternSets.values()) {\n\t\tcompiledPatterns += patternSet.positiveMatchers.length + patternSet.negativeMatchers.length;\n\t}\n\n\treturn { entries: compiledPatternSets.size, compiledPatterns };\n}\n\nfunction compiledPatternSetFor(patterns: ReadonlyArray<string>): CompiledPatternSet {\n\tconst cacheKey = patterns.join(\"\\0\");\n\tconst cached = compiledPatternSets.get(cacheKey);\n\tif (cached !== undefined) {\n\t\tcompiledPatternSets.delete(cacheKey);\n\t\tcompiledPatternSets.set(cacheKey, cached);\n\t\treturn cached;\n\t}\n\n\tconst positiveMatchers: Array<{ pattern: string; isMatch: PathMatcher }> = [];\n\tconst negativeMatchers: PathMatcher[] = [];\n\tfor (const pattern of patterns) {\n\t\tif (pattern.startsWith(\"!\")) {\n\t\t\tnegativeMatchers.push(picomatch(pattern.slice(1), PICOMATCH_OPTIONS));\n\t\t\tcontinue;\n\t\t}\n\n\t\tpositiveMatchers.push({ pattern, isMatch: picomatch(pattern, PICOMATCH_OPTIONS) });\n\t}\n\n\tconst compiledPatternSet = { positiveMatchers, negativeMatchers } satisfies CompiledPatternSet;\n\tsetCompiledPatternSet(cacheKey, compiledPatternSet);\n\treturn compiledPatternSet;\n}\n\nfunction setCompiledPatternSet(cacheKey: string, compiledPatternSet: CompiledPatternSet): void {\n\tif (compiledPatternSets.size >= MAX_COMPILED_PATTERN_SET_CACHE_ENTRIES) {\n\t\tconst oldestCacheKey = compiledPatternSets.keys().next().value;\n\t\tif (oldestCacheKey !== undefined) {\n\t\t\tcompiledPatternSets.delete(oldestCacheKey);\n\t\t}\n\t}\n\tcompiledPatternSets.set(cacheKey, compiledPatternSet);\n}\n\nfunction normalizePatternList(patterns: string | string[] | undefined): string[] {\n\tif (patterns === undefined) {\n\t\treturn [];\n\t}\n\n\treturn Array.isArray(patterns) ? patterns : [patterns];\n}\n\nfunction normalizePath(path: string): string {\n\treturn path.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction isExcluded(pathBase: string, negativeMatchers: ReadonlyArray<(path: string) => boolean>): boolean {\n\tfor (const isMatch of negativeMatchers) {\n\t\tif (isMatch(pathBase)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction noMatch(): MatchResult {\n\treturn { matched: false, reason: { kind: \"no-match\" } };\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RuleCandidate } from "./types.ts";
|
|
2
|
+
export declare function sortCandidates<T extends RuleCandidate>(candidates: ReadonlyArray<T>): T[];
|
|
3
|
+
export declare function compareCandidates(a: RuleCandidate, b: RuleCandidate): number;
|
|
4
|
+
//# sourceMappingURL=ordering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ordering.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/ordering.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAKzF;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,MAAM,CAQ5E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SOURCE_PRIORITY } from "./constants.js";
|
|
2
|
+
export function sortCandidates(candidates) {
|
|
3
|
+
return candidates
|
|
4
|
+
.map((candidate, index) => ({ candidate, index }))
|
|
5
|
+
.sort((left, right) => compareCandidates(left.candidate, right.candidate) || left.index - right.index)
|
|
6
|
+
.map(({ candidate }) => candidate);
|
|
7
|
+
}
|
|
8
|
+
export function compareCandidates(a, b) {
|
|
9
|
+
return (compareBoolean(a.isGlobal, b.isGlobal) ||
|
|
10
|
+
compareNumber(a.distance, b.distance) ||
|
|
11
|
+
compareNumber(SOURCE_PRIORITY.get(a.source) ?? Infinity, SOURCE_PRIORITY.get(b.source) ?? Infinity) ||
|
|
12
|
+
compareString(a.relativePath, b.relativePath) ||
|
|
13
|
+
compareString(a.realPath, b.realPath));
|
|
14
|
+
}
|
|
15
|
+
function compareBoolean(a, b) {
|
|
16
|
+
return Number(a) - Number(b);
|
|
17
|
+
}
|
|
18
|
+
function compareNumber(a, b) {
|
|
19
|
+
return a - b;
|
|
20
|
+
}
|
|
21
|
+
function compareString(a, b) {
|
|
22
|
+
if (a < b)
|
|
23
|
+
return -1;
|
|
24
|
+
if (a > b)
|
|
25
|
+
return 1;
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ordering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ordering.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/ordering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,UAAU,cAAc,CAA0B,UAA4B;IACnF,OAAO,UAAU;SACf,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;SACjD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;SACrG,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAgB,EAAE,CAAgB;IACnE,OAAO,CACN,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;QACtC,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;QACrC,aAAa,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC;QACnG,aAAa,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC;QAC7C,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CACrC,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,CAAU,EAAE,CAAU;IAC7C,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CAAC,CAAS,EAAE,CAAS;IAC1C,OAAO,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,CAAS,EAAE,CAAS;IAC1C,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,CAAC,CAAC;AACV,CAAC","sourcesContent":["import { SOURCE_PRIORITY } from \"./constants.ts\";\nimport type { RuleCandidate } from \"./types.ts\";\n\nexport function sortCandidates<T extends RuleCandidate>(candidates: ReadonlyArray<T>): T[] {\n\treturn candidates\n\t\t.map((candidate, index) => ({ candidate, index }))\n\t\t.sort((left, right) => compareCandidates(left.candidate, right.candidate) || left.index - right.index)\n\t\t.map(({ candidate }) => candidate);\n}\n\nexport function compareCandidates(a: RuleCandidate, b: RuleCandidate): number {\n\treturn (\n\t\tcompareBoolean(a.isGlobal, b.isGlobal) ||\n\t\tcompareNumber(a.distance, b.distance) ||\n\t\tcompareNumber(SOURCE_PRIORITY.get(a.source) ?? Infinity, SOURCE_PRIORITY.get(b.source) ?? Infinity) ||\n\t\tcompareString(a.relativePath, b.relativePath) ||\n\t\tcompareString(a.realPath, b.realPath)\n\t);\n}\n\nfunction compareBoolean(a: boolean, b: boolean): number {\n\treturn Number(a) - Number(b);\n}\n\nfunction compareNumber(a: number, b: number): number {\n\treturn a - b;\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/rules/rules/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AAK9D,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CA6BrD"}
|