@dev-sergeev/datalab-kit 0.1.2 → 0.1.3
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 +6 -0
- package/README.md +23 -5
- package/THIRD_PARTY_NOTICES.md +6 -2
- package/dist/extension.js +8 -1
- package/dist/recap.d.ts +2 -0
- package/dist/recap.js +31 -0
- package/docs/adr/0002-package-delivery.md +2 -0
- package/node_modules/@pi-plugins/elapsed/LICENSE +21 -0
- package/node_modules/@pi-plugins/elapsed/README.md +45 -0
- package/node_modules/@pi-plugins/elapsed/dist/index.d.mts +8 -0
- package/node_modules/@pi-plugins/elapsed/dist/index.d.mts.map +1 -0
- package/node_modules/@pi-plugins/elapsed/dist/index.mjs +47 -0
- package/node_modules/@pi-plugins/elapsed/dist/index.mjs.map +1 -0
- package/node_modules/@pi-plugins/elapsed/package.json +65 -0
- package/node_modules/@tifan/pi-recap/README.md +61 -0
- package/node_modules/@tifan/pi-recap/package.json +43 -0
- package/node_modules/@tifan/pi-recap/src/index.ts +584 -0
- package/node_modules/@tifan/pi-recap/src/model-picker.ts +233 -0
- package/node_modules/@tifan/pi-recap/src/models.ts +183 -0
- package/node_modules/@tifan/pi-recap/src/sanitize.ts +119 -0
- package/node_modules/@tifan/pi-recap/src/tui.ts +155 -0
- package/node_modules/@zigai/pi-extension-internals/README.md +24 -0
- package/node_modules/@zigai/pi-extension-internals/dist/editor-enhancer-registry.d.ts +21 -0
- package/node_modules/@zigai/pi-extension-internals/dist/editor-enhancer-registry.js +233 -0
- package/node_modules/@zigai/pi-extension-internals/dist/index.d.ts +6 -0
- package/node_modules/@zigai/pi-extension-internals/dist/index.js +3 -0
- package/node_modules/@zigai/pi-extension-internals/dist/linked-method-patch.d.ts +34 -0
- package/node_modules/@zigai/pi-extension-internals/dist/linked-method-patch.js +272 -0
- package/node_modules/@zigai/pi-extension-internals/dist/pi-internal-import.d.ts +11 -0
- package/node_modules/@zigai/pi-extension-internals/dist/pi-internal-import.js +139 -0
- package/node_modules/@zigai/pi-extension-internals/package.json +41 -0
- package/node_modules/@zigai/pi-extension-settings/LICENSE +21 -0
- package/node_modules/@zigai/pi-extension-settings/README.md +36 -0
- package/node_modules/@zigai/pi-extension-settings/dist/artifacts.d.ts +23 -0
- package/node_modules/@zigai/pi-extension-settings/dist/artifacts.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/artifacts.js +75 -0
- package/node_modules/@zigai/pi-extension-settings/dist/artifacts.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.d.ts +3 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.js +5 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli.d.ts +6 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli.js +87 -0
- package/node_modules/@zigai/pi-extension-settings/dist/cli.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.d.ts +2 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.js +2 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition.d.ts +159 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition.js +248 -0
- package/node_modules/@zigai/pi-extension-settings/dist/definition.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/file-system.d.ts +10 -0
- package/node_modules/@zigai/pi-extension-settings/dist/file-system.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/file-system.js +115 -0
- package/node_modules/@zigai/pi-extension-settings/dist/file-system.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/index.d.ts +2 -0
- package/node_modules/@zigai/pi-extension-settings/dist/index.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/index.js +2 -0
- package/node_modules/@zigai/pi-extension-settings/dist/index.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/json-value.d.ts +18 -0
- package/node_modules/@zigai/pi-extension-settings/dist/json-value.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/json-value.js +56 -0
- package/node_modules/@zigai/pi-extension-settings/dist/json-value.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/paths.d.ts +11 -0
- package/node_modules/@zigai/pi-extension-settings/dist/paths.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/paths.js +23 -0
- package/node_modules/@zigai/pi-extension-settings/dist/paths.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.d.ts +5 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.js +21 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.d.ts +106 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.js +122 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.ts +2537 -0
- package/node_modules/@zigai/pi-extension-settings/dist/pi.ts.map +7 -0
- package/node_modules/@zigai/pi-extension-settings/dist/projects.d.ts +10 -0
- package/node_modules/@zigai/pi-extension-settings/dist/projects.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/projects.js +177 -0
- package/node_modules/@zigai/pi-extension-settings/dist/projects.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.d.ts +40 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.js +158 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.ts +158 -0
- package/node_modules/@zigai/pi-extension-settings/dist/runtime.ts.map +7 -0
- package/node_modules/@zigai/pi-extension-settings/dist/schema-document.d.ts +19 -0
- package/node_modules/@zigai/pi-extension-settings/dist/schema-document.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/schema-document.js +168 -0
- package/node_modules/@zigai/pi-extension-settings/dist/schema-document.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.d.ts +9 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.js +242 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.d.ts +59 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.js +98 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.d.ts +80 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.js +144 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.d.ts +5 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.js +30 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.d.ts +10 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.js +16 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.d.ts +54 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.js +202 -0
- package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.d.ts +5 -0
- package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.d.ts.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.js +9 -0
- package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.js.map +1 -0
- package/node_modules/@zigai/pi-extension-settings/docs/generation.md +71 -0
- package/node_modules/@zigai/pi-extension-settings/docs/manual-setup.md +98 -0
- package/node_modules/@zigai/pi-extension-settings/docs/runtime.md +100 -0
- package/node_modules/@zigai/pi-extension-settings/docs/ui-controls.md +31 -0
- package/node_modules/@zigai/pi-extension-settings/package.json +97 -0
- package/node_modules/@zigai/pi-mention-anything/README.md +113 -0
- package/node_modules/@zigai/pi-mention-anything/config.schema.json +313 -0
- package/node_modules/@zigai/pi-mention-anything/docs/command-protocol.md +106 -0
- package/node_modules/@zigai/pi-mention-anything/docs/providers.md +128 -0
- package/node_modules/@zigai/pi-mention-anything/examples/query-command.mjs +96 -0
- package/node_modules/@zigai/pi-mention-anything/examples/recursive-tree.ts +28 -0
- package/node_modules/@zigai/pi-mention-anything/examples/static.ts +28 -0
- package/node_modules/@zigai/pi-mention-anything/examples/tmux.ts +90 -0
- package/node_modules/@zigai/pi-mention-anything/examples/tree-settings.json +25 -0
- package/node_modules/@zigai/pi-mention-anything/package.json +58 -0
- package/node_modules/@zigai/pi-mention-anything/src/api.ts +75 -0
- package/node_modules/@zigai/pi-mention-anything/src/autocomplete.ts +231 -0
- package/node_modules/@zigai/pi-mention-anything/src/chain-autocomplete.ts +596 -0
- package/node_modules/@zigai/pi-mention-anything/src/chain-syntax.ts +345 -0
- package/node_modules/@zigai/pi-mention-anything/src/command-provider.ts +291 -0
- package/node_modules/@zigai/pi-mention-anything/src/configured-source.ts +66 -0
- package/node_modules/@zigai/pi-mention-anything/src/editor.ts +180 -0
- package/node_modules/@zigai/pi-mention-anything/src/expand-mentions.ts +162 -0
- package/node_modules/@zigai/pi-mention-anything/src/index.ts +54 -0
- package/node_modules/@zigai/pi-mention-anything/src/initial-suggestions.ts +190 -0
- package/node_modules/@zigai/pi-mention-anything/src/list-provider.ts +71 -0
- package/node_modules/@zigai/pi-mention-anything/src/mention-hub.ts +307 -0
- package/node_modules/@zigai/pi-mention-anything/src/mention-resolution.ts +374 -0
- package/node_modules/@zigai/pi-mention-anything/src/mention-syntax.ts +105 -0
- package/node_modules/@zigai/pi-mention-anything/src/register-mention.ts +89 -0
- package/node_modules/@zigai/pi-mention-anything/src/rendering.ts +53 -0
- package/node_modules/@zigai/pi-mention-anything/src/selected-items.ts +21 -0
- package/node_modules/@zigai/pi-mention-anything/src/selection-history.ts +135 -0
- package/node_modules/@zigai/pi-mention-anything/src/settings-input.ts +317 -0
- package/node_modules/@zigai/pi-mention-anything/src/settings.prevalidated.ts +57 -0
- package/node_modules/@zigai/pi-mention-anything/src/settings.ts +52 -0
- package/node_modules/@zigai/pi-mention-anything/src/source-contract.ts +174 -0
- package/node_modules/@zigai/pi-mention-anything/src/source-controller.ts +1070 -0
- package/node_modules/@zigai/pi-mention-anything/src/source-runtime.ts +99 -0
- package/node_modules/@zigai/pi-mention-skill/README.md +60 -0
- package/node_modules/@zigai/pi-mention-skill/config.schema.json +81 -0
- package/node_modules/@zigai/pi-mention-skill/package.json +56 -0
- package/node_modules/@zigai/pi-mention-skill/src/index.ts +60 -0
- package/node_modules/@zigai/pi-mention-skill/src/settings-input.ts +74 -0
- package/node_modules/@zigai/pi-mention-skill/src/settings.prevalidated.ts +18 -0
- package/node_modules/@zigai/pi-mention-skill/src/settings.ts +54 -0
- package/node_modules/@zigai/pi-mention-skill/src/skill-commands.ts +18 -0
- package/node_modules/@zigai/pi-mention-skill/src/skill-content.ts +60 -0
- package/node_modules/@zigai/pi-mention-skill/src/skill-provider.ts +105 -0
- package/node_modules/@zigai/pi-mention-skill/src/slash-skill-filter.ts +29 -0
- package/node_modules/argparse/LICENSE +21 -0
- package/node_modules/argparse/README.md +257 -0
- package/node_modules/argparse/index.js +3 -0
- package/node_modules/argparse/lib/action/append/constant.js +47 -0
- package/node_modules/argparse/lib/action/append.js +53 -0
- package/node_modules/argparse/lib/action/count.js +40 -0
- package/node_modules/argparse/lib/action/help.js +47 -0
- package/node_modules/argparse/lib/action/store/constant.js +43 -0
- package/node_modules/argparse/lib/action/store/false.js +27 -0
- package/node_modules/argparse/lib/action/store/true.js +26 -0
- package/node_modules/argparse/lib/action/store.js +50 -0
- package/node_modules/argparse/lib/action/subparsers.js +149 -0
- package/node_modules/argparse/lib/action/version.js +47 -0
- package/node_modules/argparse/lib/action.js +146 -0
- package/node_modules/argparse/lib/action_container.js +482 -0
- package/node_modules/argparse/lib/argparse.js +14 -0
- package/node_modules/argparse/lib/argument/error.js +50 -0
- package/node_modules/argparse/lib/argument/exclusive.js +54 -0
- package/node_modules/argparse/lib/argument/group.js +75 -0
- package/node_modules/argparse/lib/argument_parser.js +1161 -0
- package/node_modules/argparse/lib/const.js +21 -0
- package/node_modules/argparse/lib/help/added_formatters.js +87 -0
- package/node_modules/argparse/lib/help/formatter.js +795 -0
- package/node_modules/argparse/lib/namespace.js +76 -0
- package/node_modules/argparse/lib/utils.js +57 -0
- package/node_modules/argparse/package.json +34 -0
- package/node_modules/esprima/LICENSE.BSD +21 -0
- package/node_modules/esprima/README.md +46 -0
- package/node_modules/esprima/bin/esparse.js +139 -0
- package/node_modules/esprima/bin/esvalidate.js +236 -0
- package/node_modules/esprima/dist/esprima.js +6709 -0
- package/node_modules/esprima/package.json +112 -0
- package/node_modules/extend-shallow/LICENSE +21 -0
- package/node_modules/extend-shallow/README.md +61 -0
- package/node_modules/extend-shallow/index.js +33 -0
- package/node_modules/extend-shallow/package.json +56 -0
- package/node_modules/graceful-fs/LICENSE +15 -0
- package/node_modules/graceful-fs/README.md +143 -0
- package/node_modules/graceful-fs/clone.js +23 -0
- package/node_modules/graceful-fs/graceful-fs.js +448 -0
- package/node_modules/graceful-fs/legacy-streams.js +118 -0
- package/node_modules/graceful-fs/package.json +53 -0
- package/node_modules/graceful-fs/polyfills.js +355 -0
- package/node_modules/gray-matter/LICENSE +21 -0
- package/node_modules/gray-matter/README.md +565 -0
- package/node_modules/gray-matter/gray-matter.d.ts +114 -0
- package/node_modules/gray-matter/index.js +228 -0
- package/node_modules/gray-matter/lib/defaults.js +18 -0
- package/node_modules/gray-matter/lib/engine.js +30 -0
- package/node_modules/gray-matter/lib/engines.js +54 -0
- package/node_modules/gray-matter/lib/excerpt.js +32 -0
- package/node_modules/gray-matter/lib/parse.js +13 -0
- package/node_modules/gray-matter/lib/stringify.js +56 -0
- package/node_modules/gray-matter/lib/to-file.js +43 -0
- package/node_modules/gray-matter/lib/utils.js +66 -0
- package/node_modules/gray-matter/package.json +127 -0
- package/node_modules/is-extendable/LICENSE +21 -0
- package/node_modules/is-extendable/README.md +72 -0
- package/node_modules/is-extendable/index.js +13 -0
- package/node_modules/is-extendable/package.json +51 -0
- package/node_modules/js-yaml/LICENSE +21 -0
- package/node_modules/js-yaml/README.md +302 -0
- package/node_modules/js-yaml/bin/js-yaml.js +132 -0
- package/node_modules/js-yaml/dist/js-yaml.js +4024 -0
- package/node_modules/js-yaml/dist/js-yaml.min.js +1 -0
- package/node_modules/js-yaml/index.js +7 -0
- package/node_modules/js-yaml/lib/js-yaml/common.js +59 -0
- package/node_modules/js-yaml/lib/js-yaml/dumper.js +850 -0
- package/node_modules/js-yaml/lib/js-yaml/exception.js +43 -0
- package/node_modules/js-yaml/lib/js-yaml/loader.js +1679 -0
- package/node_modules/js-yaml/lib/js-yaml/mark.js +76 -0
- package/node_modules/js-yaml/lib/js-yaml/schema/core.js +18 -0
- package/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +25 -0
- package/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +28 -0
- package/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +17 -0
- package/node_modules/js-yaml/lib/js-yaml/schema/json.js +25 -0
- package/node_modules/js-yaml/lib/js-yaml/schema.js +108 -0
- package/node_modules/js-yaml/lib/js-yaml/type/binary.js +138 -0
- package/node_modules/js-yaml/lib/js-yaml/type/bool.js +35 -0
- package/node_modules/js-yaml/lib/js-yaml/type/float.js +116 -0
- package/node_modules/js-yaml/lib/js-yaml/type/int.js +173 -0
- package/node_modules/js-yaml/lib/js-yaml/type/js/function.js +93 -0
- package/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +60 -0
- package/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +28 -0
- package/node_modules/js-yaml/lib/js-yaml/type/map.js +8 -0
- package/node_modules/js-yaml/lib/js-yaml/type/merge.js +12 -0
- package/node_modules/js-yaml/lib/js-yaml/type/null.js +34 -0
- package/node_modules/js-yaml/lib/js-yaml/type/omap.js +44 -0
- package/node_modules/js-yaml/lib/js-yaml/type/pairs.js +53 -0
- package/node_modules/js-yaml/lib/js-yaml/type/seq.js +8 -0
- package/node_modules/js-yaml/lib/js-yaml/type/set.js +29 -0
- package/node_modules/js-yaml/lib/js-yaml/type/str.js +8 -0
- package/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +88 -0
- package/node_modules/js-yaml/lib/js-yaml/type.js +61 -0
- package/node_modules/js-yaml/lib/js-yaml.js +39 -0
- package/node_modules/js-yaml/package.json +52 -0
- package/node_modules/kind-of/LICENSE +21 -0
- package/node_modules/kind-of/README.md +367 -0
- package/node_modules/kind-of/index.js +129 -0
- package/node_modules/kind-of/package.json +88 -0
- package/node_modules/pi-toggle-skills/README.md +213 -0
- package/node_modules/pi-toggle-skills/package.json +60 -0
- package/node_modules/pi-toggle-skills/src/index.ts +112 -0
- package/node_modules/pi-toggle-skills/src/skill-discovery.ts +258 -0
- package/node_modules/pi-toggle-skills/src/skill-selector.ts +435 -0
- package/node_modules/pi-toggle-skills/toggle-skills.ts +316 -0
- package/node_modules/pi-toggle-skills/vitest.config.ts +15 -0
- package/node_modules/proper-lockfile/LICENSE +21 -0
- package/node_modules/proper-lockfile/README.md +183 -0
- package/node_modules/proper-lockfile/index.js +40 -0
- package/node_modules/proper-lockfile/lib/adapter.js +85 -0
- package/node_modules/proper-lockfile/lib/lockfile.js +342 -0
- package/node_modules/proper-lockfile/lib/mtime-precision.js +55 -0
- package/node_modules/proper-lockfile/node_modules/retry/.npmignore +3 -0
- package/node_modules/proper-lockfile/node_modules/retry/.travis.yml +15 -0
- package/node_modules/proper-lockfile/node_modules/retry/License +21 -0
- package/node_modules/proper-lockfile/node_modules/retry/Makefile +18 -0
- package/node_modules/proper-lockfile/node_modules/retry/README.md +227 -0
- package/node_modules/proper-lockfile/node_modules/retry/equation.gif +0 -0
- package/node_modules/proper-lockfile/node_modules/retry/example/dns.js +31 -0
- package/node_modules/proper-lockfile/node_modules/retry/example/stop.js +40 -0
- package/node_modules/proper-lockfile/node_modules/retry/index.js +1 -0
- package/node_modules/proper-lockfile/node_modules/retry/lib/retry.js +100 -0
- package/node_modules/proper-lockfile/node_modules/retry/lib/retry_operation.js +158 -0
- package/node_modules/proper-lockfile/node_modules/retry/package.json +32 -0
- package/node_modules/proper-lockfile/node_modules/retry/test/common.js +10 -0
- package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-forever.js +24 -0
- package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-retry-operation.js +258 -0
- package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-retry-wrap.js +101 -0
- package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-timeouts.js +69 -0
- package/node_modules/proper-lockfile/package.json +71 -0
- package/node_modules/section-matter/LICENSE +21 -0
- package/node_modules/section-matter/README.md +236 -0
- package/node_modules/section-matter/index.js +136 -0
- package/node_modules/section-matter/package.json +55 -0
- package/node_modules/signal-exit/LICENSE.txt +16 -0
- package/node_modules/signal-exit/README.md +39 -0
- package/node_modules/signal-exit/index.js +202 -0
- package/node_modules/signal-exit/package.json +38 -0
- package/node_modules/signal-exit/signals.js +53 -0
- package/node_modules/sprintf-js/.npmignore +1 -0
- package/node_modules/sprintf-js/LICENSE +24 -0
- package/node_modules/sprintf-js/README.md +88 -0
- package/node_modules/sprintf-js/bower.json +14 -0
- package/node_modules/sprintf-js/demo/angular.html +20 -0
- package/node_modules/sprintf-js/dist/angular-sprintf.min.js +4 -0
- package/node_modules/sprintf-js/dist/angular-sprintf.min.js.map +1 -0
- package/node_modules/sprintf-js/dist/angular-sprintf.min.map +1 -0
- package/node_modules/sprintf-js/dist/sprintf.min.js +4 -0
- package/node_modules/sprintf-js/dist/sprintf.min.js.map +1 -0
- package/node_modules/sprintf-js/dist/sprintf.min.map +1 -0
- package/node_modules/sprintf-js/gruntfile.js +36 -0
- package/node_modules/sprintf-js/package.json +22 -0
- package/node_modules/sprintf-js/src/angular-sprintf.js +18 -0
- package/node_modules/sprintf-js/src/sprintf.js +208 -0
- package/node_modules/sprintf-js/test/test.js +82 -0
- package/node_modules/strip-bom-string/LICENSE +21 -0
- package/node_modules/strip-bom-string/README.md +66 -0
- package/node_modules/strip-bom-string/index.js +15 -0
- package/node_modules/strip-bom-string/package.json +60 -0
- package/package.json +13 -4
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { CustomEditor, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { registerEditorEnhancer, type EditorEnhancerHandle } from "@zigai/pi-extension-internals";
|
|
3
|
+
|
|
4
|
+
import { autocompleteStartIndex } from "./rendering.ts";
|
|
5
|
+
|
|
6
|
+
type EditorFactory = NonNullable<ReturnType<ExtensionContext["ui"]["getEditorComponent"]>>;
|
|
7
|
+
type EditorLike = ReturnType<EditorFactory>;
|
|
8
|
+
|
|
9
|
+
type AutocompleteVisibility = {
|
|
10
|
+
isShowingAutocomplete(): boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type AutocompleteTrigger = {
|
|
14
|
+
tryTriggerAutocomplete(): void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type CursorAccess = {
|
|
18
|
+
getCursor(): { readonly line: number; readonly col: number };
|
|
19
|
+
getLines(): string[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type SubmitAccess = {
|
|
23
|
+
onSubmit?: (text: string) => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type MentionContinuation = {
|
|
27
|
+
request(): void;
|
|
28
|
+
consume(): boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type MentionEditorContext = Pick<ExtensionContext, "hasUI"> & {
|
|
32
|
+
readonly ui: Pick<ExtensionContext["ui"], "getEditorComponent" | "setEditorComponent">;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type MentionEditorOptions = {
|
|
36
|
+
readonly key: symbol;
|
|
37
|
+
readonly isMentionContext: (line: string) => boolean;
|
|
38
|
+
readonly colorLine: (line: string) => string;
|
|
39
|
+
readonly continuation?: MentionContinuation;
|
|
40
|
+
readonly onTextChange?: (text: string) => void;
|
|
41
|
+
readonly onSubmitText?: (text: string) => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function hasAutocompleteVisibility(
|
|
45
|
+
editor: EditorLike,
|
|
46
|
+
): editor is EditorLike & AutocompleteVisibility {
|
|
47
|
+
return "isShowingAutocomplete" in editor && typeof editor.isShowingAutocomplete === "function";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function hasAutocompleteTrigger(editor: EditorLike): editor is EditorLike & AutocompleteTrigger {
|
|
51
|
+
return (
|
|
52
|
+
"tryTriggerAutocomplete" in editor && typeof editor.tryTriggerAutocomplete === "function"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function hasCursorAccess(editor: EditorLike): editor is EditorLike & CursorAccess {
|
|
57
|
+
return (
|
|
58
|
+
"getCursor" in editor &&
|
|
59
|
+
typeof editor.getCursor === "function" &&
|
|
60
|
+
"getLines" in editor &&
|
|
61
|
+
typeof editor.getLines === "function"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function hasSubmitAccess(editor: EditorLike): editor is EditorLike & SubmitAccess {
|
|
66
|
+
return "onSubmit" in editor;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isShowingAutocomplete(editor: EditorLike): boolean {
|
|
70
|
+
return hasAutocompleteVisibility(editor) && editor.isShowingAutocomplete();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function tryTriggerAutocomplete(editor: EditorLike): void {
|
|
74
|
+
if (hasAutocompleteTrigger(editor)) editor.tryTriggerAutocomplete();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function createMentionContinuation(): MentionContinuation {
|
|
78
|
+
let requested = false;
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
request() {
|
|
82
|
+
requested = true;
|
|
83
|
+
},
|
|
84
|
+
consume() {
|
|
85
|
+
const result = requested;
|
|
86
|
+
requested = false;
|
|
87
|
+
return result;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function handleInputWithSubmitCapture(
|
|
93
|
+
editor: EditorLike,
|
|
94
|
+
originalHandleInput: (data: string) => void,
|
|
95
|
+
data: string,
|
|
96
|
+
onSubmitText: ((text: string) => void) | undefined,
|
|
97
|
+
): void {
|
|
98
|
+
if (onSubmitText === undefined || !hasSubmitAccess(editor)) {
|
|
99
|
+
originalHandleInput(data);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const originalOnSubmit = editor.onSubmit;
|
|
104
|
+
const capturedOnSubmit = (text: string): void => {
|
|
105
|
+
onSubmitText(text);
|
|
106
|
+
originalOnSubmit?.(text);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
editor.onSubmit = capturedOnSubmit;
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
originalHandleInput(data);
|
|
113
|
+
} finally {
|
|
114
|
+
if (editor.onSubmit === capturedOnSubmit) editor.onSubmit = originalOnSubmit;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function enhanceEditor(editor: EditorLike, options: MentionEditorOptions): EditorLike {
|
|
119
|
+
const originalHandleInput = editor.handleInput.bind(editor);
|
|
120
|
+
|
|
121
|
+
editor.handleInput = (data: string) => {
|
|
122
|
+
const textBeforeInput = editor.getText();
|
|
123
|
+
const autocompleteWasShowing = isShowingAutocomplete(editor);
|
|
124
|
+
|
|
125
|
+
handleInputWithSubmitCapture(editor, originalHandleInput, data, options.onSubmitText);
|
|
126
|
+
|
|
127
|
+
const text = editor.getText();
|
|
128
|
+
const textChanged = text !== textBeforeInput;
|
|
129
|
+
if (textChanged) options.onTextChange?.(text);
|
|
130
|
+
|
|
131
|
+
if (options.continuation?.consume() === true) {
|
|
132
|
+
if (!isShowingAutocomplete(editor)) tryTriggerAutocomplete(editor);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (autocompleteWasShowing || isShowingAutocomplete(editor)) return;
|
|
137
|
+
|
|
138
|
+
if (!textChanged) {
|
|
139
|
+
const inputCharacters = Array.from(data);
|
|
140
|
+
if (inputCharacters.length !== 1 || /[\p{C}\s]/u.test(inputCharacters[0] ?? "")) return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let currentLine = text.split("\n").at(-1) ?? "";
|
|
144
|
+
if (hasCursorAccess(editor)) {
|
|
145
|
+
const cursor = editor.getCursor();
|
|
146
|
+
currentLine = editor.getLines()[cursor.line] ?? "";
|
|
147
|
+
currentLine = currentLine.slice(0, cursor.col);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!options.isMentionContext(currentLine)) return;
|
|
151
|
+
|
|
152
|
+
tryTriggerAutocomplete(editor);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const originalRender = editor.render.bind(editor);
|
|
156
|
+
|
|
157
|
+
editor.render = (width: number): string[] => {
|
|
158
|
+
const renderedLines = originalRender(width);
|
|
159
|
+
let colorThrough = renderedLines.length;
|
|
160
|
+
if (isShowingAutocomplete(editor)) colorThrough = autocompleteStartIndex(renderedLines);
|
|
161
|
+
return renderedLines.map((line, index) => {
|
|
162
|
+
if (index >= colorThrough) return line;
|
|
163
|
+
return options.colorLine(line);
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
return editor;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function applyMentionEditor(
|
|
171
|
+
ctx: MentionEditorContext,
|
|
172
|
+
options: MentionEditorOptions,
|
|
173
|
+
): EditorEnhancerHandle<Parameters<EditorFactory>, EditorLike> {
|
|
174
|
+
return registerEditorEnhancer(
|
|
175
|
+
ctx,
|
|
176
|
+
options.key,
|
|
177
|
+
(tui, theme, keybindings) => new CustomEditor(tui, theme, keybindings),
|
|
178
|
+
(editor) => enhanceEditor(editor, options),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { ContextEvent } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
import { mentionPattern, parseMentionName } from "./mention-syntax.ts";
|
|
4
|
+
|
|
5
|
+
export type MentionExpansionOptions<T> = {
|
|
6
|
+
readonly trigger: string;
|
|
7
|
+
readonly items: readonly T[];
|
|
8
|
+
readonly nameOf: (item: T) => string;
|
|
9
|
+
readonly replacementOf: (item: T) => string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function itemMap<T>(items: readonly T[], nameOf: (item: T) => string): Map<string, T> {
|
|
13
|
+
const byName = new Map<string, T>();
|
|
14
|
+
for (const item of items) {
|
|
15
|
+
const name = nameOf(item);
|
|
16
|
+
if (!byName.has(name)) byName.set(name, item);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return byName;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function expandMentions<T>(text: string, options: MentionExpansionOptions<T>): string {
|
|
23
|
+
const byName = itemMap(options.items, options.nameOf);
|
|
24
|
+
const knownNames = new Set(byName.keys());
|
|
25
|
+
|
|
26
|
+
return text.replace(
|
|
27
|
+
mentionPattern(options.trigger),
|
|
28
|
+
(
|
|
29
|
+
match: string,
|
|
30
|
+
leading: string,
|
|
31
|
+
quotedName: string | undefined,
|
|
32
|
+
unquotedName: string | undefined,
|
|
33
|
+
) => {
|
|
34
|
+
const parsed = parseMentionName(quotedName, unquotedName, knownNames);
|
|
35
|
+
if (parsed === undefined) return match;
|
|
36
|
+
|
|
37
|
+
const item = byName.get(parsed.name);
|
|
38
|
+
if (item === undefined) return match;
|
|
39
|
+
|
|
40
|
+
return `${leading}${options.replacementOf(item)}${parsed.suffix}`;
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type ContextMessage = ContextEvent["messages"][number];
|
|
46
|
+
type UserContextMessage = Extract<ContextMessage, { role: "user" }>;
|
|
47
|
+
type UserContentBlock = Exclude<UserContextMessage["content"], string>[number];
|
|
48
|
+
type UserTextContentBlock = Extract<UserContentBlock, { type: "text" }>;
|
|
49
|
+
|
|
50
|
+
function isUserTextContentBlock(block: UserContentBlock): block is UserTextContentBlock {
|
|
51
|
+
return block.type === "text";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type ParsedUserContent =
|
|
55
|
+
| { readonly kind: "text"; readonly text: string }
|
|
56
|
+
| { readonly kind: "blocks"; readonly blocks: UserContentBlock[] };
|
|
57
|
+
|
|
58
|
+
function parseUserContent(content: UserContextMessage["content"]): ParsedUserContent {
|
|
59
|
+
if (Array.isArray(content)) return { kind: "blocks", blocks: content };
|
|
60
|
+
|
|
61
|
+
return { kind: "text", text: content };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function firstRecentMessageIndex(messages: ContextEvent["messages"]): number {
|
|
65
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
66
|
+
const message = messages.at(index);
|
|
67
|
+
if (message?.role === "assistant" && message.stopReason !== "toolUse") return index + 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function recentUserMessageIndexesWithTrigger(
|
|
74
|
+
messages: ContextEvent["messages"],
|
|
75
|
+
trigger: string,
|
|
76
|
+
): number[] {
|
|
77
|
+
const indexes: number[] = [];
|
|
78
|
+
for (let index = firstRecentMessageIndex(messages); index < messages.length; index += 1) {
|
|
79
|
+
const message = messages.at(index);
|
|
80
|
+
if (message?.role !== "user") continue;
|
|
81
|
+
|
|
82
|
+
const content = parseUserContent(message.content);
|
|
83
|
+
if (content.kind === "text") {
|
|
84
|
+
if (content.text.includes(trigger)) indexes.push(index);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (
|
|
89
|
+
content.blocks.some(
|
|
90
|
+
(block) => isUserTextContentBlock(block) && block.text.includes(trigger),
|
|
91
|
+
)
|
|
92
|
+
) {
|
|
93
|
+
indexes.push(index);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return indexes;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function contextContainsMentionTrigger(
|
|
101
|
+
messages: ContextEvent["messages"],
|
|
102
|
+
trigger: string,
|
|
103
|
+
): boolean {
|
|
104
|
+
return recentUserMessageIndexesWithTrigger(messages, trigger).length > 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function expandMentionsInUserMessage<T>(
|
|
108
|
+
message: UserContextMessage,
|
|
109
|
+
options: MentionExpansionOptions<T>,
|
|
110
|
+
): UserContextMessage {
|
|
111
|
+
const parsedContent = parseUserContent(message.content);
|
|
112
|
+
if (parsedContent.kind === "text") {
|
|
113
|
+
const expanded = expandMentions(parsedContent.text, options);
|
|
114
|
+
if (expanded === parsedContent.text) return message;
|
|
115
|
+
|
|
116
|
+
return { ...message, content: expanded };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let changed = false;
|
|
120
|
+
const content: UserContentBlock[] = [];
|
|
121
|
+
for (const block of parsedContent.blocks) {
|
|
122
|
+
if (!isUserTextContentBlock(block) || !block.text.includes(options.trigger)) {
|
|
123
|
+
content.push(block);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const expanded = expandMentions(block.text, options);
|
|
128
|
+
if (expanded === block.text) {
|
|
129
|
+
content.push(block);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
changed = true;
|
|
134
|
+
content.push({ ...block, text: expanded });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!changed) return message;
|
|
138
|
+
|
|
139
|
+
return { ...message, content };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function expandMentionsInMessages<T>(
|
|
143
|
+
messages: ContextEvent["messages"],
|
|
144
|
+
options: MentionExpansionOptions<T>,
|
|
145
|
+
): ContextEvent["messages"] {
|
|
146
|
+
const indexes = recentUserMessageIndexesWithTrigger(messages, options.trigger);
|
|
147
|
+
if (indexes.length === 0) return messages;
|
|
148
|
+
|
|
149
|
+
let expandedMessages: ContextEvent["messages"] | undefined;
|
|
150
|
+
for (const index of indexes) {
|
|
151
|
+
const message = messages.at(index);
|
|
152
|
+
if (message?.role !== "user") continue;
|
|
153
|
+
|
|
154
|
+
const expanded = expandMentionsInUserMessage(message, options);
|
|
155
|
+
if (expanded === message) continue;
|
|
156
|
+
|
|
157
|
+
expandedMessages ??= [...messages];
|
|
158
|
+
expandedMessages[index] = expanded;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return expandedMessages ?? messages;
|
|
162
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
import { createConfiguredProvider } from "./configured-source.ts";
|
|
6
|
+
import { registerMentionSources, type MentionConfiguration } from "./register-mention.ts";
|
|
7
|
+
import { loadMentionAnythingSettings } from "./settings.ts";
|
|
8
|
+
|
|
9
|
+
export default function (pi: Pick<ExtensionAPI, "on">): void {
|
|
10
|
+
registerMentionSources(pi, (ctx) =>
|
|
11
|
+
loadMentionAnythingSettings(ctx).mentions.map((mention) => ({
|
|
12
|
+
id: mention.id,
|
|
13
|
+
configuration: (): MentionConfiguration => {
|
|
14
|
+
const base = {
|
|
15
|
+
trigger: mention.trigger,
|
|
16
|
+
separator: mention.separator,
|
|
17
|
+
completionSuffix: mention.completionSuffix,
|
|
18
|
+
initialSuggestions: mention.initialSuggestions,
|
|
19
|
+
expansionPolicy: mention.expansionPolicy,
|
|
20
|
+
replacementTemplate: mention.replacementTemplate,
|
|
21
|
+
};
|
|
22
|
+
if (mention.source.type === "static") return { ...base, cache: true };
|
|
23
|
+
|
|
24
|
+
const source = mention.source;
|
|
25
|
+
const configurationKey = createHash("sha256")
|
|
26
|
+
.update(JSON.stringify(mention))
|
|
27
|
+
.digest("hex");
|
|
28
|
+
const configuration = {
|
|
29
|
+
...base,
|
|
30
|
+
cache: source.cache,
|
|
31
|
+
debounceMs: source.debounceMs,
|
|
32
|
+
cacheTtlMs: source.cacheTtlMs,
|
|
33
|
+
refreshOnStartup: source.refreshOnStartup,
|
|
34
|
+
refreshIntervalMs: source.refreshIntervalMs,
|
|
35
|
+
watchFiles: source.watchFiles,
|
|
36
|
+
configurationKey,
|
|
37
|
+
};
|
|
38
|
+
if (source.persistentCache === true)
|
|
39
|
+
return {
|
|
40
|
+
...configuration,
|
|
41
|
+
persistentCachePath: join(
|
|
42
|
+
getAgentDir(),
|
|
43
|
+
"cache",
|
|
44
|
+
"pi-mention-anything",
|
|
45
|
+
`${mention.id}.json`,
|
|
46
|
+
),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return configuration;
|
|
50
|
+
},
|
|
51
|
+
provider: () => createConfiguredProvider(mention, ctx.cwd),
|
|
52
|
+
})),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
const FRECENCY_HALF_LIFE_DAYS = 30;
|
|
2
|
+
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1_000;
|
|
3
|
+
|
|
4
|
+
export type InitialSuggestionStrategy =
|
|
5
|
+
| "frecency"
|
|
6
|
+
| "recent"
|
|
7
|
+
| "frequent"
|
|
8
|
+
| "alphabetical"
|
|
9
|
+
| "sourceOrder";
|
|
10
|
+
|
|
11
|
+
export type InitialSuggestions = {
|
|
12
|
+
readonly strategy: InitialSuggestionStrategy;
|
|
13
|
+
readonly pinned: readonly string[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type Selection = {
|
|
17
|
+
readonly count: number;
|
|
18
|
+
readonly lastSelectedAt: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type SelectionHistory = {
|
|
22
|
+
load(): Promise<ReadonlyMap<string, Selection>>;
|
|
23
|
+
recordSelection(name: string): void;
|
|
24
|
+
flush(): Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type SelectionHistoryOptions = {
|
|
28
|
+
readonly stateFileName: string;
|
|
29
|
+
readonly errorMessage: string;
|
|
30
|
+
readonly filePath?: string;
|
|
31
|
+
readonly now?: () => number;
|
|
32
|
+
readonly onError?: (message: string) => void;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function compareNames(left: string, right: string): number {
|
|
36
|
+
return left.localeCompare(right, undefined, { sensitivity: "base" });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function historyRankingNeeded(strategy: InitialSuggestionStrategy): boolean {
|
|
40
|
+
return strategy === "frecency" || strategy === "recent" || strategy === "frequent";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function frecencyScore(selection: Selection | undefined, now: number): number {
|
|
44
|
+
if (selection === undefined) return 0;
|
|
45
|
+
|
|
46
|
+
const ageDays = Math.max(0, now - selection.lastSelectedAt) / MILLISECONDS_PER_DAY;
|
|
47
|
+
return selection.count / (1 + ageDays / FRECENCY_HALF_LIFE_DAYS);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function rankInitialSuggestions<T>(
|
|
51
|
+
items: readonly T[],
|
|
52
|
+
nameOf: (item: T) => string,
|
|
53
|
+
settings: InitialSuggestions,
|
|
54
|
+
selections: ReadonlyMap<string, Selection>,
|
|
55
|
+
now = Date.now(),
|
|
56
|
+
priorityOf?: (item: T) => number,
|
|
57
|
+
): T[] {
|
|
58
|
+
const pinnedIndexes = new Map(settings.pinned.map((name, index) => [name, index]));
|
|
59
|
+
const ranked = items.map((item, sourceIndex) => {
|
|
60
|
+
let priority = 0;
|
|
61
|
+
if (priorityOf !== undefined) priority = priorityOf(item);
|
|
62
|
+
|
|
63
|
+
return { item, name: nameOf(item), priority, sourceIndex };
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
ranked.sort((left, right) => {
|
|
67
|
+
const leftPin = pinnedIndexes.get(left.name);
|
|
68
|
+
const rightPin = pinnedIndexes.get(right.name);
|
|
69
|
+
if (leftPin !== undefined || rightPin !== undefined) {
|
|
70
|
+
if (leftPin === undefined) return 1;
|
|
71
|
+
if (rightPin === undefined) return -1;
|
|
72
|
+
return leftPin - rightPin;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const priorityComparison = left.priority - right.priority;
|
|
76
|
+
if (priorityComparison !== 0) return priorityComparison;
|
|
77
|
+
|
|
78
|
+
const leftSelection = selections.get(left.name);
|
|
79
|
+
const rightSelection = selections.get(right.name);
|
|
80
|
+
switch (settings.strategy) {
|
|
81
|
+
case "alphabetical": {
|
|
82
|
+
const comparison = compareNames(left.name, right.name);
|
|
83
|
+
if (comparison !== 0) return comparison;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "recent": {
|
|
87
|
+
const comparison =
|
|
88
|
+
(rightSelection?.lastSelectedAt ?? -1) - (leftSelection?.lastSelectedAt ?? -1);
|
|
89
|
+
if (comparison !== 0) return comparison;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "frequent": {
|
|
93
|
+
const comparison = (rightSelection?.count ?? 0) - (leftSelection?.count ?? 0);
|
|
94
|
+
if (comparison !== 0) return comparison;
|
|
95
|
+
|
|
96
|
+
const recencyComparison =
|
|
97
|
+
(rightSelection?.lastSelectedAt ?? -1) - (leftSelection?.lastSelectedAt ?? -1);
|
|
98
|
+
if (recencyComparison !== 0) return recencyComparison;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "frecency": {
|
|
102
|
+
const comparison =
|
|
103
|
+
frecencyScore(rightSelection, now) - frecencyScore(leftSelection, now);
|
|
104
|
+
if (comparison !== 0) return comparison;
|
|
105
|
+
|
|
106
|
+
const recencyComparison =
|
|
107
|
+
(rightSelection?.lastSelectedAt ?? -1) - (leftSelection?.lastSelectedAt ?? -1);
|
|
108
|
+
if (recencyComparison !== 0) return recencyComparison;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "sourceOrder":
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return left.sourceIndex - right.sourceIndex;
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return ranked.map(({ item }) => item);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function rankWithSelectionHistory<T>(
|
|
122
|
+
items: readonly T[],
|
|
123
|
+
nameOf: (item: T) => string,
|
|
124
|
+
settings: InitialSuggestions,
|
|
125
|
+
history: SelectionHistory | undefined,
|
|
126
|
+
priorityOf?: (item: T) => number,
|
|
127
|
+
): Promise<T[]> {
|
|
128
|
+
let selections: ReadonlyMap<string, Selection> = new Map();
|
|
129
|
+
if (history !== undefined && historyRankingNeeded(settings.strategy)) {
|
|
130
|
+
selections = await history.load();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return rankInitialSuggestions(items, nameOf, settings, selections, Date.now(), priorityOf);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function createLazySelectionHistory(options: SelectionHistoryOptions): SelectionHistory {
|
|
137
|
+
let historyTask: Promise<SelectionHistory> | undefined;
|
|
138
|
+
let pendingRecords = Promise.resolve();
|
|
139
|
+
let errorReported = false;
|
|
140
|
+
|
|
141
|
+
const reportError = (): void => {
|
|
142
|
+
if (errorReported) return;
|
|
143
|
+
|
|
144
|
+
errorReported = true;
|
|
145
|
+
options.onError?.(options.errorMessage);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const unavailableHistory: SelectionHistory = {
|
|
149
|
+
async load() {
|
|
150
|
+
return new Map();
|
|
151
|
+
},
|
|
152
|
+
recordSelection() {
|
|
153
|
+
return;
|
|
154
|
+
},
|
|
155
|
+
async flush() {
|
|
156
|
+
return;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
const getHistory = async (): Promise<SelectionHistory> => {
|
|
160
|
+
if (historyTask !== undefined) return historyTask;
|
|
161
|
+
|
|
162
|
+
historyTask = import("./selection-history.ts")
|
|
163
|
+
.then(({ createSelectionHistory }) => createSelectionHistory(options))
|
|
164
|
+
.catch(() => {
|
|
165
|
+
reportError();
|
|
166
|
+
return unavailableHistory;
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return historyTask;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
async load() {
|
|
174
|
+
return (await getHistory()).load();
|
|
175
|
+
},
|
|
176
|
+
recordSelection(name) {
|
|
177
|
+
pendingRecords = pendingRecords.then(async () => {
|
|
178
|
+
const history = await getHistory();
|
|
179
|
+
history.recordSelection(name);
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
async flush() {
|
|
183
|
+
await pendingRecords;
|
|
184
|
+
|
|
185
|
+
if (historyTask === undefined) return;
|
|
186
|
+
|
|
187
|
+
await (await historyTask).flush();
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Candidate, DiscoveryRequest, Provider } from "./source-contract.ts";
|
|
2
|
+
|
|
3
|
+
/** Adapt a bounded enumerable source. Large remote sources should implement exact resolution directly. */
|
|
4
|
+
export function createListProvider(
|
|
5
|
+
loadItems: (request: DiscoveryRequest) => Promise<readonly Candidate[]>,
|
|
6
|
+
): Provider {
|
|
7
|
+
return {
|
|
8
|
+
filtering: "local",
|
|
9
|
+
async discover(request) {
|
|
10
|
+
request.signal.throwIfAborted();
|
|
11
|
+
const items = await loadItems(request);
|
|
12
|
+
if (items.length > 10000)
|
|
13
|
+
throw new Error(
|
|
14
|
+
"Enumerable mention sources are limited to 10000 items per parent.",
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
request.signal.throwIfAborted();
|
|
18
|
+
return { items: items.slice(0, request.limit) };
|
|
19
|
+
},
|
|
20
|
+
async resolve(request) {
|
|
21
|
+
request.signal.throwIfAborted();
|
|
22
|
+
const path: Candidate[] = [];
|
|
23
|
+
for (const [index, segment] of request.segments.entries()) {
|
|
24
|
+
const items = await loadItems({
|
|
25
|
+
sourceId: request.sourceId,
|
|
26
|
+
cwd: request.cwd,
|
|
27
|
+
trusted: request.trusted,
|
|
28
|
+
query: "",
|
|
29
|
+
path,
|
|
30
|
+
limit: 10000,
|
|
31
|
+
signal: request.signal,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
request.signal.throwIfAborted();
|
|
35
|
+
|
|
36
|
+
if (items.length > 10000)
|
|
37
|
+
throw new Error(
|
|
38
|
+
"Enumerable mention sources are limited to 10000 items per parent.",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const matches = items.filter((item) => item.segment === segment);
|
|
42
|
+
if (matches.length === 0) {
|
|
43
|
+
return { status: "unresolved", reason: "missing" };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (matches.length > 1) {
|
|
47
|
+
return { status: "unresolved", reason: "ambiguous" };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const candidate = matches.at(0);
|
|
51
|
+
if (candidate === undefined) {
|
|
52
|
+
return { status: "unresolved", reason: "missing" };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const finalSegment = index === request.segments.length - 1;
|
|
56
|
+
if (!finalSegment && !candidate.navigable) {
|
|
57
|
+
return { status: "unresolved", reason: "not-navigable" };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
path.push(candidate);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (path.length === 0) return { status: "unresolved", reason: "empty" };
|
|
64
|
+
|
|
65
|
+
const target = path.at(-1);
|
|
66
|
+
if (target?.replacement === undefined) return { status: "resolved", path };
|
|
67
|
+
|
|
68
|
+
return { status: "resolved", path, replacement: target.replacement };
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|