@unbrained/pm-cli 2026.5.18 → 2026.5.27
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 +953 -472
- package/README.md +4 -11
- package/dist/cli/bootstrap-args.d.ts +18 -1
- package/dist/cli/bootstrap-args.js +143 -3
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +147 -10
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/annotation-command.d.ts +49 -0
- package/dist/cli/commands/annotation-command.js +135 -0
- package/dist/cli/commands/annotation-command.js.map +1 -0
- package/dist/cli/commands/append.js +5 -8
- package/dist/cli/commands/append.js.map +1 -1
- package/dist/cli/commands/calendar.js +3 -6
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/claim.js +15 -24
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.js +63 -10
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments.d.ts +5 -0
- package/dist/cli/commands/comments.js +27 -117
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.d.ts +2 -2
- package/dist/cli/commands/completion.js +203 -63
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.d.ts +1 -1
- package/dist/cli/commands/config.js +82 -4
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context.js +4 -10
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +168 -36
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +53 -313
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/dedupe-audit.js +7 -4
- package/dist/cli/commands/dedupe-audit.js.map +1 -1
- package/dist/cli/commands/delete.d.ts +3 -0
- package/dist/cli/commands/delete.js +11 -9
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +2 -12
- package/dist/cli/commands/docs.js +8 -316
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/event-validation-messages.d.ts +3 -0
- package/dist/cli/commands/event-validation-messages.js +44 -0
- package/dist/cli/commands/event-validation-messages.js.map +1 -0
- package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
- package/dist/cli/commands/extension/bundled-catalog.js +268 -0
- package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
- package/dist/cli/commands/extension/doctor.d.ts +31 -0
- package/dist/cli/commands/extension/doctor.js +345 -0
- package/dist/cli/commands/extension/doctor.js.map +1 -0
- package/dist/cli/commands/extension/install-sources.d.ts +37 -0
- package/dist/cli/commands/extension/install-sources.js +384 -0
- package/dist/cli/commands/extension/install-sources.js.map +1 -0
- package/dist/cli/commands/extension/managed-state.d.ts +48 -0
- package/dist/cli/commands/extension/managed-state.js +172 -0
- package/dist/cli/commands/extension/managed-state.js.map +1 -0
- package/dist/cli/commands/extension/scaffold.d.ts +14 -0
- package/dist/cli/commands/extension/scaffold.js +169 -0
- package/dist/cli/commands/extension/scaffold.js.map +1 -0
- package/dist/cli/commands/extension/shared.d.ts +14 -0
- package/dist/cli/commands/extension/shared.js +106 -0
- package/dist/cli/commands/extension/shared.js.map +1 -0
- package/dist/cli/commands/extension.d.ts +37 -68
- package/dist/cli/commands/extension.js +157 -1319
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.d.ts +1 -12
- package/dist/cli/commands/files.js +14 -318
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/gc.js +17 -4
- package/dist/cli/commands/gc.js.map +1 -1
- package/dist/cli/commands/get.d.ts +3 -2
- package/dist/cli/commands/get.js +52 -9
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.d.ts +10 -0
- package/dist/cli/commands/health.js +269 -76
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-redact.d.ts +8 -0
- package/dist/cli/commands/history-redact.js +35 -113
- package/dist/cli/commands/history-redact.js.map +1 -1
- package/dist/cli/commands/history-repair.d.ts +33 -0
- package/dist/cli/commands/history-repair.js +172 -0
- package/dist/cli/commands/history-repair.js.map +1 -0
- package/dist/cli/commands/history.d.ts +4 -4
- package/dist/cli/commands/history.js +10 -88
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +3 -1
- package/dist/cli/commands/index.js +5 -3
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +28 -0
- package/dist/cli/commands/init.js +23 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learnings.js +20 -119
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
- package/dist/cli/commands/legacy-none-tokens.js +39 -0
- package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
- package/dist/cli/commands/linked-artifacts.d.ts +96 -0
- package/dist/cli/commands/linked-artifacts.js +335 -0
- package/dist/cli/commands/linked-artifacts.js.map +1 -0
- package/dist/cli/commands/linked-test-entry.d.ts +3 -0
- package/dist/cli/commands/linked-test-entry.js +62 -0
- package/dist/cli/commands/linked-test-entry.js.map +1 -0
- package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
- package/dist/cli/commands/linked-test-parsers.js +192 -0
- package/dist/cli/commands/linked-test-parsers.js.map +1 -0
- package/dist/cli/commands/list.js +49 -24
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/normalize.js +4 -3
- package/dist/cli/commands/normalize.js.map +1 -1
- package/dist/cli/commands/notes.js +20 -119
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +3 -0
- package/dist/cli/commands/plan.js +184 -22
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
- package/dist/cli/commands/recurrence-parsers.js +98 -0
- package/dist/cli/commands/recurrence-parsers.js.map +1 -0
- package/dist/cli/commands/restore.js +24 -56
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/schema.d.ts +31 -0
- package/dist/cli/commands/schema.js +98 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/search.js +154 -42
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/templates.d.ts +4 -0
- package/dist/cli/commands/templates.js +89 -17
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
- package/dist/cli/commands/test/linked-command-detection.js +200 -0
- package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
- package/dist/cli/commands/test-all.js +4 -8
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +2 -2
- package/dist/cli/commands/test.js +12 -357
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.js +6 -9
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.js +167 -401
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +3 -1
- package/dist/cli/commands/validate.js +23 -71
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +1 -0
- package/dist/cli/error-guidance.js +100 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.d.ts +0 -1
- package/dist/cli/extension-command-help.js +2 -13
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/extension-command-options.d.ts +1 -0
- package/dist/cli/extension-command-options.js +106 -7
- package/dist/cli/extension-command-options.js.map +1 -1
- package/dist/cli/help-content.d.ts +0 -1
- package/dist/cli/help-content.js +13 -9
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.d.ts +1 -0
- package/dist/cli/help-json-payload.js +33 -3
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.d.ts +11 -0
- package/dist/cli/main.js +109 -55
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.d.ts +5 -2
- package/dist/cli/register-list-query.js +254 -192
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.d.ts +1 -1
- package/dist/cli/register-mutation.js +247 -64
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +17 -12
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +33 -16
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +0 -2
- package/dist/cli/registration-helpers.js +14 -40
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli.js +25 -4
- package/dist/cli.js.map +1 -1
- package/dist/core/config/positional-value.d.ts +44 -0
- package/dist/core/config/positional-value.js +109 -0
- package/dist/core/config/positional-value.js.map +1 -0
- package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
- package/dist/core/extensions/extension-capability-aliases.js +159 -0
- package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
- package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
- package/dist/core/extensions/extension-hook-runtime.js +414 -0
- package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
- package/dist/core/extensions/extension-policy.d.ts +69 -0
- package/dist/core/extensions/extension-policy.js +481 -0
- package/dist/core/extensions/extension-policy.js.map +1 -0
- package/dist/core/extensions/extension-registries.d.ts +8 -0
- package/dist/core/extensions/extension-registries.js +52 -0
- package/dist/core/extensions/extension-registries.js.map +1 -0
- package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
- package/dist/core/extensions/extension-runtime-helpers.js +29 -0
- package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
- package/dist/core/extensions/extension-types.d.ts +13 -39
- package/dist/core/extensions/extension-types.js +34 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +7 -1
- package/dist/core/extensions/index.js +11 -14
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +4 -22
- package/dist/core/extensions/loader.js +23 -1146
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/fs/path-utils.d.ts +1 -0
- package/dist/core/fs/path-utils.js +12 -0
- package/dist/core/fs/path-utils.js.map +1 -0
- package/dist/core/history/drift-scan.d.ts +22 -0
- package/dist/core/history/drift-scan.js +149 -0
- package/dist/core/history/drift-scan.js.map +1 -0
- package/dist/core/history/history-rewrite.d.ts +43 -0
- package/dist/core/history/history-rewrite.js +48 -0
- package/dist/core/history/history-rewrite.js.map +1 -0
- package/dist/core/history/history.js +5 -4
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/history/replay.d.ts +82 -0
- package/dist/core/history/replay.js +250 -0
- package/dist/core/history/replay.js.map +1 -0
- package/dist/core/item/item-format.js +11 -8
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/item/item-record.d.ts +19 -0
- package/dist/core/item/item-record.js +24 -0
- package/dist/core/item/item-record.js.map +1 -0
- package/dist/core/item/item-type-definition.d.ts +52 -0
- package/dist/core/item/item-type-definition.js +123 -0
- package/dist/core/item/item-type-definition.js.map +1 -0
- package/dist/core/item/parse.js +3 -2
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/item/priority.d.ts +23 -0
- package/dist/core/item/priority.js +55 -0
- package/dist/core/item/priority.js.map +1 -0
- package/dist/core/item/status.d.ts +14 -1
- package/dist/core/item/status.js +22 -2
- package/dist/core/item/status.js.map +1 -1
- package/dist/core/item/toon-decode.d.ts +19 -0
- package/dist/core/item/toon-decode.js +69 -0
- package/dist/core/item/toon-decode.js.map +1 -0
- package/dist/core/item/type-registry.js +13 -84
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/output/mutation-projection.d.ts +31 -0
- package/dist/core/output/mutation-projection.js +103 -0
- package/dist/core/output/mutation-projection.js.map +1 -0
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +5 -3
- package/dist/core/output/output.js.map +1 -1
- package/dist/core/packages/manifest.js +3 -9
- package/dist/core/packages/manifest.js.map +1 -1
- package/dist/core/schema/item-types-file.d.ts +85 -0
- package/dist/core/schema/item-types-file.js +243 -0
- package/dist/core/schema/item-types-file.js.map +1 -0
- package/dist/core/schema/runtime-schema.d.ts +2 -1
- package/dist/core/schema/runtime-schema.js +17 -45
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +3 -3
- package/dist/core/search/semantic-defaults.js.map +1 -1
- package/dist/core/search/vector-stores.js +46 -9
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.d.ts +1 -1
- package/dist/core/sentry/helpers.js +20 -3
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/shared/author.d.ts +1 -0
- package/dist/core/shared/author.js +9 -0
- package/dist/core/shared/author.js.map +1 -0
- package/dist/core/shared/command-types.d.ts +1 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/command-types.js.map +1 -1
- package/dist/core/shared/constants.d.ts +10 -1
- package/dist/core/shared/constants.js +56 -58
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/lazy-module.d.ts +1 -0
- package/dist/core/shared/lazy-module.js +11 -0
- package/dist/core/shared/lazy-module.js.map +1 -0
- package/dist/core/shared/option-alias-visibility.d.ts +44 -0
- package/dist/core/shared/option-alias-visibility.js +76 -0
- package/dist/core/shared/option-alias-visibility.js.map +1 -0
- package/dist/core/shared/primitives.d.ts +23 -0
- package/dist/core/shared/primitives.js +39 -2
- package/dist/core/shared/primitives.js.map +1 -1
- package/dist/core/shared/text-normalization.d.ts +0 -1
- package/dist/core/shared/text-normalization.js +2 -5
- package/dist/core/shared/text-normalization.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +16 -2
- package/dist/core/store/front-matter-cache.js +99 -33
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-store.d.ts +2 -0
- package/dist/core/store/item-store.js +76 -110
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +106 -0
- package/dist/core/store/settings-validator.js +279 -0
- package/dist/core/store/settings-validator.js.map +1 -0
- package/dist/core/store/settings.js +6 -343
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.js +5 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/mcp/server.js +138 -39
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +18 -33
- package/dist/sdk/cli-contracts.js +96 -1238
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/package-import-adapters.d.ts +74 -0
- package/dist/sdk/package-import-adapters.js +186 -0
- package/dist/sdk/package-import-adapters.js.map +1 -0
- package/dist/sdk/package-runtime-options.d.ts +26 -0
- package/dist/sdk/package-runtime-options.js +71 -0
- package/dist/sdk/package-runtime-options.js.map +1 -0
- package/dist/sdk/runtime.d.ts +27 -1
- package/dist/sdk/runtime.js +48 -3
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.js +10 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +13 -11
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
- package/docs/CODEX_PLUGIN.md +5 -5
- package/docs/COMMANDS.md +58 -9
- package/docs/CONFIGURATION.md +16 -1
- package/docs/EXTENSIONS.md +4 -63
- package/docs/RELEASING.md +12 -8
- package/docs/SDK.md +11 -2
- package/marketplace.json +7 -3
- package/package.json +18 -14
- package/packages/pm-beads/extensions/beads/index.js +2 -49
- package/packages/pm-beads/extensions/beads/index.ts +2 -54
- package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
- package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
- package/packages/pm-beads/extensions/beads/runtime.js +26 -115
- package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
- package/packages/pm-calendar/README.md +3 -1
- package/packages/pm-calendar/extensions/calendar/index.js +66 -2
- package/packages/pm-calendar/extensions/calendar/index.ts +71 -2
- package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
- package/packages/pm-search-advanced/README.md +8 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +75 -1
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +74 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +58 -33
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +60 -33
- package/packages/pm-templates/extensions/templates/runtime.js +11 -202
- package/packages/pm-templates/extensions/templates/runtime.ts +38 -230
- package/packages/pm-todos/extensions/todos/index.js +3 -50
- package/packages/pm-todos/extensions/todos/index.ts +3 -55
- package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
- package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
- package/packages/pm-todos/extensions/todos/runtime.js +24 -117
- package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
- package/plugins/pm-claude/README.md +2 -2
- package/plugins/pm-claude/commands/pm-planner.md +1 -15
- package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
- package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
- package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
- package/PRD.md +0 -1734
- package/dist/core/output/command-aware.d.ts +0 -1
- package/dist/core/output/command-aware.js +0 -397
- package/dist/core/output/command-aware.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7b4219a0-215b-5cfa-a437-f979968a70c4")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
|
|
6
|
+
import { isPathWithinDirectory } from "../../core/fs/path-utils.js";
|
|
6
7
|
import { getActiveExtensionRegistrations, runActiveOnReadHooks } from "../../core/extensions/index.js";
|
|
7
8
|
import { resolveRegisteredSearchProvider, resolveRegisteredVectorStoreAdapter, } from "../../core/extensions/runtime-registrations.js";
|
|
8
9
|
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
@@ -13,7 +14,8 @@ import { executeVectorQuery, resolveVectorStores, } from "../../core/search/vect
|
|
|
13
14
|
import { buildEventCorpus, buildPlanFlatCorpus, buildReminderCorpus } from "../../core/search/corpus.js";
|
|
14
15
|
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
15
16
|
import { parseItemDocument } from "../../core/item/item-format.js";
|
|
16
|
-
import {
|
|
17
|
+
import { toItemRecord } from "../../core/item/item-record.js";
|
|
18
|
+
import { isTerminalStatus } from "../../core/item/status.js";
|
|
17
19
|
import { collectRuntimeFilterValues, matchesRuntimeFilters } from "../../core/schema/runtime-field-filters.js";
|
|
18
20
|
import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
|
|
19
21
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
@@ -34,15 +36,68 @@ const DEFAULT_COMPACT_SEARCH_FIELDS = [
|
|
|
34
36
|
"score",
|
|
35
37
|
"matched_fields",
|
|
36
38
|
];
|
|
39
|
+
const SEARCH_HIT_FIELD_KEYS = new Set(["score", "matched_fields"]);
|
|
40
|
+
const SEARCH_ITEM_FIELD_KEYS = new Set([
|
|
41
|
+
"id",
|
|
42
|
+
"title",
|
|
43
|
+
"description",
|
|
44
|
+
"type",
|
|
45
|
+
"status",
|
|
46
|
+
"priority",
|
|
47
|
+
"tags",
|
|
48
|
+
"created_at",
|
|
49
|
+
"updated_at",
|
|
50
|
+
"deadline",
|
|
51
|
+
"assignee",
|
|
52
|
+
"author",
|
|
53
|
+
"estimated_minutes",
|
|
54
|
+
"acceptance_criteria",
|
|
55
|
+
"dependencies",
|
|
56
|
+
"comments",
|
|
57
|
+
"notes",
|
|
58
|
+
"learnings",
|
|
59
|
+
"reminders",
|
|
60
|
+
"events",
|
|
61
|
+
"files",
|
|
62
|
+
"tests",
|
|
63
|
+
"docs",
|
|
64
|
+
"close_reason",
|
|
65
|
+
"parent",
|
|
66
|
+
"reviewer",
|
|
67
|
+
"risk",
|
|
68
|
+
"confidence",
|
|
69
|
+
"sprint",
|
|
70
|
+
"release",
|
|
71
|
+
"blocked_by",
|
|
72
|
+
"blocked_reason",
|
|
73
|
+
"reporter",
|
|
74
|
+
"severity",
|
|
75
|
+
"environment",
|
|
76
|
+
"repro_steps",
|
|
77
|
+
"resolution",
|
|
78
|
+
"expected_result",
|
|
79
|
+
"actual_result",
|
|
80
|
+
"affected_version",
|
|
81
|
+
"fixed_version",
|
|
82
|
+
"component",
|
|
83
|
+
"regression",
|
|
84
|
+
"customer_impact",
|
|
85
|
+
"definition_of_ready",
|
|
86
|
+
"order",
|
|
87
|
+
"rank",
|
|
88
|
+
"goal",
|
|
89
|
+
"objective",
|
|
90
|
+
"value",
|
|
91
|
+
"impact",
|
|
92
|
+
"outcome",
|
|
93
|
+
"why_now",
|
|
94
|
+
"plan",
|
|
95
|
+
]);
|
|
37
96
|
const LONG_QUERY_TOKEN_THRESHOLD = 2;
|
|
38
97
|
const LONG_QUERY_TITLE_EXACT_BONUS = 120;
|
|
39
98
|
const LONG_QUERY_PHRASE_MULTIPLIER = 6;
|
|
40
99
|
const IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS = 8_000;
|
|
41
100
|
const IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS = 8_000;
|
|
42
|
-
function isTerminal(status, statusRegistry) {
|
|
43
|
-
const normalized = normalizeStatusInput(status, statusRegistry) ?? status;
|
|
44
|
-
return statusRegistry.terminal_statuses.has(normalized);
|
|
45
|
-
}
|
|
46
101
|
function classifyImplicitSemanticFallbackReason(error) {
|
|
47
102
|
const message = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
48
103
|
if (message.includes("timed out") || message.includes("timeout")) {
|
|
@@ -67,9 +122,16 @@ function buildImplicitSemanticFallbackWarning(error) {
|
|
|
67
122
|
}
|
|
68
123
|
return "search_implicit_semantic_fallback:error:using_keyword_mode";
|
|
69
124
|
}
|
|
70
|
-
|
|
125
|
+
// Explicit --semantic/--hybrid searches must never hard-fail an agent when the
|
|
126
|
+
// embedding/vector backend is unreachable or unconfigured: degrade to keyword
|
|
127
|
+
// search and surface a machine-readable warning instead of an unknown_error.
|
|
128
|
+
function buildExplicitSemanticFallbackWarning(requestedMode, error) {
|
|
129
|
+
const reason = classifyImplicitSemanticFallbackReason(error);
|
|
130
|
+
return `search_${requestedMode}_fallback:${reason}:using_keyword_mode`;
|
|
131
|
+
}
|
|
132
|
+
function parseMode(raw, _context) {
|
|
71
133
|
if (raw === undefined) {
|
|
72
|
-
return
|
|
134
|
+
return "keyword";
|
|
73
135
|
}
|
|
74
136
|
const normalized = raw.trim().toLowerCase();
|
|
75
137
|
if (normalized !== "keyword" && normalized !== "semantic" && normalized !== "hybrid") {
|
|
@@ -141,6 +203,26 @@ function parseProjectionConfig(options) {
|
|
|
141
203
|
fields: [],
|
|
142
204
|
};
|
|
143
205
|
}
|
|
206
|
+
function validateSearchProjectionFields(projection, runtimeFieldRegistry) {
|
|
207
|
+
if (projection.mode !== "fields") {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const runtimeKeys = new Set(runtimeFieldRegistry.definitions.flatMap((field) => [field.key, field.metadata_key]));
|
|
211
|
+
const unknown = projection.fields.filter((field) => {
|
|
212
|
+
const normalized = field.trim();
|
|
213
|
+
const itemKey = normalized.startsWith("item.") ? normalized.slice("item.".length) : normalized;
|
|
214
|
+
return !SEARCH_HIT_FIELD_KEYS.has(normalized) && !SEARCH_ITEM_FIELD_KEYS.has(itemKey) && !runtimeKeys.has(itemKey);
|
|
215
|
+
});
|
|
216
|
+
if (unknown.length > 0) {
|
|
217
|
+
throw new PmCliError(`Unknown search --fields value(s): ${unknown.join(", ")}`, EXIT_CODE.USAGE, {
|
|
218
|
+
examples: [
|
|
219
|
+
"pm search <query> --fields id,title,status,score",
|
|
220
|
+
"pm search <query> --fields id,title,item.description,matched_fields",
|
|
221
|
+
],
|
|
222
|
+
nextSteps: ["Use item.<field> for explicit item metadata fields, or run pm search --help for projection examples."],
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
144
226
|
function parseTokens(query) {
|
|
145
227
|
const normalized = normalizeSearchPhrase(query);
|
|
146
228
|
if (!normalized) {
|
|
@@ -148,20 +230,36 @@ function parseTokens(query) {
|
|
|
148
230
|
}
|
|
149
231
|
return normalized.split(/\s+/).filter(Boolean);
|
|
150
232
|
}
|
|
233
|
+
function stringArray(value) {
|
|
234
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
235
|
+
}
|
|
236
|
+
function textEntries(value) {
|
|
237
|
+
return Array.isArray(value)
|
|
238
|
+
? value.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.text === "string")
|
|
239
|
+
: [];
|
|
240
|
+
}
|
|
241
|
+
function dependencyEntries(value) {
|
|
242
|
+
return Array.isArray(value)
|
|
243
|
+
? value.filter((entry) => typeof entry === "object" &&
|
|
244
|
+
entry !== null &&
|
|
245
|
+
typeof entry.id === "string" &&
|
|
246
|
+
typeof entry.kind === "string")
|
|
247
|
+
: [];
|
|
248
|
+
}
|
|
151
249
|
function collectExactPhraseFields(document) {
|
|
152
250
|
const item = document.metadata;
|
|
153
251
|
return [
|
|
154
252
|
item.title,
|
|
155
253
|
item.description,
|
|
156
254
|
item.status,
|
|
157
|
-
item.tags.join(" "),
|
|
255
|
+
stringArray(item.tags).join(" "),
|
|
158
256
|
document.body,
|
|
159
|
-
(item.comments
|
|
160
|
-
(item.notes
|
|
161
|
-
(item.learnings
|
|
257
|
+
textEntries(item.comments).map((entry) => entry.text).join(" "),
|
|
258
|
+
textEntries(item.notes).map((entry) => entry.text).join(" "),
|
|
259
|
+
textEntries(item.learnings).map((entry) => entry.text).join(" "),
|
|
162
260
|
buildReminderCorpus(item).join(" "),
|
|
163
261
|
buildEventCorpus(item).join(" "),
|
|
164
|
-
(item.dependencies
|
|
262
|
+
dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
|
|
165
263
|
buildPlanFlatCorpus(item),
|
|
166
264
|
];
|
|
167
265
|
}
|
|
@@ -192,7 +290,7 @@ function applyFilters(items, options, typeRegistry, runtimeFieldFilters) {
|
|
|
192
290
|
const item = document.metadata;
|
|
193
291
|
if (typeFilter && item.type !== typeFilter)
|
|
194
292
|
return false;
|
|
195
|
-
if (tagFilter && !item.tags.includes(tagFilter))
|
|
293
|
+
if (tagFilter && !stringArray(item.tags).includes(tagFilter))
|
|
196
294
|
return false;
|
|
197
295
|
if (priorityFilter !== undefined && item.priority !== priorityFilter)
|
|
198
296
|
return false;
|
|
@@ -244,13 +342,6 @@ function collectLinkedPaths(item) {
|
|
|
244
342
|
}
|
|
245
343
|
return [...deduped.values()];
|
|
246
344
|
}
|
|
247
|
-
function isPathWithinRoot(root, resolvedPath) {
|
|
248
|
-
const relative = path.relative(root, resolvedPath);
|
|
249
|
-
if (relative.length === 0) {
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
return !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
253
|
-
}
|
|
254
345
|
async function resolveContainmentRoot(root) {
|
|
255
346
|
const resolved = path.resolve(root);
|
|
256
347
|
try {
|
|
@@ -283,7 +374,7 @@ async function loadLinkedCorpus(document, roots) {
|
|
|
283
374
|
continue;
|
|
284
375
|
}
|
|
285
376
|
const resolved = path.resolve(containmentRoot.resolved, linkedPath.path);
|
|
286
|
-
if (!
|
|
377
|
+
if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {
|
|
287
378
|
continue;
|
|
288
379
|
}
|
|
289
380
|
let linkedRealpath;
|
|
@@ -293,7 +384,7 @@ async function loadLinkedCorpus(document, roots) {
|
|
|
293
384
|
catch {
|
|
294
385
|
continue;
|
|
295
386
|
}
|
|
296
|
-
if (!
|
|
387
|
+
if (!isPathWithinDirectory(containmentRoot.realpath, linkedRealpath)) {
|
|
297
388
|
continue;
|
|
298
389
|
}
|
|
299
390
|
try {
|
|
@@ -318,17 +409,17 @@ function scoreDocument(document, tokens, normalizedQuery, linkedCorpus, tuning)
|
|
|
318
409
|
const searchableFields = [
|
|
319
410
|
{ name: "title", value: item.title, weight: tuning.title_weight },
|
|
320
411
|
{ name: "description", value: item.description, weight: tuning.description_weight },
|
|
321
|
-
{ name: "tags", value: item.tags.join(" "), weight: tuning.tags_weight },
|
|
322
|
-
{ name: "status", value: item.status, weight: tuning.status_weight },
|
|
412
|
+
{ name: "tags", value: stringArray(item.tags).join(" "), weight: tuning.tags_weight },
|
|
413
|
+
{ name: "status", value: typeof item.status === "string" ? item.status : "", weight: tuning.status_weight },
|
|
323
414
|
{ name: "body", value: document.body, weight: tuning.body_weight },
|
|
324
|
-
{ name: "comments", value: (item.comments
|
|
325
|
-
{ name: "notes", value: (item.notes
|
|
326
|
-
{ name: "learnings", value: (item.learnings
|
|
415
|
+
{ name: "comments", value: textEntries(item.comments).map((entry) => entry.text).join(" "), weight: tuning.comments_weight },
|
|
416
|
+
{ name: "notes", value: textEntries(item.notes).map((entry) => entry.text).join(" "), weight: tuning.notes_weight },
|
|
417
|
+
{ name: "learnings", value: textEntries(item.learnings).map((entry) => entry.text).join(" "), weight: tuning.learnings_weight },
|
|
327
418
|
{ name: "reminders", value: buildReminderCorpus(item).join(" "), weight: tuning.reminders_weight },
|
|
328
419
|
{ name: "events", value: buildEventCorpus(item).join(" "), weight: tuning.events_weight },
|
|
329
420
|
{
|
|
330
421
|
name: "dependencies",
|
|
331
|
-
value: (item.dependencies
|
|
422
|
+
value: dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
|
|
332
423
|
weight: tuning.dependencies_weight,
|
|
333
424
|
},
|
|
334
425
|
{ name: "plan", value: buildPlanFlatCorpus(item), weight: tuning.body_weight },
|
|
@@ -381,8 +472,8 @@ function sortHits(items, statusRegistry) {
|
|
|
381
472
|
const byScore = b.score - a.score;
|
|
382
473
|
if (byScore !== 0)
|
|
383
474
|
return byScore;
|
|
384
|
-
const aTerminal =
|
|
385
|
-
const bTerminal =
|
|
475
|
+
const aTerminal = isTerminalStatus(a.item.status, statusRegistry);
|
|
476
|
+
const bTerminal = isTerminalStatus(b.item.status, statusRegistry);
|
|
386
477
|
if (aTerminal !== bTerminal) {
|
|
387
478
|
return aTerminal ? 1 : -1;
|
|
388
479
|
}
|
|
@@ -678,10 +769,14 @@ async function computeSemanticOrHybridHits(context) {
|
|
|
678
769
|
}
|
|
679
770
|
const filteredById = new Map(context.filteredDocuments.map((document) => [document.metadata.id, document]));
|
|
680
771
|
const { semanticHits, semanticScores } = buildSemanticHits(vectorHits, filteredById);
|
|
772
|
+
const vectorMatchCount = semanticScores.size;
|
|
681
773
|
if (context.requestedMode === "semantic") {
|
|
682
|
-
return semanticHits;
|
|
774
|
+
return { hits: semanticHits, vectorMatchCount };
|
|
683
775
|
}
|
|
684
|
-
return
|
|
776
|
+
return {
|
|
777
|
+
hits: combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight),
|
|
778
|
+
vectorMatchCount,
|
|
779
|
+
};
|
|
685
780
|
}
|
|
686
781
|
async function loadDocuments(pmRoot, itemFormat, typeToFolder, schema) {
|
|
687
782
|
const readDocumentBody = async (metadata, preferredPath, preferredFormat) => {
|
|
@@ -760,11 +855,11 @@ function readSearchFieldValue(hit, field) {
|
|
|
760
855
|
if (itemKey.length === 0) {
|
|
761
856
|
return null;
|
|
762
857
|
}
|
|
763
|
-
const itemRecord = hit.item;
|
|
858
|
+
const itemRecord = toItemRecord(hit.item);
|
|
764
859
|
return itemRecord[itemKey] ?? null;
|
|
765
860
|
}
|
|
766
861
|
const hitRecord = hit;
|
|
767
|
-
const itemRecord = hit.item;
|
|
862
|
+
const itemRecord = toItemRecord(hit.item);
|
|
768
863
|
if (Object.prototype.hasOwnProperty.call(itemRecord, normalized)) {
|
|
769
864
|
return itemRecord[normalized] ?? null;
|
|
770
865
|
}
|
|
@@ -803,6 +898,7 @@ export async function runSearch(query, options, global) {
|
|
|
803
898
|
const settings = runtimeDefaultsResolution.settings;
|
|
804
899
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
805
900
|
const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
|
|
901
|
+
validateSearchProjectionFields(projection, runtimeFieldRegistry);
|
|
806
902
|
const runtimeFieldFilters = collectRuntimeFilterValues(options, runtimeFieldRegistry, "search");
|
|
807
903
|
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
808
904
|
const maxResults = resolveSearchMaxResults(settings);
|
|
@@ -873,7 +969,7 @@ export async function runSearch(query, options, global) {
|
|
|
873
969
|
if (hits === keywordHits) {
|
|
874
970
|
const implicitHybridMode = !modeWasExplicit && effectiveMode === "hybrid";
|
|
875
971
|
const { provider, vectorStore } = requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
|
|
876
|
-
|
|
972
|
+
const semanticResult = await computeSemanticOrHybridHits({
|
|
877
973
|
requestedMode: effectiveMode,
|
|
878
974
|
query,
|
|
879
975
|
filteredDocuments,
|
|
@@ -892,16 +988,32 @@ export async function runSearch(query, options, global) {
|
|
|
892
988
|
}
|
|
893
989
|
: {}),
|
|
894
990
|
});
|
|
991
|
+
hits = semanticResult.hits;
|
|
992
|
+
// The semantic/hybrid query ran without error, but vector ranking
|
|
993
|
+
// contributed no hits for this query/filter set. Pure semantic mode would
|
|
994
|
+
// otherwise return an empty set, so degrade to the locally computed
|
|
995
|
+
// keyword hits (hybrid already blends them in) and warn so agents do not
|
|
996
|
+
// mistake them for true vector ranking. The reported mode is left
|
|
997
|
+
// unchanged; the warning is the signal.
|
|
998
|
+
if (semanticResult.vectorMatchCount === 0) {
|
|
999
|
+
if (effectiveMode === "semantic") {
|
|
1000
|
+
hits = keywordHits;
|
|
1001
|
+
}
|
|
1002
|
+
warnings.push(`search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`);
|
|
1003
|
+
}
|
|
895
1004
|
}
|
|
896
1005
|
}
|
|
897
1006
|
catch (error) {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1007
|
+
// Any semantic/hybrid attempt that fails (backend down, timeout, or the
|
|
1008
|
+
// project is not configured for semantic search) degrades to keyword mode
|
|
1009
|
+
// so agents are never blocked. Keyword hits are always computed locally
|
|
1010
|
+
// before this point, so the fallback is guaranteed to succeed.
|
|
1011
|
+
const fallbackWarning = modeWasExplicit
|
|
1012
|
+
? buildExplicitSemanticFallbackWarning(effectiveMode, error)
|
|
1013
|
+
: buildImplicitSemanticFallbackWarning(error);
|
|
902
1014
|
effectiveMode = "keyword";
|
|
903
1015
|
hits = keywordHits;
|
|
904
|
-
warnings.push(
|
|
1016
|
+
warnings.push(fallbackWarning);
|
|
905
1017
|
}
|
|
906
1018
|
}
|
|
907
1019
|
const thresholded = hits.filter((entry) => entry.score >= scoreThreshold);
|
|
@@ -941,4 +1053,4 @@ export async function runSearch(query, options, global) {
|
|
|
941
1053
|
};
|
|
942
1054
|
}
|
|
943
1055
|
//# sourceMappingURL=search.js.map
|
|
944
|
-
//# debugId=
|
|
1056
|
+
//# debugId=7b4219a0-215b-5cfa-a437-f979968a70c4
|