@unbrained/pm-cli 2026.5.30 → 2026.5.31
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 +25 -0
- package/dist/cli/commands/calendar.js +81 -9
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/create.js +34 -4
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/extension/install-sources.d.ts +2 -0
- package/dist/cli/commands/extension/install-sources.js +11 -4
- package/dist/cli/commands/extension/install-sources.js.map +1 -1
- package/dist/cli/commands/reindex.js +3 -3
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.d.ts +17 -0
- package/dist/cli/commands/search.js +40 -10
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/register-list-query.js +9 -11
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +20 -22
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +32 -25
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +6 -8
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.js +6 -3
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli/search-refresh.d.ts +2 -0
- package/dist/cli/search-refresh.js +13 -0
- package/dist/cli/search-refresh.js.map +1 -0
- package/dist/cli-bundle/chunks/activity-OWYSUZOY.js +17 -0
- package/dist/cli-bundle/chunks/activity-OWYSUZOY.js.map +7 -0
- package/dist/cli-bundle/chunks/aggregate-ADUOSFRO.js +209 -0
- package/dist/cli-bundle/chunks/aggregate-ADUOSFRO.js.map +7 -0
- package/dist/cli-bundle/chunks/append-JD2DETU7.js +73 -0
- package/dist/cli-bundle/chunks/append-JD2DETU7.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-3HUE7XOF.js +27 -0
- package/dist/cli-bundle/chunks/chunk-3HUE7XOF.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-3M73P3G6.js +1636 -0
- package/dist/cli-bundle/chunks/chunk-3M73P3G6.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-4AEZR5EJ.js +189 -0
- package/dist/cli-bundle/chunks/chunk-4AEZR5EJ.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-5HSEP75M.js +330 -0
- package/dist/cli-bundle/chunks/chunk-5HSEP75M.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-6HT2F4TK.js +1770 -0
- package/dist/cli-bundle/chunks/chunk-6HT2F4TK.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-6YCV7WSL.js +552 -0
- package/dist/cli-bundle/chunks/chunk-6YCV7WSL.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-7Y53ZJIQ.js +202 -0
- package/dist/cli-bundle/chunks/chunk-7Y53ZJIQ.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-A7E7PUVX.js +157 -0
- package/dist/cli-bundle/chunks/chunk-A7E7PUVX.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-AKOOMO3T.js +90 -0
- package/dist/cli-bundle/chunks/chunk-AKOOMO3T.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-BUPWJ3IJ.js +950 -0
- package/dist/cli-bundle/chunks/chunk-BUPWJ3IJ.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-CEFIVZPG.js +79 -0
- package/dist/cli-bundle/chunks/chunk-CEFIVZPG.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-D7AOMPRH.js +349 -0
- package/dist/cli-bundle/chunks/chunk-D7AOMPRH.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-EAOG77HM.js +56 -0
- package/dist/cli-bundle/chunks/chunk-EAOG77HM.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-EGUGFSNX.js +47 -0
- package/dist/cli-bundle/chunks/chunk-EGUGFSNX.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-FM26RGSU.js +56 -0
- package/dist/cli-bundle/chunks/chunk-FM26RGSU.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-FQE6XZDB.js +435 -0
- package/dist/cli-bundle/chunks/chunk-FQE6XZDB.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-G57E5D7T.js +185 -0
- package/dist/cli-bundle/chunks/chunk-G57E5D7T.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-GN7IJPCD.js +3621 -0
- package/dist/cli-bundle/chunks/chunk-GN7IJPCD.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-JFWUHHS2.js +233 -0
- package/dist/cli-bundle/chunks/chunk-JFWUHHS2.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-JTWRXG4B.js +1861 -0
- package/dist/cli-bundle/chunks/chunk-JTWRXG4B.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-JULRTHJQ.js +648 -0
- package/dist/cli-bundle/chunks/chunk-JULRTHJQ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-PB2YU2E3.js → chunk-KBQY3YG5.js} +28 -70
- package/dist/cli-bundle/chunks/chunk-KBQY3YG5.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-L2FXEKDB.js +185 -0
- package/dist/cli-bundle/chunks/chunk-L2FXEKDB.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-LRBOHPUE.js +189 -0
- package/dist/cli-bundle/chunks/chunk-LRBOHPUE.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-LSXGH6NE.js +5153 -0
- package/dist/cli-bundle/chunks/chunk-LSXGH6NE.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-MD7K4JYF.js +1345 -0
- package/dist/cli-bundle/chunks/chunk-MD7K4JYF.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-NGN7UV5K.js +341 -0
- package/dist/cli-bundle/chunks/chunk-NGN7UV5K.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-O7IWB35H.js +18 -0
- package/dist/cli-bundle/chunks/chunk-O7IWB35H.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-OGZEG5TT.js +2929 -0
- package/dist/cli-bundle/chunks/chunk-OGZEG5TT.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RJONRNXN.js → chunk-P53TN6IA.js} +22 -30
- package/dist/cli-bundle/chunks/chunk-P53TN6IA.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-PVNQLCIS.js +176 -0
- package/dist/cli-bundle/chunks/chunk-PVNQLCIS.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-PXUAZUUY.js +1680 -0
- package/dist/cli-bundle/chunks/chunk-PXUAZUUY.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-QAJBIGRA.js +20 -0
- package/dist/cli-bundle/chunks/chunk-QAJBIGRA.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-SEXQN4KL.js +60 -0
- package/dist/cli-bundle/chunks/chunk-SEXQN4KL.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-U7FMKRXH.js +362 -0
- package/dist/cli-bundle/chunks/chunk-U7FMKRXH.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-VGICHR7D.js +141 -0
- package/dist/cli-bundle/chunks/chunk-VGICHR7D.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-WDPXDQFG.js +632 -0
- package/dist/cli-bundle/chunks/chunk-WDPXDQFG.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-WJ2NAC37.js +252 -0
- package/dist/cli-bundle/chunks/chunk-WJ2NAC37.js.map +7 -0
- package/dist/cli-bundle/chunks/claim-EE4TKKCV.js +133 -0
- package/dist/cli-bundle/chunks/claim-EE4TKKCV.js.map +7 -0
- package/dist/cli-bundle/chunks/close-XY4CSAYF.js +14 -0
- package/dist/cli-bundle/chunks/close-XY4CSAYF.js.map +7 -0
- package/dist/cli-bundle/chunks/comments-AAKJQ6LW.js +104 -0
- package/dist/cli-bundle/chunks/comments-AAKJQ6LW.js.map +7 -0
- package/dist/cli-bundle/chunks/config-V3FZOKLI.js +1577 -0
- package/dist/cli-bundle/chunks/config-V3FZOKLI.js.map +7 -0
- package/dist/cli-bundle/chunks/context-RZ5QPNJB.js +1458 -0
- package/dist/cli-bundle/chunks/context-RZ5QPNJB.js.map +7 -0
- package/dist/cli-bundle/chunks/contracts-YLMH33VU.js +1245 -0
- package/dist/cli-bundle/chunks/contracts-YLMH33VU.js.map +7 -0
- package/dist/cli-bundle/chunks/create-PZVHRIZQ.js +28 -0
- package/dist/cli-bundle/chunks/create-PZVHRIZQ.js.map +7 -0
- package/dist/cli-bundle/chunks/delete-RHCTEORS.js +59 -0
- package/dist/cli-bundle/chunks/delete-RHCTEORS.js.map +7 -0
- package/dist/cli-bundle/chunks/deps-MZYCMLAO.js +229 -0
- package/dist/cli-bundle/chunks/deps-MZYCMLAO.js.map +7 -0
- package/dist/cli-bundle/chunks/docs-FXXUCZYU.js +35 -0
- package/dist/cli-bundle/chunks/docs-FXXUCZYU.js.map +7 -0
- package/dist/cli-bundle/chunks/extension-B4WL7BQU.js +25 -0
- package/dist/cli-bundle/chunks/extension-B4WL7BQU.js.map +7 -0
- package/dist/cli-bundle/chunks/files-WVOX67PE.js +286 -0
- package/dist/cli-bundle/chunks/files-WVOX67PE.js.map +7 -0
- package/dist/cli-bundle/chunks/gc-JWNF66EC.js +181 -0
- package/dist/cli-bundle/chunks/gc-JWNF66EC.js.map +7 -0
- package/dist/cli-bundle/chunks/get-LTK3HOCQ.js +198 -0
- package/dist/cli-bundle/chunks/get-LTK3HOCQ.js.map +7 -0
- package/dist/cli-bundle/chunks/health-TCWL55KM.js +1233 -0
- package/dist/cli-bundle/chunks/health-TCWL55KM.js.map +7 -0
- package/dist/cli-bundle/chunks/history-A2JUDXUE.js +21 -0
- package/dist/cli-bundle/chunks/history-A2JUDXUE.js.map +7 -0
- package/dist/cli-bundle/chunks/history-redact-ED6RFCPL.js +20 -0
- package/dist/cli-bundle/chunks/history-redact-ED6RFCPL.js.map +7 -0
- package/dist/cli-bundle/chunks/history-repair-ZWSTDRH2.js +198 -0
- package/dist/cli-bundle/chunks/history-repair-ZWSTDRH2.js.map +7 -0
- package/dist/cli-bundle/chunks/init-M2WUB4YH.js +16 -0
- package/dist/cli-bundle/chunks/init-M2WUB4YH.js.map +7 -0
- package/dist/cli-bundle/chunks/learnings-NXTWE3FR.js +48 -0
- package/dist/cli-bundle/chunks/learnings-NXTWE3FR.js.map +7 -0
- package/dist/cli-bundle/chunks/list-OGWQPC26.js +20 -0
- package/dist/cli-bundle/chunks/list-OGWQPC26.js.map +7 -0
- package/dist/cli-bundle/chunks/notes-DFS5ZGOO.js +48 -0
- package/dist/cli-bundle/chunks/notes-DFS5ZGOO.js.map +7 -0
- package/dist/cli-bundle/chunks/plan-67AB2PLM.js +1175 -0
- package/dist/cli-bundle/chunks/plan-67AB2PLM.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-list-query-EIVQ5FMR.js → register-list-query-UP3VRUFS.js} +24 -15
- package/dist/cli-bundle/chunks/register-list-query-UP3VRUFS.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-RSZNPSGI.js → register-mutation-YWSBF545.js} +38 -28
- package/dist/cli-bundle/chunks/register-mutation-YWSBF545.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-operations-APUSYDMR.js → register-operations-3BDTGSDH.js} +49 -30
- package/dist/cli-bundle/chunks/register-operations-3BDTGSDH.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-setup-OZOKSMPJ.js → register-setup-V56GDRUS.js} +21 -12
- package/dist/cli-bundle/chunks/register-setup-V56GDRUS.js.map +7 -0
- package/dist/cli-bundle/chunks/restore-MB2ISME7.js +18 -0
- package/dist/cli-bundle/chunks/restore-MB2ISME7.js.map +7 -0
- package/dist/cli-bundle/chunks/schema-Q622KC46.js +119 -0
- package/dist/cli-bundle/chunks/schema-Q622KC46.js.map +7 -0
- package/dist/cli-bundle/chunks/search-HENBL456.js +1135 -0
- package/dist/cli-bundle/chunks/search-HENBL456.js.map +7 -0
- package/dist/cli-bundle/chunks/stats-N6H3YP2F.js +124 -0
- package/dist/cli-bundle/chunks/stats-N6H3YP2F.js.map +7 -0
- package/dist/cli-bundle/chunks/test-VNBDRJ4Z.js +32 -0
- package/dist/cli-bundle/chunks/test-VNBDRJ4Z.js.map +7 -0
- package/dist/cli-bundle/chunks/test-all-G2AZOHXI.js +332 -0
- package/dist/cli-bundle/chunks/test-all-G2AZOHXI.js.map +7 -0
- package/dist/cli-bundle/chunks/test-runs-GX5HTPSF.js +939 -0
- package/dist/cli-bundle/chunks/test-runs-GX5HTPSF.js.map +7 -0
- package/dist/cli-bundle/chunks/update-H6SCWNMA.js +22 -0
- package/dist/cli-bundle/chunks/update-H6SCWNMA.js.map +7 -0
- package/dist/cli-bundle/chunks/update-many-46HRSP2Q.js +676 -0
- package/dist/cli-bundle/chunks/update-many-46HRSP2Q.js.map +7 -0
- package/dist/cli-bundle/chunks/upgrade-H5HHM5UV.js +271 -0
- package/dist/cli-bundle/chunks/upgrade-H5HHM5UV.js.map +7 -0
- package/dist/cli-bundle/chunks/validate-TMCVKIGZ.js +1110 -0
- package/dist/cli-bundle/chunks/validate-TMCVKIGZ.js.map +7 -0
- package/dist/cli-bundle/main.js +146 -90
- package/dist/cli-bundle/main.js.map +4 -4
- package/dist/core/item/item-type-definition.js +6 -2
- package/dist/core/item/item-type-definition.js.map +1 -1
- package/dist/core/item/type-registry.d.ts +4 -0
- package/dist/core/item/type-registry.js +10 -2
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/search/background-refresh.d.ts +53 -0
- package/dist/core/search/background-refresh.js +286 -0
- package/dist/core/search/background-refresh.js.map +1 -0
- package/dist/core/search/cache.d.ts +20 -1
- package/dist/core/search/cache.js +33 -4
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/search/vector-stores.js +7 -3
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/shared/constants.d.ts +2 -2
- package/dist/core/shared/constants.js +2 -3
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/store/item-format-migration.js +25 -15
- package/dist/core/store/item-format-migration.js.map +1 -1
- package/dist/core/store/settings-validator.js +6 -2
- package/dist/core/store/settings-validator.js.map +1 -1
- package/dist/core/telemetry/runtime.d.ts +10 -0
- package/dist/core/telemetry/runtime.js +86 -2
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +4 -4
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts.js +26 -5
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/types.d.ts +7 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/docs/RELEASING.md +1 -1
- package/package.json +1 -2
- package/dist/cli-bundle/chunks/chunk-PB2YU2E3.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RJONRNXN.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SW5BMMCU.js +0 -13864
- package/dist/cli-bundle/chunks/chunk-SW5BMMCU.js.map +0 -7
- package/dist/cli-bundle/chunks/commands-XJ4TJ5UN.js +0 -24225
- package/dist/cli-bundle/chunks/commands-XJ4TJ5UN.js.map +0 -7
- package/dist/cli-bundle/chunks/register-list-query-EIVQ5FMR.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-RSZNPSGI.js.map +0 -7
- package/dist/cli-bundle/chunks/register-operations-APUSYDMR.js.map +0 -7
- package/dist/cli-bundle/chunks/register-setup-OZOKSMPJ.js.map +0 -7
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collectStaleVectorizationIds
|
|
3
|
+
} from "./chunk-QAJBIGRA.js";
|
|
4
|
+
import {
|
|
5
|
+
buildEventCorpus,
|
|
6
|
+
buildPlanFlatCorpus,
|
|
7
|
+
buildReminderCorpus,
|
|
8
|
+
executeEmbeddingRequest,
|
|
9
|
+
executeVectorQuery,
|
|
10
|
+
readVectorizationStatusLedger,
|
|
11
|
+
resolveEmbeddingProviders,
|
|
12
|
+
resolveSettingsWithSemanticRuntimeDefaults,
|
|
13
|
+
resolveVectorStores
|
|
14
|
+
} from "./chunk-6HT2F4TK.js";
|
|
15
|
+
import "./chunk-EGUGFSNX.js";
|
|
16
|
+
import {
|
|
17
|
+
collectRuntimeFilterValues,
|
|
18
|
+
matchesRuntimeFilters
|
|
19
|
+
} from "./chunk-FM26RGSU.js";
|
|
20
|
+
import {
|
|
21
|
+
parseLimit,
|
|
22
|
+
parsePriority,
|
|
23
|
+
parseType
|
|
24
|
+
} from "./chunk-SEXQN4KL.js";
|
|
25
|
+
import {
|
|
26
|
+
listAllDocumentCandidatesCached,
|
|
27
|
+
listAllFrontMatter,
|
|
28
|
+
toItemRecord
|
|
29
|
+
} from "./chunk-BUPWJ3IJ.js";
|
|
30
|
+
import "./chunk-4AEZR5EJ.js";
|
|
31
|
+
import "./chunk-CEFIVZPG.js";
|
|
32
|
+
import {
|
|
33
|
+
isTerminalStatus,
|
|
34
|
+
parseItemDocument
|
|
35
|
+
} from "./chunk-MD7K4JYF.js";
|
|
36
|
+
import {
|
|
37
|
+
resolveItemTypeRegistry
|
|
38
|
+
} from "./chunk-WDPXDQFG.js";
|
|
39
|
+
import {
|
|
40
|
+
compareTimestampStrings,
|
|
41
|
+
nowIso,
|
|
42
|
+
resolveIsoOrRelative
|
|
43
|
+
} from "./chunk-PVNQLCIS.js";
|
|
44
|
+
import {
|
|
45
|
+
EXIT_CODE,
|
|
46
|
+
PmCliError,
|
|
47
|
+
getActiveExtensionRegistrations,
|
|
48
|
+
getItemPath,
|
|
49
|
+
getSettingsPath,
|
|
50
|
+
isPathWithinDirectory,
|
|
51
|
+
pathExists,
|
|
52
|
+
readSettings,
|
|
53
|
+
resolveGlobalPmRoot,
|
|
54
|
+
resolvePmRoot,
|
|
55
|
+
resolveRuntimeFieldRegistry,
|
|
56
|
+
resolveRuntimeStatusRegistry,
|
|
57
|
+
runActiveOnReadHooks,
|
|
58
|
+
toNonEmptyStringOrUndefined
|
|
59
|
+
} from "./chunk-LSXGH6NE.js";
|
|
60
|
+
|
|
61
|
+
// dist/cli/commands/search.js
|
|
62
|
+
import fs from "node:fs/promises";
|
|
63
|
+
import path from "node:path";
|
|
64
|
+
|
|
65
|
+
// dist/core/extensions/runtime-registrations.js
|
|
66
|
+
!(function() {
|
|
67
|
+
try {
|
|
68
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
69
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "0eb4f7df-9f0e-5e86-9802-1490f5a73f6e");
|
|
70
|
+
} catch (e2) {
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
function normalizeRegistrationName(value) {
|
|
74
|
+
if (typeof value !== "string") {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const normalized = value.trim().toLowerCase();
|
|
78
|
+
return normalized.length > 0 ? normalized : null;
|
|
79
|
+
}
|
|
80
|
+
function resolveRegisteredSearchProvider(registrations, configuredProvider) {
|
|
81
|
+
const providerName = normalizeRegistrationName(configuredProvider);
|
|
82
|
+
if (!registrations || !providerName) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const matched = [...registrations.search_providers].reverse().find((registration) => {
|
|
86
|
+
const definitionName = normalizeRegistrationName(registration.runtime_definition?.name) ?? normalizeRegistrationName(registration.definition?.name);
|
|
87
|
+
return definitionName === providerName;
|
|
88
|
+
});
|
|
89
|
+
return matched ?? null;
|
|
90
|
+
}
|
|
91
|
+
function resolveRegisteredVectorStoreAdapter(registrations, configuredAdapter) {
|
|
92
|
+
const adapterName = normalizeRegistrationName(configuredAdapter);
|
|
93
|
+
if (!registrations || !adapterName) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const matched = [...registrations.vector_store_adapters].reverse().find((registration) => {
|
|
97
|
+
const definitionName = normalizeRegistrationName(registration.runtime_definition?.name) ?? normalizeRegistrationName(registration.definition?.name);
|
|
98
|
+
return definitionName === adapterName;
|
|
99
|
+
});
|
|
100
|
+
return matched ?? null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// dist/core/shared/text-normalization.js
|
|
104
|
+
!(function() {
|
|
105
|
+
try {
|
|
106
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
107
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "1109b938-c421-5517-9671-2cebd7e10309");
|
|
108
|
+
} catch (e2) {
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
111
|
+
function normalizeLowercaseWhitespace(value) {
|
|
112
|
+
return value.trim().toLowerCase().replace(/\s+/g, " ");
|
|
113
|
+
}
|
|
114
|
+
function tokenizeAlphaNumeric(value) {
|
|
115
|
+
return normalizeLowercaseWhitespace(value).split(/[^a-z0-9]+/).filter((token) => token.length > 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// dist/cli/commands/search.js
|
|
119
|
+
!(function() {
|
|
120
|
+
try {
|
|
121
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
122
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "22bb189d-1bb3-5ce3-8b8a-d64dcb0b6c02");
|
|
123
|
+
} catch (e2) {
|
|
124
|
+
}
|
|
125
|
+
})();
|
|
126
|
+
var DEFAULT_COMPACT_SEARCH_FIELDS = [
|
|
127
|
+
"id",
|
|
128
|
+
"title",
|
|
129
|
+
"status",
|
|
130
|
+
"type",
|
|
131
|
+
"priority",
|
|
132
|
+
"updated_at",
|
|
133
|
+
"score",
|
|
134
|
+
"matched_fields"
|
|
135
|
+
];
|
|
136
|
+
var SEARCH_HIT_FIELD_KEYS = /* @__PURE__ */ new Set(["score", "matched_fields"]);
|
|
137
|
+
var SEARCH_ITEM_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
138
|
+
"id",
|
|
139
|
+
"title",
|
|
140
|
+
"description",
|
|
141
|
+
"type",
|
|
142
|
+
"status",
|
|
143
|
+
"priority",
|
|
144
|
+
"tags",
|
|
145
|
+
"created_at",
|
|
146
|
+
"updated_at",
|
|
147
|
+
"deadline",
|
|
148
|
+
"assignee",
|
|
149
|
+
"author",
|
|
150
|
+
"estimated_minutes",
|
|
151
|
+
"acceptance_criteria",
|
|
152
|
+
"dependencies",
|
|
153
|
+
"comments",
|
|
154
|
+
"notes",
|
|
155
|
+
"learnings",
|
|
156
|
+
"reminders",
|
|
157
|
+
"events",
|
|
158
|
+
"files",
|
|
159
|
+
"tests",
|
|
160
|
+
"docs",
|
|
161
|
+
"close_reason",
|
|
162
|
+
"parent",
|
|
163
|
+
"reviewer",
|
|
164
|
+
"risk",
|
|
165
|
+
"confidence",
|
|
166
|
+
"sprint",
|
|
167
|
+
"release",
|
|
168
|
+
"blocked_by",
|
|
169
|
+
"blocked_reason",
|
|
170
|
+
"reporter",
|
|
171
|
+
"severity",
|
|
172
|
+
"environment",
|
|
173
|
+
"repro_steps",
|
|
174
|
+
"resolution",
|
|
175
|
+
"expected_result",
|
|
176
|
+
"actual_result",
|
|
177
|
+
"affected_version",
|
|
178
|
+
"fixed_version",
|
|
179
|
+
"component",
|
|
180
|
+
"regression",
|
|
181
|
+
"customer_impact",
|
|
182
|
+
"definition_of_ready",
|
|
183
|
+
"order",
|
|
184
|
+
"rank",
|
|
185
|
+
"goal",
|
|
186
|
+
"objective",
|
|
187
|
+
"value",
|
|
188
|
+
"impact",
|
|
189
|
+
"outcome",
|
|
190
|
+
"why_now",
|
|
191
|
+
"plan"
|
|
192
|
+
]);
|
|
193
|
+
var LONG_QUERY_TOKEN_THRESHOLD = 2;
|
|
194
|
+
var LONG_QUERY_TITLE_EXACT_BONUS = 120;
|
|
195
|
+
var LONG_QUERY_PHRASE_MULTIPLIER = 6;
|
|
196
|
+
var IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS = 8e3;
|
|
197
|
+
var IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS = 8e3;
|
|
198
|
+
function collectErrorCauseCodes(error) {
|
|
199
|
+
const codes = [];
|
|
200
|
+
let current = error;
|
|
201
|
+
for (let depth = 0; depth < 5 && current && typeof current === "object"; depth += 1) {
|
|
202
|
+
const code = current.code;
|
|
203
|
+
if (typeof code === "string") {
|
|
204
|
+
codes.push(code.toLowerCase());
|
|
205
|
+
}
|
|
206
|
+
current = current.cause;
|
|
207
|
+
}
|
|
208
|
+
return codes.join(" ");
|
|
209
|
+
}
|
|
210
|
+
function classifyImplicitSemanticFallbackReason(error) {
|
|
211
|
+
const message = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
212
|
+
const causeCodes = collectErrorCauseCodes(error);
|
|
213
|
+
const haystack = `${message} ${causeCodes}`;
|
|
214
|
+
if (haystack.includes("timed out") || haystack.includes("timeout") || haystack.includes("etimedout")) {
|
|
215
|
+
return "timeout";
|
|
216
|
+
}
|
|
217
|
+
if (haystack.includes("econnrefused") || haystack.includes("connection refused") || haystack.includes("connect ") || haystack.includes("enotfound") || haystack.includes("eai_again") || haystack.includes("econnreset") || haystack.includes("fetch failed")) {
|
|
218
|
+
return "connection";
|
|
219
|
+
}
|
|
220
|
+
return "error";
|
|
221
|
+
}
|
|
222
|
+
function buildImplicitSemanticFallbackWarning(error) {
|
|
223
|
+
const reason = classifyImplicitSemanticFallbackReason(error);
|
|
224
|
+
if (reason === "timeout") {
|
|
225
|
+
return "search_implicit_semantic_fallback:timeout:using_keyword_mode";
|
|
226
|
+
}
|
|
227
|
+
if (reason === "connection") {
|
|
228
|
+
return "search_implicit_semantic_fallback:connection:using_keyword_mode";
|
|
229
|
+
}
|
|
230
|
+
return "search_implicit_semantic_fallback:error:using_keyword_mode";
|
|
231
|
+
}
|
|
232
|
+
function buildExplicitSemanticFallbackWarning(requestedMode, error) {
|
|
233
|
+
const reason = classifyImplicitSemanticFallbackReason(error);
|
|
234
|
+
return `search_${requestedMode}_fallback:${reason}:using_keyword_mode`;
|
|
235
|
+
}
|
|
236
|
+
async function maybeEmitVectorIndexStaleWarning(pmRoot, filteredDocuments, warnings) {
|
|
237
|
+
try {
|
|
238
|
+
const ledger = await readVectorizationStatusLedger(pmRoot);
|
|
239
|
+
if (ledger.warnings.length > 0) {
|
|
240
|
+
warnings.push(...ledger.warnings);
|
|
241
|
+
}
|
|
242
|
+
const staleIds = collectStaleVectorizationIds(filteredDocuments.map((document) => ({
|
|
243
|
+
id: document.metadata.id,
|
|
244
|
+
updated_at: document.metadata.updated_at
|
|
245
|
+
})), ledger.entries);
|
|
246
|
+
if (staleIds.length === 0) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
warnings.push(`vector_index_stale:${staleIds.length}`);
|
|
250
|
+
process.stderr.write(`[pm] warning: ${staleIds.length} item${staleIds.length === 1 ? " is" : "s are"} new or modified since the last reindex and ${staleIds.length === 1 ? "is" : "are"} NOT in the semantic index yet \u2014 they will be missing from semantic/hybrid results until you run 'pm reindex --mode hybrid'. (Write-time embedding is governed by search.mutation_refresh_policy; staleness means the embed was skipped, failed, or the backend was unreachable.)
|
|
251
|
+
`);
|
|
252
|
+
} catch {
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function parseMode(raw, _context) {
|
|
256
|
+
if (raw === void 0) {
|
|
257
|
+
return "keyword";
|
|
258
|
+
}
|
|
259
|
+
const normalized = raw.trim().toLowerCase();
|
|
260
|
+
if (normalized !== "keyword" && normalized !== "semantic" && normalized !== "hybrid") {
|
|
261
|
+
throw new PmCliError("Search mode must be one of keyword|semantic|hybrid", EXIT_CODE.USAGE);
|
|
262
|
+
}
|
|
263
|
+
return normalized;
|
|
264
|
+
}
|
|
265
|
+
function parseIncludeLinked(raw) {
|
|
266
|
+
return raw === true;
|
|
267
|
+
}
|
|
268
|
+
function parseTitleExact(raw) {
|
|
269
|
+
return raw === true;
|
|
270
|
+
}
|
|
271
|
+
function parsePhraseExact(raw) {
|
|
272
|
+
return raw === true;
|
|
273
|
+
}
|
|
274
|
+
function normalizeSearchPhrase(value) {
|
|
275
|
+
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
276
|
+
}
|
|
277
|
+
function parseDeadline(raw, fieldLabel) {
|
|
278
|
+
if (raw === void 0)
|
|
279
|
+
return void 0;
|
|
280
|
+
return resolveIsoOrRelative(raw, /* @__PURE__ */ new Date(), fieldLabel);
|
|
281
|
+
}
|
|
282
|
+
function parseFieldSelectors(raw) {
|
|
283
|
+
if (raw === void 0) {
|
|
284
|
+
return void 0;
|
|
285
|
+
}
|
|
286
|
+
const selectors = raw.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
287
|
+
if (selectors.length === 0) {
|
|
288
|
+
throw new PmCliError("Search --fields requires a comma-separated list of field names", EXIT_CODE.USAGE);
|
|
289
|
+
}
|
|
290
|
+
return [...new Set(selectors)];
|
|
291
|
+
}
|
|
292
|
+
function parseProjectionConfig(options) {
|
|
293
|
+
const compactRequested = options.compact === true;
|
|
294
|
+
const fullRequested = options.full === true;
|
|
295
|
+
const fieldSelectors = parseFieldSelectors(options.fields);
|
|
296
|
+
const enabledModes = Number(compactRequested) + Number(fullRequested) + Number(fieldSelectors !== void 0);
|
|
297
|
+
if (enabledModes > 1) {
|
|
298
|
+
throw new PmCliError("Search projection options are mutually exclusive. Use one of --compact, --full, or --fields.", EXIT_CODE.USAGE);
|
|
299
|
+
}
|
|
300
|
+
if (compactRequested) {
|
|
301
|
+
return {
|
|
302
|
+
mode: "compact",
|
|
303
|
+
fields: [...DEFAULT_COMPACT_SEARCH_FIELDS]
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
if (fullRequested) {
|
|
307
|
+
return {
|
|
308
|
+
mode: "full",
|
|
309
|
+
fields: []
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
if (fieldSelectors) {
|
|
313
|
+
return {
|
|
314
|
+
mode: "fields",
|
|
315
|
+
fields: fieldSelectors
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
mode: "full",
|
|
320
|
+
fields: []
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function validateSearchProjectionFields(projection, runtimeFieldRegistry) {
|
|
324
|
+
if (projection.mode !== "fields") {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const runtimeKeys = new Set(runtimeFieldRegistry.definitions.flatMap((field) => [field.key, field.metadata_key]));
|
|
328
|
+
const unknown = projection.fields.filter((field) => {
|
|
329
|
+
const normalized = field.trim();
|
|
330
|
+
const itemKey = normalized.startsWith("item.") ? normalized.slice("item.".length) : normalized;
|
|
331
|
+
return !SEARCH_HIT_FIELD_KEYS.has(normalized) && !SEARCH_ITEM_FIELD_KEYS.has(itemKey) && !runtimeKeys.has(itemKey);
|
|
332
|
+
});
|
|
333
|
+
if (unknown.length > 0) {
|
|
334
|
+
throw new PmCliError(`Unknown search --fields value(s): ${unknown.join(", ")}`, EXIT_CODE.USAGE, {
|
|
335
|
+
examples: [
|
|
336
|
+
"pm search <query> --fields id,title,status,score",
|
|
337
|
+
"pm search <query> --fields id,title,item.description,matched_fields"
|
|
338
|
+
],
|
|
339
|
+
nextSteps: ["Use item.<field> for explicit item metadata fields, or run pm search --help for projection examples."]
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function parseTokens(query) {
|
|
344
|
+
const normalized = normalizeSearchPhrase(query);
|
|
345
|
+
if (!normalized) {
|
|
346
|
+
throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
|
|
347
|
+
}
|
|
348
|
+
return normalized.split(/\s+/).filter(Boolean);
|
|
349
|
+
}
|
|
350
|
+
function stringArray(value) {
|
|
351
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
352
|
+
}
|
|
353
|
+
function textEntries(value) {
|
|
354
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.text === "string") : [];
|
|
355
|
+
}
|
|
356
|
+
function dependencyEntries(value) {
|
|
357
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string" && typeof entry.kind === "string") : [];
|
|
358
|
+
}
|
|
359
|
+
function collectExactPhraseFields(document) {
|
|
360
|
+
const item = document.metadata;
|
|
361
|
+
return [
|
|
362
|
+
item.title,
|
|
363
|
+
item.description,
|
|
364
|
+
item.status,
|
|
365
|
+
stringArray(item.tags).join(" "),
|
|
366
|
+
document.body,
|
|
367
|
+
textEntries(item.comments).map((entry) => entry.text).join(" "),
|
|
368
|
+
textEntries(item.notes).map((entry) => entry.text).join(" "),
|
|
369
|
+
textEntries(item.learnings).map((entry) => entry.text).join(" "),
|
|
370
|
+
buildReminderCorpus(item).join(" "),
|
|
371
|
+
buildEventCorpus(item).join(" "),
|
|
372
|
+
dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
|
|
373
|
+
buildPlanFlatCorpus(item)
|
|
374
|
+
];
|
|
375
|
+
}
|
|
376
|
+
function documentContainsExactPhrase(document, normalizedQuery) {
|
|
377
|
+
return collectExactPhraseFields(document).some((fieldValue) => normalizeSearchPhrase(fieldValue).includes(normalizedQuery));
|
|
378
|
+
}
|
|
379
|
+
function applyExactQueryFilters(items, normalizedQuery, options) {
|
|
380
|
+
if (!options.titleExact && !options.phraseExact) {
|
|
381
|
+
return items;
|
|
382
|
+
}
|
|
383
|
+
return items.filter((document) => {
|
|
384
|
+
if (options.titleExact && normalizeSearchPhrase(document.metadata.title) !== normalizedQuery) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
if (options.phraseExact && !documentContainsExactPhrase(document, normalizedQuery)) {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
return true;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function applyFilters(items, options, typeRegistry, runtimeFieldFilters) {
|
|
394
|
+
const typeFilter = parseType(options.type, typeRegistry);
|
|
395
|
+
const tagFilter = options.tag?.trim().toLowerCase();
|
|
396
|
+
const priorityFilter = parsePriority(options.priority);
|
|
397
|
+
const deadlineBefore = parseDeadline(options.deadlineBefore, "deadline-before");
|
|
398
|
+
const deadlineAfter = parseDeadline(options.deadlineAfter, "deadline-after");
|
|
399
|
+
return items.filter((document) => {
|
|
400
|
+
const item = document.metadata;
|
|
401
|
+
if (typeFilter && item.type !== typeFilter)
|
|
402
|
+
return false;
|
|
403
|
+
if (tagFilter && !stringArray(item.tags).includes(tagFilter))
|
|
404
|
+
return false;
|
|
405
|
+
if (priorityFilter !== void 0 && item.priority !== priorityFilter)
|
|
406
|
+
return false;
|
|
407
|
+
if (deadlineBefore && (!item.deadline || compareTimestampStrings(item.deadline, deadlineBefore) > 0))
|
|
408
|
+
return false;
|
|
409
|
+
if (deadlineAfter && (!item.deadline || compareTimestampStrings(item.deadline, deadlineAfter) < 0))
|
|
410
|
+
return false;
|
|
411
|
+
if (!matchesRuntimeFilters(item, runtimeFieldFilters))
|
|
412
|
+
return false;
|
|
413
|
+
return true;
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
function countOccurrences(haystack, needle) {
|
|
417
|
+
let count = 0;
|
|
418
|
+
let index = 0;
|
|
419
|
+
while (true) {
|
|
420
|
+
const foundAt = haystack.indexOf(needle, index);
|
|
421
|
+
if (foundAt < 0) {
|
|
422
|
+
return count;
|
|
423
|
+
}
|
|
424
|
+
count += 1;
|
|
425
|
+
index = foundAt + needle.length;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function tokenizeForExactTokenMatch(value) {
|
|
429
|
+
return tokenizeAlphaNumeric(value);
|
|
430
|
+
}
|
|
431
|
+
function collectLinkedPaths(item) {
|
|
432
|
+
const fromFiles = (item.files ?? []).map((entry) => ({
|
|
433
|
+
scope: entry.scope,
|
|
434
|
+
path: entry.path.trim()
|
|
435
|
+
}));
|
|
436
|
+
const fromDocs = (item.docs ?? []).map((entry) => ({
|
|
437
|
+
scope: entry.scope,
|
|
438
|
+
path: entry.path.trim()
|
|
439
|
+
}));
|
|
440
|
+
const fromTests = (item.tests ?? []).filter((entry) => typeof entry.path === "string" && entry.path.trim().length > 0).map((entry) => ({
|
|
441
|
+
scope: entry.scope,
|
|
442
|
+
path: entry.path.trim()
|
|
443
|
+
}));
|
|
444
|
+
const sorted = [...fromFiles, ...fromDocs, ...fromTests].filter((entry) => entry.path.length > 0).sort((a, b) => a.scope.localeCompare(b.scope) || a.path.localeCompare(b.path));
|
|
445
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
446
|
+
for (const entry of sorted) {
|
|
447
|
+
deduped.set(`${entry.scope}:${entry.path}`, entry);
|
|
448
|
+
}
|
|
449
|
+
return [...deduped.values()];
|
|
450
|
+
}
|
|
451
|
+
async function resolveContainmentRoot(root) {
|
|
452
|
+
const resolved = path.resolve(root);
|
|
453
|
+
try {
|
|
454
|
+
const realpathRoot = await fs.realpath(resolved);
|
|
455
|
+
return {
|
|
456
|
+
resolved,
|
|
457
|
+
realpath: realpathRoot
|
|
458
|
+
};
|
|
459
|
+
} catch {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async function resolveLinkedCorpusRoots(projectRoot, globalRoot) {
|
|
464
|
+
const [projectContainmentRoot, globalContainmentRoot] = await Promise.all([
|
|
465
|
+
resolveContainmentRoot(projectRoot),
|
|
466
|
+
resolveContainmentRoot(globalRoot)
|
|
467
|
+
]);
|
|
468
|
+
return {
|
|
469
|
+
projectContainmentRoot,
|
|
470
|
+
globalContainmentRoot
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
async function loadLinkedCorpus(document, roots) {
|
|
474
|
+
const linkedPaths = collectLinkedPaths(document.metadata);
|
|
475
|
+
const chunks = [];
|
|
476
|
+
for (const linkedPath of linkedPaths) {
|
|
477
|
+
const containmentRoot = linkedPath.scope === "global" ? roots.globalContainmentRoot : roots.projectContainmentRoot;
|
|
478
|
+
if (!containmentRoot) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
const resolved = path.resolve(containmentRoot.resolved, linkedPath.path);
|
|
482
|
+
if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
let linkedRealpath;
|
|
486
|
+
try {
|
|
487
|
+
linkedRealpath = await fs.realpath(resolved);
|
|
488
|
+
} catch {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
if (!isPathWithinDirectory(containmentRoot.realpath, linkedRealpath)) {
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
await runActiveOnReadHooks({
|
|
496
|
+
path: resolved,
|
|
497
|
+
scope: linkedPath.scope
|
|
498
|
+
});
|
|
499
|
+
chunks.push(await fs.readFile(resolved, "utf8"));
|
|
500
|
+
} catch {
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return chunks.join("\n");
|
|
504
|
+
}
|
|
505
|
+
function scoreDocument(document, tokens, normalizedQuery, linkedCorpus, tuning) {
|
|
506
|
+
const item = document.metadata;
|
|
507
|
+
const titleTokenCounts = /* @__PURE__ */ new Map();
|
|
508
|
+
for (const token of tokenizeForExactTokenMatch(item.title)) {
|
|
509
|
+
titleTokenCounts.set(token, (titleTokenCounts.get(token) ?? 0) + 1);
|
|
510
|
+
}
|
|
511
|
+
const searchableFields = [
|
|
512
|
+
{ name: "title", value: item.title, weight: tuning.title_weight },
|
|
513
|
+
{ name: "description", value: item.description, weight: tuning.description_weight },
|
|
514
|
+
{ name: "tags", value: stringArray(item.tags).join(" "), weight: tuning.tags_weight },
|
|
515
|
+
{ name: "status", value: typeof item.status === "string" ? item.status : "", weight: tuning.status_weight },
|
|
516
|
+
{ name: "body", value: document.body, weight: tuning.body_weight },
|
|
517
|
+
{ name: "comments", value: textEntries(item.comments).map((entry) => entry.text).join(" "), weight: tuning.comments_weight },
|
|
518
|
+
{ name: "notes", value: textEntries(item.notes).map((entry) => entry.text).join(" "), weight: tuning.notes_weight },
|
|
519
|
+
{ name: "learnings", value: textEntries(item.learnings).map((entry) => entry.text).join(" "), weight: tuning.learnings_weight },
|
|
520
|
+
{ name: "reminders", value: buildReminderCorpus(item).join(" "), weight: tuning.reminders_weight },
|
|
521
|
+
{ name: "events", value: buildEventCorpus(item).join(" "), weight: tuning.events_weight },
|
|
522
|
+
{
|
|
523
|
+
name: "dependencies",
|
|
524
|
+
value: dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
|
|
525
|
+
weight: tuning.dependencies_weight
|
|
526
|
+
},
|
|
527
|
+
{ name: "plan", value: buildPlanFlatCorpus(item), weight: tuning.body_weight },
|
|
528
|
+
{ name: "linked_content", value: linkedCorpus, weight: tuning.linked_content_weight }
|
|
529
|
+
];
|
|
530
|
+
let score = 0;
|
|
531
|
+
const matched = /* @__PURE__ */ new Set();
|
|
532
|
+
for (const token of tokens) {
|
|
533
|
+
const exactTitleMatches = titleTokenCounts.get(token) ?? 0;
|
|
534
|
+
if (exactTitleMatches > 0) {
|
|
535
|
+
score += exactTitleMatches * tuning.title_exact_bonus;
|
|
536
|
+
matched.add("title");
|
|
537
|
+
}
|
|
538
|
+
for (const field of searchableFields) {
|
|
539
|
+
const fieldValue = field.value.toLowerCase();
|
|
540
|
+
const occurrences = countOccurrences(fieldValue, token);
|
|
541
|
+
if (occurrences > 0) {
|
|
542
|
+
score += occurrences * field.weight;
|
|
543
|
+
matched.add(field.name);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
const isLongPhraseQuery = tokens.length >= LONG_QUERY_TOKEN_THRESHOLD && normalizedQuery.includes(" ");
|
|
548
|
+
if (isLongPhraseQuery) {
|
|
549
|
+
const normalizedTitle = normalizeSearchPhrase(item.title);
|
|
550
|
+
if (normalizedTitle === normalizedQuery) {
|
|
551
|
+
score += LONG_QUERY_TITLE_EXACT_BONUS;
|
|
552
|
+
matched.add("title");
|
|
553
|
+
}
|
|
554
|
+
for (const field of searchableFields) {
|
|
555
|
+
const normalizedField = normalizeSearchPhrase(field.value);
|
|
556
|
+
const phraseOccurrences = countOccurrences(normalizedField, normalizedQuery);
|
|
557
|
+
if (phraseOccurrences > 0) {
|
|
558
|
+
score += phraseOccurrences * field.weight * LONG_QUERY_PHRASE_MULTIPLIER;
|
|
559
|
+
matched.add(field.name);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (score <= 0) {
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
return {
|
|
567
|
+
item,
|
|
568
|
+
score,
|
|
569
|
+
matched_fields: [...matched].sort((a, b) => a.localeCompare(b))
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
function sortHits(items, statusRegistry) {
|
|
573
|
+
return [...items].sort((a, b) => {
|
|
574
|
+
const byScore = b.score - a.score;
|
|
575
|
+
if (byScore !== 0)
|
|
576
|
+
return byScore;
|
|
577
|
+
const aTerminal = isTerminalStatus(a.item.status, statusRegistry);
|
|
578
|
+
const bTerminal = isTerminalStatus(b.item.status, statusRegistry);
|
|
579
|
+
if (aTerminal !== bTerminal) {
|
|
580
|
+
return aTerminal ? 1 : -1;
|
|
581
|
+
}
|
|
582
|
+
const byPriority = a.item.priority - b.item.priority;
|
|
583
|
+
if (byPriority !== 0)
|
|
584
|
+
return byPriority;
|
|
585
|
+
const byUpdated = compareTimestampStrings(b.item.updated_at, a.item.updated_at);
|
|
586
|
+
if (byUpdated !== 0)
|
|
587
|
+
return byUpdated;
|
|
588
|
+
return a.item.id.localeCompare(b.item.id);
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
function buildHybridLexicalScore(document, tokens, normalizedQuery, includeLinked, linkedCorpusById, tuning) {
|
|
592
|
+
return scoreDocument(document, tokens, normalizedQuery, includeLinked ? linkedCorpusById.get(document.metadata.id) ?? "" : "", tuning);
|
|
593
|
+
}
|
|
594
|
+
function normalizeScoreMap(scoreById) {
|
|
595
|
+
if (scoreById.size === 0) {
|
|
596
|
+
return /* @__PURE__ */ new Map();
|
|
597
|
+
}
|
|
598
|
+
const values = [...scoreById.values()];
|
|
599
|
+
const minScore = Math.min(...values);
|
|
600
|
+
const maxScore = Math.max(...values);
|
|
601
|
+
if (maxScore === minScore) {
|
|
602
|
+
return new Map([...scoreById.keys()].map((id) => [id, 1]));
|
|
603
|
+
}
|
|
604
|
+
const normalized = /* @__PURE__ */ new Map();
|
|
605
|
+
for (const [id, score] of scoreById) {
|
|
606
|
+
normalized.set(id, (score - minScore) / (maxScore - minScore));
|
|
607
|
+
}
|
|
608
|
+
return normalized;
|
|
609
|
+
}
|
|
610
|
+
function resolveSearchMaxResults(settings) {
|
|
611
|
+
const candidate = settings.search?.max_results;
|
|
612
|
+
if (typeof candidate === "number" && Number.isFinite(candidate) && candidate > 0) {
|
|
613
|
+
return Math.floor(candidate);
|
|
614
|
+
}
|
|
615
|
+
return 50;
|
|
616
|
+
}
|
|
617
|
+
function resolveSearchScoreThreshold(settings) {
|
|
618
|
+
const candidate = settings.search?.score_threshold;
|
|
619
|
+
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
|
620
|
+
return candidate;
|
|
621
|
+
}
|
|
622
|
+
return 0;
|
|
623
|
+
}
|
|
624
|
+
function resolveHybridSemanticWeight(settings) {
|
|
625
|
+
const candidate = settings.search?.hybrid_semantic_weight;
|
|
626
|
+
if (typeof candidate === "number" && Number.isFinite(candidate) && candidate >= 0 && candidate <= 1) {
|
|
627
|
+
return candidate;
|
|
628
|
+
}
|
|
629
|
+
return 0.7;
|
|
630
|
+
}
|
|
631
|
+
function resolveSearchTuning(settings) {
|
|
632
|
+
const defaults = {
|
|
633
|
+
title_exact_bonus: 10,
|
|
634
|
+
title_weight: 8,
|
|
635
|
+
description_weight: 5,
|
|
636
|
+
tags_weight: 6,
|
|
637
|
+
status_weight: 2,
|
|
638
|
+
body_weight: 1,
|
|
639
|
+
comments_weight: 1,
|
|
640
|
+
notes_weight: 1,
|
|
641
|
+
learnings_weight: 1,
|
|
642
|
+
reminders_weight: 2,
|
|
643
|
+
events_weight: 2,
|
|
644
|
+
dependencies_weight: 3,
|
|
645
|
+
linked_content_weight: 1
|
|
646
|
+
};
|
|
647
|
+
const tuning = settings.search?.tuning;
|
|
648
|
+
if (!tuning)
|
|
649
|
+
return defaults;
|
|
650
|
+
const resolveWeight = (candidate, fallback) => {
|
|
651
|
+
if (typeof candidate === "number" && Number.isFinite(candidate) && candidate >= 0) {
|
|
652
|
+
return candidate;
|
|
653
|
+
}
|
|
654
|
+
return fallback;
|
|
655
|
+
};
|
|
656
|
+
return {
|
|
657
|
+
title_exact_bonus: resolveWeight(tuning.title_exact_bonus, defaults.title_exact_bonus),
|
|
658
|
+
title_weight: resolveWeight(tuning.title_weight, defaults.title_weight),
|
|
659
|
+
description_weight: resolveWeight(tuning.description_weight, defaults.description_weight),
|
|
660
|
+
tags_weight: resolveWeight(tuning.tags_weight, defaults.tags_weight),
|
|
661
|
+
status_weight: resolveWeight(tuning.status_weight, defaults.status_weight),
|
|
662
|
+
body_weight: resolveWeight(tuning.body_weight, defaults.body_weight),
|
|
663
|
+
comments_weight: resolveWeight(tuning.comments_weight, defaults.comments_weight),
|
|
664
|
+
notes_weight: resolveWeight(tuning.notes_weight, defaults.notes_weight),
|
|
665
|
+
learnings_weight: resolveWeight(tuning.learnings_weight, defaults.learnings_weight),
|
|
666
|
+
reminders_weight: resolveWeight(tuning.reminders_weight, defaults.reminders_weight),
|
|
667
|
+
events_weight: resolveWeight(tuning.events_weight, defaults.events_weight),
|
|
668
|
+
dependencies_weight: resolveWeight(tuning.dependencies_weight, defaults.dependencies_weight),
|
|
669
|
+
linked_content_weight: resolveWeight(tuning.linked_content_weight, defaults.linked_content_weight)
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
function emptySearchResult(query, mode, options, includeLinked, scoreThreshold, hybridSemanticWeight, projection, warnings) {
|
|
673
|
+
const projectionFields = projection.mode === "full" ? null : [...projection.fields];
|
|
674
|
+
return {
|
|
675
|
+
query: query.trim(),
|
|
676
|
+
mode,
|
|
677
|
+
items: [],
|
|
678
|
+
count: 0,
|
|
679
|
+
filters: {
|
|
680
|
+
mode,
|
|
681
|
+
type: options.type ?? null,
|
|
682
|
+
tag: options.tag ?? null,
|
|
683
|
+
priority: options.priority ?? null,
|
|
684
|
+
deadline_before: options.deadlineBefore ?? null,
|
|
685
|
+
deadline_after: options.deadlineAfter ?? null,
|
|
686
|
+
include_linked: includeLinked,
|
|
687
|
+
title_exact: options.titleExact === true,
|
|
688
|
+
phrase_exact: options.phraseExact === true,
|
|
689
|
+
score_threshold: scoreThreshold,
|
|
690
|
+
hybrid_semantic_weight: mode === "hybrid" ? hybridSemanticWeight : null,
|
|
691
|
+
limit: options.limit ?? null
|
|
692
|
+
},
|
|
693
|
+
projection: {
|
|
694
|
+
mode: projection.mode,
|
|
695
|
+
fields: projectionFields
|
|
696
|
+
},
|
|
697
|
+
now: nowIso(),
|
|
698
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function requireSemanticDependencies(requestedMode, providerResolution, vectorResolution, hasExtensionVectorQuery) {
|
|
702
|
+
if (!providerResolution.active) {
|
|
703
|
+
throw new PmCliError(`Search mode '${requestedMode}' requires a configured embedding provider in settings.providers.openai or settings.providers.ollama`, EXIT_CODE.USAGE);
|
|
704
|
+
}
|
|
705
|
+
if (!vectorResolution.active && !hasExtensionVectorQuery) {
|
|
706
|
+
throw new PmCliError(`Search mode '${requestedMode}' requires a configured vector store in settings.vector_store.qdrant/settings.vector_store.lancedb or an extension adapter selected by settings.vector_store.adapter`, EXIT_CODE.USAGE);
|
|
707
|
+
}
|
|
708
|
+
return {
|
|
709
|
+
provider: providerResolution.active,
|
|
710
|
+
vectorStore: vectorResolution.active ?? null
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
var toOptionalNonEmptyString = toNonEmptyStringOrUndefined;
|
|
714
|
+
function resolveExtensionSearchProvider(settings) {
|
|
715
|
+
const registrations = getActiveExtensionRegistrations();
|
|
716
|
+
const providerName = toOptionalNonEmptyString(settings.search?.provider);
|
|
717
|
+
const resolved = resolveRegisteredSearchProvider(registrations, providerName);
|
|
718
|
+
if (!resolved) {
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
721
|
+
const runtimeDefinition = resolved.runtime_definition ?? resolved.definition;
|
|
722
|
+
const query = runtimeDefinition.query;
|
|
723
|
+
if (typeof query !== "function") {
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
const registeredName = toOptionalNonEmptyString(runtimeDefinition.name) ?? toOptionalNonEmptyString(resolved.definition.name) ?? providerName;
|
|
727
|
+
if (!registeredName) {
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
return {
|
|
731
|
+
providerName: registeredName,
|
|
732
|
+
query
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
function resolveExtensionVectorAdapter(settings) {
|
|
736
|
+
const registrations = getActiveExtensionRegistrations();
|
|
737
|
+
const adapterName = toOptionalNonEmptyString(settings.vector_store?.adapter);
|
|
738
|
+
const resolved = resolveRegisteredVectorStoreAdapter(registrations, adapterName);
|
|
739
|
+
if (!resolved) {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
const runtimeDefinition = resolved.runtime_definition ?? resolved.definition;
|
|
743
|
+
const query = runtimeDefinition.query;
|
|
744
|
+
if (typeof query !== "function") {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
return {
|
|
748
|
+
query
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function normalizeExtensionProviderHits(providerName, raw, filteredById) {
|
|
752
|
+
const rawHits = Array.isArray(raw) ? raw : raw?.hits;
|
|
753
|
+
if (!Array.isArray(rawHits)) {
|
|
754
|
+
throw new PmCliError(`Extension search provider "${providerName}" must return an array of hits or { hits: [...] }`, EXIT_CODE.GENERIC_FAILURE);
|
|
755
|
+
}
|
|
756
|
+
const seen = /* @__PURE__ */ new Set();
|
|
757
|
+
const hits = [];
|
|
758
|
+
for (const rawHit of rawHits) {
|
|
759
|
+
if (typeof rawHit !== "object" || rawHit === null) {
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
const id = toOptionalNonEmptyString(rawHit.id);
|
|
763
|
+
const score = rawHit.score;
|
|
764
|
+
if (!id || typeof score !== "number" || !Number.isFinite(score) || seen.has(id)) {
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
const document = filteredById.get(id);
|
|
768
|
+
if (!document) {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
const matchedFieldsRaw = rawHit.matched_fields;
|
|
772
|
+
const matchedFields = Array.isArray(matchedFieldsRaw) && matchedFieldsRaw.every((entry) => typeof entry === "string") ? [...new Set(matchedFieldsRaw.map((entry) => entry.trim()).filter((entry) => entry.length > 0))].sort((a, b) => a.localeCompare(b)) : [`provider:${providerName}`];
|
|
773
|
+
seen.add(id);
|
|
774
|
+
hits.push({
|
|
775
|
+
item: document.metadata,
|
|
776
|
+
score,
|
|
777
|
+
matched_fields: matchedFields
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
return hits;
|
|
781
|
+
}
|
|
782
|
+
function buildSemanticHits(vectorHits, filteredById) {
|
|
783
|
+
const semanticHits = [];
|
|
784
|
+
const semanticScores = /* @__PURE__ */ new Map();
|
|
785
|
+
for (const vectorHit of vectorHits) {
|
|
786
|
+
if (semanticScores.has(vectorHit.id)) {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
const document = filteredById.get(vectorHit.id);
|
|
790
|
+
if (!document) {
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
semanticScores.set(vectorHit.id, vectorHit.score);
|
|
794
|
+
semanticHits.push({
|
|
795
|
+
item: document.metadata,
|
|
796
|
+
score: vectorHit.score,
|
|
797
|
+
matched_fields: ["semantic"]
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
return {
|
|
801
|
+
semanticHits,
|
|
802
|
+
semanticScores
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
function combineHybridHits(filteredById, semanticScores, keywordHits, hybridSemanticWeight) {
|
|
806
|
+
const keywordScores = new Map(keywordHits.map((entry) => [entry.item.id, entry.score]));
|
|
807
|
+
const keywordMatches = new Map(keywordHits.map((entry) => [entry.item.id, entry.matched_fields]));
|
|
808
|
+
const normalizedSemantic = normalizeScoreMap(semanticScores);
|
|
809
|
+
const normalizedKeyword = normalizeScoreMap(keywordScores);
|
|
810
|
+
const candidateIds = /* @__PURE__ */ new Set([...semanticScores.keys(), ...keywordScores.keys()]);
|
|
811
|
+
const keywordWeight = 1 - hybridSemanticWeight;
|
|
812
|
+
return [...candidateIds].map((id) => {
|
|
813
|
+
const document = filteredById.get(id);
|
|
814
|
+
const semanticScore = normalizedSemantic.get(id) ?? 0;
|
|
815
|
+
const keywordScore = normalizedKeyword.get(id) ?? 0;
|
|
816
|
+
const combinedScore = semanticScore * hybridSemanticWeight + keywordScore * keywordWeight;
|
|
817
|
+
if (combinedScore <= 0) {
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
const matchedFields = /* @__PURE__ */ new Set();
|
|
821
|
+
if (semanticScores.has(id)) {
|
|
822
|
+
matchedFields.add("semantic");
|
|
823
|
+
}
|
|
824
|
+
for (const field of keywordMatches.get(id) ?? []) {
|
|
825
|
+
matchedFields.add(field);
|
|
826
|
+
}
|
|
827
|
+
return {
|
|
828
|
+
item: document.metadata,
|
|
829
|
+
score: combinedScore,
|
|
830
|
+
matched_fields: [...matchedFields].sort((a, b) => a.localeCompare(b))
|
|
831
|
+
};
|
|
832
|
+
}).filter((entry) => entry !== null);
|
|
833
|
+
}
|
|
834
|
+
async function computeSemanticOrHybridHits(context) {
|
|
835
|
+
const semanticLimit = context.limit ?? context.maxResults;
|
|
836
|
+
const embeddingOptions = context.embeddingTimeoutMs !== void 0 ? { timeout_ms: context.embeddingTimeoutMs } : {};
|
|
837
|
+
const vectorQueryOptions = context.vectorQueryTimeoutMs !== void 0 ? { timeout_ms: context.vectorQueryTimeoutMs } : {};
|
|
838
|
+
const queryVectors = await executeEmbeddingRequest(context.provider, context.query.trim(), embeddingOptions);
|
|
839
|
+
const semanticVector = queryVectors[0];
|
|
840
|
+
let vectorHits;
|
|
841
|
+
if (context.extensionVectorAdapter?.query) {
|
|
842
|
+
try {
|
|
843
|
+
vectorHits = await Promise.resolve(context.extensionVectorAdapter.query({
|
|
844
|
+
vector: semanticVector,
|
|
845
|
+
limit: semanticLimit,
|
|
846
|
+
settings: context.settings
|
|
847
|
+
}));
|
|
848
|
+
} catch (error) {
|
|
849
|
+
if (!context.vectorStore) {
|
|
850
|
+
throw new PmCliError(`Extension vector adapter query failed and no built-in fallback store is configured (${error instanceof Error ? error.message : String(error)})`, EXIT_CODE.GENERIC_FAILURE);
|
|
851
|
+
}
|
|
852
|
+
vectorHits = await executeVectorQuery(context.vectorStore, semanticVector, semanticLimit, vectorQueryOptions);
|
|
853
|
+
}
|
|
854
|
+
} else if (context.vectorStore) {
|
|
855
|
+
vectorHits = await executeVectorQuery(context.vectorStore, semanticVector, semanticLimit, vectorQueryOptions);
|
|
856
|
+
} else {
|
|
857
|
+
throw new PmCliError("Semantic search requires either a configured vector store or an extension vector adapter query handler", EXIT_CODE.USAGE);
|
|
858
|
+
}
|
|
859
|
+
const filteredById = new Map(context.filteredDocuments.map((document) => [document.metadata.id, document]));
|
|
860
|
+
const { semanticHits, semanticScores } = buildSemanticHits(vectorHits, filteredById);
|
|
861
|
+
const vectorMatchCount = semanticScores.size;
|
|
862
|
+
if (context.requestedMode === "semantic") {
|
|
863
|
+
return { hits: semanticHits, vectorMatchCount };
|
|
864
|
+
}
|
|
865
|
+
return {
|
|
866
|
+
hits: combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight),
|
|
867
|
+
vectorMatchCount
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
async function loadDocuments(pmRoot, itemFormat, typeToFolder, schema) {
|
|
871
|
+
const readDocumentBody = async (metadata, preferredPath, preferredFormat) => {
|
|
872
|
+
const tryRead = async (targetPath, format) => {
|
|
873
|
+
await runActiveOnReadHooks({ path: targetPath, scope: "project" });
|
|
874
|
+
const raw = await fs.readFile(targetPath, "utf8");
|
|
875
|
+
const parsed = parseItemDocument(raw, {
|
|
876
|
+
format,
|
|
877
|
+
schema,
|
|
878
|
+
onWarning: (warning) => listWarnings.push(warning)
|
|
879
|
+
});
|
|
880
|
+
return parsed.body;
|
|
881
|
+
};
|
|
882
|
+
try {
|
|
883
|
+
return await tryRead(preferredPath, preferredFormat);
|
|
884
|
+
} catch {
|
|
885
|
+
const alternateFormat = preferredFormat === "toon" ? "json_markdown" : "toon";
|
|
886
|
+
const alternatePath = getItemPath(pmRoot, metadata.type, metadata.id, alternateFormat, typeToFolder);
|
|
887
|
+
try {
|
|
888
|
+
return await tryRead(alternatePath, alternateFormat);
|
|
889
|
+
} catch {
|
|
890
|
+
listWarnings.push(`item_list_item_read_failed:${path.relative(pmRoot, alternatePath)}`);
|
|
891
|
+
return "";
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
const listWarnings = [];
|
|
896
|
+
const cachedDocuments = await listAllDocumentCandidatesCached(pmRoot, itemFormat, typeToFolder, listWarnings, schema);
|
|
897
|
+
const documents = [];
|
|
898
|
+
if (cachedDocuments.length === 0) {
|
|
899
|
+
const frontMatterDocuments = await listAllFrontMatter(pmRoot, itemFormat, typeToFolder, listWarnings, schema);
|
|
900
|
+
for (const metadata of frontMatterDocuments) {
|
|
901
|
+
const preferredPath = getItemPath(pmRoot, metadata.type, metadata.id, itemFormat, typeToFolder);
|
|
902
|
+
const body = await readDocumentBody(metadata, preferredPath, itemFormat);
|
|
903
|
+
documents.push({ metadata, body });
|
|
904
|
+
}
|
|
905
|
+
return {
|
|
906
|
+
documents,
|
|
907
|
+
warnings: [...new Set(listWarnings)].sort((left, right) => left.localeCompare(right))
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
for (const cachedDocument of cachedDocuments) {
|
|
911
|
+
if (typeof cachedDocument.body === "string") {
|
|
912
|
+
documents.push({
|
|
913
|
+
metadata: cachedDocument.metadata,
|
|
914
|
+
body: cachedDocument.body
|
|
915
|
+
});
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
const body = await readDocumentBody(cachedDocument.metadata, cachedDocument.item_path, cachedDocument.item_format);
|
|
919
|
+
documents.push({
|
|
920
|
+
metadata: cachedDocument.metadata,
|
|
921
|
+
body
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return {
|
|
925
|
+
documents,
|
|
926
|
+
warnings: [...new Set(listWarnings)].sort((left, right) => left.localeCompare(right))
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
function readSearchFieldValue(hit, field) {
|
|
930
|
+
const normalized = field.trim();
|
|
931
|
+
if (normalized.length === 0) {
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
if (normalized === "score") {
|
|
935
|
+
return hit.score;
|
|
936
|
+
}
|
|
937
|
+
if (normalized === "matched_fields") {
|
|
938
|
+
return hit.matched_fields;
|
|
939
|
+
}
|
|
940
|
+
if (normalized.startsWith("item.")) {
|
|
941
|
+
const itemKey = normalized.slice("item.".length);
|
|
942
|
+
if (itemKey.length === 0) {
|
|
943
|
+
return null;
|
|
944
|
+
}
|
|
945
|
+
const itemRecord2 = toItemRecord(hit.item);
|
|
946
|
+
return itemRecord2[itemKey] ?? null;
|
|
947
|
+
}
|
|
948
|
+
const hitRecord = hit;
|
|
949
|
+
const itemRecord = toItemRecord(hit.item);
|
|
950
|
+
if (Object.prototype.hasOwnProperty.call(itemRecord, normalized)) {
|
|
951
|
+
return itemRecord[normalized] ?? null;
|
|
952
|
+
}
|
|
953
|
+
if (Object.prototype.hasOwnProperty.call(hitRecord, normalized)) {
|
|
954
|
+
return hitRecord[normalized] ?? null;
|
|
955
|
+
}
|
|
956
|
+
return null;
|
|
957
|
+
}
|
|
958
|
+
function projectSearchHits(hits, projection) {
|
|
959
|
+
if (projection.mode === "full") {
|
|
960
|
+
return hits;
|
|
961
|
+
}
|
|
962
|
+
return hits.map((hit) => {
|
|
963
|
+
const projected = {};
|
|
964
|
+
for (const field of projection.fields) {
|
|
965
|
+
projected[field] = readSearchFieldValue(hit, field);
|
|
966
|
+
}
|
|
967
|
+
return projected;
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
async function runSearch(query, options, global2) {
|
|
971
|
+
const includeLinked = parseIncludeLinked(options.includeLinked);
|
|
972
|
+
const titleExact = parseTitleExact(options.titleExact);
|
|
973
|
+
const phraseExact = parsePhraseExact(options.phraseExact);
|
|
974
|
+
const tokens = parseTokens(query);
|
|
975
|
+
const normalizedQuery = normalizeSearchPhrase(query);
|
|
976
|
+
const limit = parseLimit(options.limit);
|
|
977
|
+
const projection = parseProjectionConfig(options);
|
|
978
|
+
const modeWasExplicit = typeof options.mode === "string" && options.mode.trim().length > 0;
|
|
979
|
+
const pmRoot = resolvePmRoot(process.cwd(), global2.path);
|
|
980
|
+
if (!await pathExists(getSettingsPath(pmRoot))) {
|
|
981
|
+
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
982
|
+
}
|
|
983
|
+
const storedSettings = await readSettings(pmRoot);
|
|
984
|
+
const runtimeDefaultsResolution = resolveSettingsWithSemanticRuntimeDefaults(storedSettings);
|
|
985
|
+
const settings = runtimeDefaultsResolution.settings;
|
|
986
|
+
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
987
|
+
const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
|
|
988
|
+
validateSearchProjectionFields(projection, runtimeFieldRegistry);
|
|
989
|
+
const runtimeFieldFilters = collectRuntimeFilterValues(options, runtimeFieldRegistry, "search");
|
|
990
|
+
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
991
|
+
const maxResults = resolveSearchMaxResults(settings);
|
|
992
|
+
const scoreThreshold = resolveSearchScoreThreshold(settings);
|
|
993
|
+
const hybridSemanticWeight = resolveHybridSemanticWeight(settings);
|
|
994
|
+
const tuning = resolveSearchTuning(settings);
|
|
995
|
+
const providerResolution = resolveEmbeddingProviders(settings);
|
|
996
|
+
const vectorResolution = resolveVectorStores(settings);
|
|
997
|
+
const extensionSearchProvider = resolveExtensionSearchProvider(settings);
|
|
998
|
+
const extensionVectorAdapter = resolveExtensionVectorAdapter(settings);
|
|
999
|
+
let effectiveMode = parseMode(options.mode, {
|
|
1000
|
+
hasProvider: providerResolution.active !== null || extensionSearchProvider !== null,
|
|
1001
|
+
hasVectorStore: vectorResolution.active !== null || extensionVectorAdapter !== null
|
|
1002
|
+
});
|
|
1003
|
+
const loadedDocuments = await loadDocuments(pmRoot, settings.item_format ?? "toon", typeRegistry.type_to_folder, settings.schema);
|
|
1004
|
+
const warnings = loadedDocuments.warnings;
|
|
1005
|
+
const allDocuments = loadedDocuments.documents;
|
|
1006
|
+
const metadataFilteredDocuments = applyFilters(allDocuments, options, typeRegistry, runtimeFieldFilters);
|
|
1007
|
+
const filteredDocuments = applyExactQueryFilters(metadataFilteredDocuments, normalizedQuery, {
|
|
1008
|
+
titleExact,
|
|
1009
|
+
phraseExact
|
|
1010
|
+
});
|
|
1011
|
+
if (effectiveMode === "keyword" && (filteredDocuments.length === 0 || limit === 0)) {
|
|
1012
|
+
return emptySearchResult(query, effectiveMode, options, includeLinked, scoreThreshold, hybridSemanticWeight, projection, warnings);
|
|
1013
|
+
}
|
|
1014
|
+
const projectRoot = process.cwd();
|
|
1015
|
+
const globalRoot = resolveGlobalPmRoot(projectRoot);
|
|
1016
|
+
const linkedCorpusById = /* @__PURE__ */ new Map();
|
|
1017
|
+
if (includeLinked && (effectiveMode === "keyword" || effectiveMode === "hybrid")) {
|
|
1018
|
+
const linkedCorpusRoots = await resolveLinkedCorpusRoots(projectRoot, globalRoot);
|
|
1019
|
+
const linkedCorpusEntries = await Promise.all(filteredDocuments.map(async (document) => [document.metadata.id, await loadLinkedCorpus(document, linkedCorpusRoots)]));
|
|
1020
|
+
for (const [id, corpus] of linkedCorpusEntries) {
|
|
1021
|
+
linkedCorpusById.set(id, corpus);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
const keywordHits = filteredDocuments.map((document) => buildHybridLexicalScore(document, tokens, normalizedQuery, effectiveMode !== "semantic", linkedCorpusById, tuning)).filter((entry) => entry !== null);
|
|
1025
|
+
let hits = keywordHits;
|
|
1026
|
+
if (effectiveMode !== "keyword") {
|
|
1027
|
+
const builtInSemanticWillRun = !extensionSearchProvider && providerResolution.active !== null && (vectorResolution.active !== null || extensionVectorAdapter !== null);
|
|
1028
|
+
if (modeWasExplicit && builtInSemanticWillRun) {
|
|
1029
|
+
await maybeEmitVectorIndexStaleWarning(pmRoot, filteredDocuments, warnings);
|
|
1030
|
+
}
|
|
1031
|
+
try {
|
|
1032
|
+
if (!extensionSearchProvider) {
|
|
1033
|
+
requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
|
|
1034
|
+
}
|
|
1035
|
+
if (filteredDocuments.length === 0 || limit === 0) {
|
|
1036
|
+
return emptySearchResult(query, effectiveMode, options, includeLinked, scoreThreshold, hybridSemanticWeight, projection, warnings);
|
|
1037
|
+
}
|
|
1038
|
+
const filteredById = new Map(filteredDocuments.map((document) => [document.metadata.id, document]));
|
|
1039
|
+
const canUseBuiltInSemantic = providerResolution.active !== null && (vectorResolution.active !== null || extensionVectorAdapter !== null);
|
|
1040
|
+
if (extensionSearchProvider) {
|
|
1041
|
+
try {
|
|
1042
|
+
const providerResponse = await Promise.resolve(extensionSearchProvider.query({
|
|
1043
|
+
query,
|
|
1044
|
+
mode: effectiveMode,
|
|
1045
|
+
tokens,
|
|
1046
|
+
options,
|
|
1047
|
+
settings,
|
|
1048
|
+
documents: filteredDocuments
|
|
1049
|
+
}));
|
|
1050
|
+
hits = normalizeExtensionProviderHits(extensionSearchProvider.providerName, providerResponse, filteredById);
|
|
1051
|
+
} catch (error) {
|
|
1052
|
+
if (!canUseBuiltInSemantic) {
|
|
1053
|
+
throw new PmCliError(`Extension search provider "${extensionSearchProvider.providerName}" failed: ${error instanceof Error ? error.message : String(error)}`, EXIT_CODE.GENERIC_FAILURE);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
if (hits === keywordHits) {
|
|
1058
|
+
const implicitHybridMode = !modeWasExplicit && effectiveMode === "hybrid";
|
|
1059
|
+
const { provider, vectorStore } = requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
|
|
1060
|
+
const semanticResult = await computeSemanticOrHybridHits({
|
|
1061
|
+
requestedMode: effectiveMode,
|
|
1062
|
+
query,
|
|
1063
|
+
filteredDocuments,
|
|
1064
|
+
keywordHits,
|
|
1065
|
+
hybridSemanticWeight,
|
|
1066
|
+
limit,
|
|
1067
|
+
maxResults,
|
|
1068
|
+
provider,
|
|
1069
|
+
vectorStore,
|
|
1070
|
+
extensionVectorAdapter,
|
|
1071
|
+
settings,
|
|
1072
|
+
...implicitHybridMode ? {
|
|
1073
|
+
embeddingTimeoutMs: IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS,
|
|
1074
|
+
vectorQueryTimeoutMs: IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS
|
|
1075
|
+
} : {}
|
|
1076
|
+
});
|
|
1077
|
+
hits = semanticResult.hits;
|
|
1078
|
+
if (semanticResult.vectorMatchCount === 0) {
|
|
1079
|
+
if (effectiveMode === "semantic") {
|
|
1080
|
+
hits = keywordHits;
|
|
1081
|
+
}
|
|
1082
|
+
warnings.push(`search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
} catch (error) {
|
|
1086
|
+
const fallbackWarning = modeWasExplicit ? buildExplicitSemanticFallbackWarning(effectiveMode, error) : buildImplicitSemanticFallbackWarning(error);
|
|
1087
|
+
effectiveMode = "keyword";
|
|
1088
|
+
hits = keywordHits;
|
|
1089
|
+
warnings.push(fallbackWarning);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
const thresholded = hits.filter((entry) => entry.score >= scoreThreshold);
|
|
1093
|
+
const sorted = sortHits(thresholded, statusRegistry);
|
|
1094
|
+
const resolvedLimit = effectiveMode === "keyword" ? limit : limit ?? maxResults;
|
|
1095
|
+
const limited = resolvedLimit === void 0 ? sorted : sorted.slice(0, resolvedLimit);
|
|
1096
|
+
const projectedItems = projectSearchHits(limited, projection);
|
|
1097
|
+
const projectionFields = projection.mode === "full" ? null : [...projection.fields];
|
|
1098
|
+
return {
|
|
1099
|
+
query: query.trim(),
|
|
1100
|
+
mode: effectiveMode,
|
|
1101
|
+
items: projectedItems,
|
|
1102
|
+
count: projectedItems.length,
|
|
1103
|
+
filters: {
|
|
1104
|
+
mode: effectiveMode,
|
|
1105
|
+
type: options.type ?? null,
|
|
1106
|
+
tag: options.tag ?? null,
|
|
1107
|
+
priority: options.priority ?? null,
|
|
1108
|
+
deadline_before: options.deadlineBefore ?? null,
|
|
1109
|
+
deadline_after: options.deadlineAfter ?? null,
|
|
1110
|
+
include_linked: includeLinked,
|
|
1111
|
+
title_exact: titleExact,
|
|
1112
|
+
phrase_exact: phraseExact,
|
|
1113
|
+
score_threshold: scoreThreshold,
|
|
1114
|
+
hybrid_semantic_weight: effectiveMode === "hybrid" ? hybridSemanticWeight : null,
|
|
1115
|
+
limit: options.limit ?? null,
|
|
1116
|
+
runtime_filters: runtimeFieldFilters
|
|
1117
|
+
},
|
|
1118
|
+
projection: {
|
|
1119
|
+
mode: projection.mode,
|
|
1120
|
+
fields: projectionFields
|
|
1121
|
+
},
|
|
1122
|
+
now: nowIso(),
|
|
1123
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
export {
|
|
1127
|
+
classifyImplicitSemanticFallbackReason,
|
|
1128
|
+
collectErrorCauseCodes,
|
|
1129
|
+
resolveHybridSemanticWeight,
|
|
1130
|
+
resolveSearchMaxResults,
|
|
1131
|
+
resolveSearchScoreThreshold,
|
|
1132
|
+
resolveSearchTuning,
|
|
1133
|
+
runSearch
|
|
1134
|
+
};
|
|
1135
|
+
//# sourceMappingURL=search-HENBL456.js.map
|