@unbrained/pm-cli 2026.5.29 → 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 +54 -12
- package/dist/cli/bootstrap-args.d.ts +1 -1
- package/dist/cli/bootstrap-args.js +59 -9
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commands/activity.js +4 -4
- package/dist/cli/commands/activity.js.map +1 -1
- package/dist/cli/commands/calendar.js +83 -11
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/close.js +4 -4
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/completion.js +4 -4
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/create.js +50 -7
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/deps.js +4 -4
- package/dist/cli/commands/deps.js.map +1 -1
- package/dist/cli/commands/extension/install-sources.d.ts +3 -0
- package/dist/cli/commands/extension/install-sources.js +29 -4
- package/dist/cli/commands/extension/install-sources.js.map +1 -1
- package/dist/cli/commands/extension.js +26 -5
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/get.js +6 -3
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/list.js +25 -6
- package/dist/cli/commands/list.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/commands/stats.js +4 -4
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/test-all.js +4 -4
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +39 -11
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +10 -12
- 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 +7 -9
- 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-KBQY3YG5.js +122 -0
- 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-P53TN6IA.js +674 -0
- 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-UP3VRUFS.js +232 -0
- package/dist/cli-bundle/chunks/register-list-query-UP3VRUFS.js.map +7 -0
- package/dist/cli-bundle/chunks/register-mutation-YWSBF545.js +712 -0
- package/dist/cli-bundle/chunks/register-mutation-YWSBF545.js.map +7 -0
- package/dist/cli-bundle/chunks/register-operations-3BDTGSDH.js +374 -0
- package/dist/cli-bundle/chunks/register-operations-3BDTGSDH.js.map +7 -0
- package/dist/cli-bundle/chunks/register-setup-V56GDRUS.js +246 -0
- 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 +6952 -0
- package/dist/cli-bundle/main.js.map +7 -0
- package/dist/cli.js +1 -1
- package/dist/core/config/nested-settings.d.ts +2 -0
- package/dist/core/config/nested-settings.js +17 -2
- package/dist/core/config/nested-settings.js.map +1 -1
- 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/item/type-synonyms.d.ts +20 -0
- package/dist/core/item/type-synonyms.js +42 -0
- package/dist/core/item/type-synonyms.js.map +1 -0
- 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 +76 -5
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +73 -32
- package/dist/core/search/semantic-defaults.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/sentry/helpers.d.ts +1 -1
- package/dist/core/sentry/helpers.js +4 -4
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/shared/constants.d.ts +2 -2
- package/dist/core/shared/constants.js +3 -3
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/html-entity-decode.d.ts +2 -1
- package/dist/core/shared/html-entity-decode.js +14 -9
- package/dist/core/shared/html-entity-decode.js.map +1 -1
- package/dist/core/shared/time.js +52 -2
- package/dist/core/shared/time.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +24 -0
- package/dist/core/store/front-matter-cache.js +119 -8
- package/dist/core/store/front-matter-cache.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/item-store.d.ts +7 -0
- package/dist/core/store/item-store.js +13 -3
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +7 -2
- package/dist/core/store/settings-validator.js.map +1 -1
- package/dist/core/store/settings.js +19 -3
- package/dist/core/store/settings.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/mcp/server.js +3 -3
- package/dist/mcp/server.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 +29 -8
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/docs/CONFIGURATION.md +11 -0
- package/docs/RELEASING.md +1 -1
- package/package.json +7 -5
- package/packages/pm-calendar/extensions/calendar/index.js +27 -2
- package/packages/pm-calendar/extensions/calendar/index.ts +28 -2
- package/scripts/bundle-cli.mjs +39 -0
|
@@ -1,5 +1,5 @@
|
|
|
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]="a14ed5c7-eb26-57d5-8b28-58d736a3c11c")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
@@ -7,9 +7,54 @@ import { hasActiveOnReadHooks, runActiveOnReadHooks } from "../extensions/index.
|
|
|
7
7
|
import { parseItemDocument } from "../item/item-format.js";
|
|
8
8
|
import { writeFileAtomic } from "../fs/fs-utils.js";
|
|
9
9
|
import { ITEM_FILE_EXTENSIONS, getItemFormatFromPath } from "./paths.js";
|
|
10
|
-
const CACHE_VERSION =
|
|
10
|
+
const CACHE_VERSION = 6;
|
|
11
11
|
const CACHE_FILENAME = "metadata-cache.json";
|
|
12
12
|
const BODY_CACHE_FILENAME = "metadata-cache-bodies.json";
|
|
13
|
+
const COLLECTIONS_CACHE_FILENAME = "metadata-cache-collections.json";
|
|
14
|
+
/**
|
|
15
|
+
* Heavy "collection" front-matter fields. These arrays dominate the on-disk cache
|
|
16
|
+
* (e.g. a single item's comment thread can be hundreds of KB) yet the hot list path
|
|
17
|
+
* (`pm list`, stats, deps, activity, calendar, close) never reads them. They are
|
|
18
|
+
* stored in a separate collections cache that is parsed only when a caller opts in
|
|
19
|
+
* (`includeCollections`), keeping the always-loaded light cache an order of magnitude
|
|
20
|
+
* smaller and its JSON.parse correspondingly cheaper.
|
|
21
|
+
*/
|
|
22
|
+
export const HEAVY_METADATA_KEYS = [
|
|
23
|
+
"comments",
|
|
24
|
+
"notes",
|
|
25
|
+
"learnings",
|
|
26
|
+
"files",
|
|
27
|
+
"tests",
|
|
28
|
+
"test_runs",
|
|
29
|
+
"docs",
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Split parsed front-matter into the light scalar/small fields (everything except the
|
|
33
|
+
* heavy collection arrays) and the heavy collection fields. Only keys that are actually
|
|
34
|
+
* present are moved, so an item without comments stays without comments in both tiers.
|
|
35
|
+
*/
|
|
36
|
+
function splitHeavyMetadata(metadata) {
|
|
37
|
+
const light = { ...metadata };
|
|
38
|
+
const heavy = {};
|
|
39
|
+
for (const key of HEAVY_METADATA_KEYS) {
|
|
40
|
+
if (key in light) {
|
|
41
|
+
heavy[key] = light[key];
|
|
42
|
+
delete light[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { light: light, heavy };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Recombine light metadata with cached heavy collection fields. Key order differs from
|
|
49
|
+
* the on-disk document, but every downstream hash/serialization canonicalizes and
|
|
50
|
+
* sorts keys (`stableStringify`), so the merged record is byte-identical once hashed.
|
|
51
|
+
*/
|
|
52
|
+
function mergeHeavyMetadata(light, heavy) {
|
|
53
|
+
if (!heavy || Object.keys(heavy).length === 0) {
|
|
54
|
+
return light;
|
|
55
|
+
}
|
|
56
|
+
return { ...light, ...heavy };
|
|
57
|
+
}
|
|
13
58
|
function computeContextFingerprint(preferredFormat, typeToFolder, schema) {
|
|
14
59
|
const hash = createHash("sha256");
|
|
15
60
|
hash.update(`format:${preferredFormat ?? "default"}`);
|
|
@@ -29,6 +74,9 @@ function getCachePath(pmRoot) {
|
|
|
29
74
|
function getBodyCachePath(pmRoot) {
|
|
30
75
|
return path.join(pmRoot, "runtime", BODY_CACHE_FILENAME);
|
|
31
76
|
}
|
|
77
|
+
function getCollectionsCachePath(pmRoot) {
|
|
78
|
+
return path.join(pmRoot, "runtime", COLLECTIONS_CACHE_FILENAME);
|
|
79
|
+
}
|
|
32
80
|
async function loadCache(pmRoot) {
|
|
33
81
|
try {
|
|
34
82
|
const raw = await fs.readFile(getCachePath(pmRoot), "utf8");
|
|
@@ -55,6 +103,19 @@ async function loadBodyCache(pmRoot) {
|
|
|
55
103
|
return null;
|
|
56
104
|
}
|
|
57
105
|
}
|
|
106
|
+
async function loadCollectionsCache(pmRoot) {
|
|
107
|
+
try {
|
|
108
|
+
const raw = await fs.readFile(getCollectionsCachePath(pmRoot), "utf8");
|
|
109
|
+
const parsed = JSON.parse(raw);
|
|
110
|
+
if (parsed.version !== CACHE_VERSION || typeof parsed.collections !== "object" || parsed.collections === null) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
return parsed;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
58
119
|
async function persistCache(cachePath, envelope) {
|
|
59
120
|
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
60
121
|
await writeFileAtomic(cachePath, JSON.stringify(envelope));
|
|
@@ -79,11 +140,16 @@ function statMatches(signature, mtimeMs, ctimeMs, size) {
|
|
|
79
140
|
*/
|
|
80
141
|
export async function listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, options = {}) {
|
|
81
142
|
const includeBody = options.includeBody !== false;
|
|
143
|
+
const includeCollections = options.includeCollections !== false;
|
|
82
144
|
const contextFingerprint = computeContextFingerprint(preferredFormat, typeToFolder, schema);
|
|
83
145
|
const existingCache = await loadCache(pmRoot);
|
|
84
146
|
const previousEntries = existingCache && existingCache.context_fingerprint === contextFingerprint ? existingCache.entries : {};
|
|
85
147
|
const existingBodyCache = includeBody ? await loadBodyCache(pmRoot) : null;
|
|
86
148
|
const previousBodies = existingBodyCache && existingBodyCache.context_fingerprint === contextFingerprint ? existingBodyCache.bodies : {};
|
|
149
|
+
const existingCollectionsCache = includeCollections ? await loadCollectionsCache(pmRoot) : null;
|
|
150
|
+
const previousCollections = existingCollectionsCache && existingCollectionsCache.context_fingerprint === contextFingerprint
|
|
151
|
+
? existingCollectionsCache.collections
|
|
152
|
+
: {};
|
|
87
153
|
const entries = Object.entries(typeToFolder);
|
|
88
154
|
const dirResults = await Promise.all(entries.map(async ([, folder]) => {
|
|
89
155
|
const dirPath = path.join(pmRoot, folder);
|
|
@@ -101,9 +167,11 @@ export async function listAllDocumentCandidatesCached(pmRoot, preferredFormat, t
|
|
|
101
167
|
const dispatchReadHooks = hasActiveOnReadHooks();
|
|
102
168
|
const newEntries = {};
|
|
103
169
|
const newBodies = {};
|
|
170
|
+
const newCollections = {};
|
|
104
171
|
const documentsById = new Map();
|
|
105
172
|
let metadataMiss = false;
|
|
106
173
|
let bodyMiss = false;
|
|
174
|
+
let collectionsMiss = false;
|
|
107
175
|
const parseTasks = [];
|
|
108
176
|
for (const { folder, dirPath, files } of dirResults) {
|
|
109
177
|
for (const file of files) {
|
|
@@ -131,8 +199,11 @@ export async function listAllDocumentCandidatesCached(pmRoot, preferredFormat, t
|
|
|
131
199
|
const metadataCached = cachedEntry !== undefined && statMatches(cachedEntry, mtimeMs, ctimeMs, size);
|
|
132
200
|
const cachedBody = previousBodies[relativePath];
|
|
133
201
|
const bodyCached = cachedBody !== undefined && statMatches(cachedBody, mtimeMs, ctimeMs, size);
|
|
134
|
-
const
|
|
135
|
-
|
|
202
|
+
const cachedCollections = previousCollections[relativePath];
|
|
203
|
+
const collectionsCached = cachedCollections !== undefined && statMatches(cachedCollections, mtimeMs, ctimeMs, size);
|
|
204
|
+
const needRead = !metadataCached || (includeBody && !bodyCached) || (includeCollections && !collectionsCached);
|
|
205
|
+
let lightMetadata;
|
|
206
|
+
let heavyMetadata;
|
|
136
207
|
let bodyLength;
|
|
137
208
|
let body;
|
|
138
209
|
if (needRead) {
|
|
@@ -142,31 +213,43 @@ export async function listAllDocumentCandidatesCached(pmRoot, preferredFormat, t
|
|
|
142
213
|
schema,
|
|
143
214
|
onWarning: (w) => appendWarning(warnings, w),
|
|
144
215
|
});
|
|
145
|
-
|
|
216
|
+
const split = splitHeavyMetadata(parsed.metadata);
|
|
217
|
+
lightMetadata = metadataCached ? cachedEntry.metadata : split.light;
|
|
146
218
|
bodyLength = metadataCached ? cachedEntry.body_length : parsed.body.length;
|
|
147
219
|
body = includeBody ? parsed.body : undefined;
|
|
220
|
+
if (includeCollections) {
|
|
221
|
+
heavyMetadata = collectionsCached ? cachedCollections.collections : split.heavy;
|
|
222
|
+
}
|
|
148
223
|
if (!metadataCached) {
|
|
149
224
|
metadataMiss = true;
|
|
150
225
|
}
|
|
151
226
|
if (includeBody && !bodyCached) {
|
|
152
227
|
bodyMiss = true;
|
|
153
228
|
}
|
|
229
|
+
if (includeCollections && !collectionsCached) {
|
|
230
|
+
collectionsMiss = true;
|
|
231
|
+
}
|
|
154
232
|
}
|
|
155
233
|
else {
|
|
156
|
-
|
|
234
|
+
lightMetadata = cachedEntry.metadata;
|
|
157
235
|
bodyLength = cachedEntry.body_length;
|
|
158
236
|
body = includeBody ? cachedBody.body : undefined;
|
|
237
|
+
heavyMetadata = includeCollections && cachedCollections ? cachedCollections.collections : undefined;
|
|
159
238
|
}
|
|
160
239
|
newEntries[relativePath] = {
|
|
161
240
|
mtime_ms: mtimeMs,
|
|
162
241
|
ctime_ms: ctimeMs,
|
|
163
242
|
size,
|
|
164
|
-
metadata,
|
|
243
|
+
metadata: lightMetadata,
|
|
165
244
|
body_length: bodyLength,
|
|
166
245
|
};
|
|
167
246
|
if (includeBody && body !== undefined) {
|
|
168
247
|
newBodies[relativePath] = { mtime_ms: mtimeMs, ctime_ms: ctimeMs, size, body };
|
|
169
248
|
}
|
|
249
|
+
if (includeCollections && heavyMetadata !== undefined) {
|
|
250
|
+
newCollections[relativePath] = { mtime_ms: mtimeMs, ctime_ms: ctimeMs, size, collections: heavyMetadata };
|
|
251
|
+
}
|
|
252
|
+
const metadata = includeCollections ? mergeHeavyMetadata(lightMetadata, heavyMetadata) : lightMetadata;
|
|
170
253
|
const existing = documentsById.get(metadata.id);
|
|
171
254
|
const candidate = {
|
|
172
255
|
metadata,
|
|
@@ -213,6 +296,18 @@ export async function listAllDocumentCandidatesCached(pmRoot, preferredFormat, t
|
|
|
213
296
|
}).catch(() => { });
|
|
214
297
|
}
|
|
215
298
|
}
|
|
299
|
+
if (includeCollections) {
|
|
300
|
+
const collectionsDirty = collectionsMiss || Object.keys(previousCollections).length !== Object.keys(newCollections).length;
|
|
301
|
+
if (collectionsDirty ||
|
|
302
|
+
existingCollectionsCache === null ||
|
|
303
|
+
existingCollectionsCache.context_fingerprint !== contextFingerprint) {
|
|
304
|
+
await persistCache(getCollectionsCachePath(pmRoot), {
|
|
305
|
+
version: CACHE_VERSION,
|
|
306
|
+
context_fingerprint: contextFingerprint,
|
|
307
|
+
collections: newCollections,
|
|
308
|
+
}).catch(() => { });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
216
311
|
return [...documentsById.values()]
|
|
217
312
|
.sort((left, right) => left.candidate.metadata.id.localeCompare(right.candidate.metadata.id))
|
|
218
313
|
.map((entry) => entry.candidate);
|
|
@@ -226,5 +321,21 @@ export async function listAllDocumentsCached(pmRoot, preferredFormat, typeToFold
|
|
|
226
321
|
body: candidate.body ?? "",
|
|
227
322
|
}));
|
|
228
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Light variant of {@link listAllDocumentsCached}: returns metadata WITHOUT the heavy
|
|
326
|
+
* collection fields (comments/notes/learnings/files/tests/test_runs/docs), skipping the
|
|
327
|
+
* large collections cache entirely. Only safe for callers that read just the light
|
|
328
|
+
* scalar/small fields (id/title/status/type/priority/parent/tags/dates/dependencies/…).
|
|
329
|
+
*/
|
|
330
|
+
export async function listAllDocumentsCachedLight(pmRoot, preferredFormat, typeToFolder, warnings, schema) {
|
|
331
|
+
const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, {
|
|
332
|
+
includeBody: false,
|
|
333
|
+
includeCollections: false,
|
|
334
|
+
});
|
|
335
|
+
return candidates.map((candidate) => ({
|
|
336
|
+
metadata: candidate.metadata,
|
|
337
|
+
body: candidate.body ?? "",
|
|
338
|
+
}));
|
|
339
|
+
}
|
|
229
340
|
//# sourceMappingURL=front-matter-cache.js.map
|
|
230
|
-
//# debugId=
|
|
341
|
+
//# debugId=a14ed5c7-eb26-57d5-8b28-58d736a3c11c
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-matter-cache.js","sources":["core/store/front-matter-cache.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { hasActiveOnReadHooks, runActiveOnReadHooks } from \"../extensions/index.js\";\nimport { parseItemDocument } from \"../item/item-format.js\";\nimport { writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { ITEM_FILE_EXTENSIONS, getItemFormatFromPath } from \"./paths.js\";\nimport type { ItemDocument, ItemFormat, ItemMetadata, ItemType, RuntimeSchemaSettings } from \"../../types/index.js\";\n\nconst CACHE_VERSION = 5;\nconst CACHE_FILENAME = \"metadata-cache.json\";\nconst BODY_CACHE_FILENAME = \"metadata-cache-bodies.json\";\n\ninterface StatSignature {\n mtime_ms: number;\n ctime_ms: number;\n size: number;\n}\n\ninterface CachedEntry extends StatSignature {\n metadata: ItemMetadata;\n body_length: number;\n}\n\ninterface CachedBody extends StatSignature {\n body: string;\n}\n\ninterface CacheEnvelope {\n version: number;\n context_fingerprint: string;\n entries: Record<string, CachedEntry>;\n}\n\ninterface BodyCacheEnvelope {\n version: number;\n context_fingerprint: string;\n bodies: Record<string, CachedBody>;\n}\n\nexport interface CachedDocumentCandidate {\n metadata: ItemMetadata;\n body?: string;\n item_format: ItemFormat;\n item_path: string;\n}\n\nfunction computeContextFingerprint(\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n schema: RuntimeSchemaSettings | undefined,\n): string {\n const hash = createHash(\"sha256\");\n hash.update(`format:${preferredFormat ?? \"default\"}`);\n const sortedTypes = Object.entries(typeToFolder)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([type, folder]) => `${type}=${folder}`)\n .join(\",\");\n hash.update(`|types:${sortedTypes}`);\n if (schema) {\n hash.update(`|schema:${JSON.stringify(schema)}`);\n }\n return hash.digest(\"hex\").slice(0, 16);\n}\n\nfunction getCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", CACHE_FILENAME);\n}\n\nfunction getBodyCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", BODY_CACHE_FILENAME);\n}\n\nasync function loadCache(pmRoot: string): Promise<CacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as CacheEnvelope;\n if (parsed.version !== CACHE_VERSION || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function loadBodyCache(pmRoot: string): Promise<BodyCacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getBodyCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as BodyCacheEnvelope;\n if (parsed.version !== CACHE_VERSION || typeof parsed.bodies !== \"object\" || parsed.bodies === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function persistCache(cachePath: string, envelope: CacheEnvelope | BodyCacheEnvelope): Promise<void> {\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await writeFileAtomic(cachePath, JSON.stringify(envelope));\n}\n\nfunction appendWarning(warnings: string[] | undefined, warning: string): void {\n if (warnings && !warnings.includes(warning)) {\n warnings.push(warning);\n }\n}\n\nfunction statMatches(signature: StatSignature, mtimeMs: number, ctimeMs: number, size: number): boolean {\n return signature.mtime_ms === mtimeMs && signature.ctime_ms === ctimeMs && signature.size === size;\n}\n\nexport interface ListCacheOptions {\n /**\n * When false, item bodies are neither loaded from nor written to the separate\n * body cache. Metadata-only callers (`pm list`, stats, deps, activity, …) skip\n * the large body cache entirely; only body consumers (search/reindex) pay for it.\n */\n includeBody?: boolean;\n}\n\n/**\n * List all item documents using a persistent on-disk metadata cache.\n *\n * Metadata and bodies are stored in two separate cache files so the hot path\n * (`pm list` and friends, which discard bodies) never loads or rewrites the much\n * larger body payload. Each file is rewritten only when its contents actually\n * change, and per-file onRead hooks are dispatched only when an extension\n * registers one. Only files whose mtime/ctime/size changed since the last run are\n * re-parsed.\n */\nexport async function listAllDocumentCandidatesCached(\n pmRoot: string,\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n warnings: string[] | undefined,\n schema: RuntimeSchemaSettings | undefined,\n options: ListCacheOptions = {},\n): Promise<CachedDocumentCandidate[]> {\n const includeBody = options.includeBody !== false;\n const contextFingerprint = computeContextFingerprint(preferredFormat, typeToFolder, schema);\n\n const existingCache = await loadCache(pmRoot);\n const previousEntries: Record<string, CachedEntry> =\n existingCache && existingCache.context_fingerprint === contextFingerprint ? existingCache.entries : {};\n\n const existingBodyCache = includeBody ? await loadBodyCache(pmRoot) : null;\n const previousBodies: Record<string, CachedBody> =\n existingBodyCache && existingBodyCache.context_fingerprint === contextFingerprint ? existingBodyCache.bodies : {};\n\n const entries = Object.entries(typeToFolder) as Array<[ItemType, string]>;\n const dirResults = await Promise.all(\n entries.map(async ([, folder]) => {\n const dirPath = path.join(pmRoot, folder);\n try {\n const files = await fs.readdir(dirPath);\n return { folder, dirPath, files };\n } catch (error: unknown) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code !== \"ENOENT\") {\n appendWarning(warnings, `item_list_directory_read_failed:${folder}`);\n }\n return { folder, dirPath, files: [] as string[] };\n }\n }),\n );\n\n const dispatchReadHooks = hasActiveOnReadHooks();\n const newEntries: Record<string, CachedEntry> = {};\n const newBodies: Record<string, CachedBody> = {};\n const documentsById = new Map<string, { candidate: CachedDocumentCandidate; itemFormat: ItemFormat }>();\n let metadataMiss = false;\n let bodyMiss = false;\n\n const parseTasks: Array<Promise<void>> = [];\n\n for (const { folder, dirPath, files } of dirResults) {\n for (const file of files) {\n if (!ITEM_FILE_EXTENSIONS.some((ext) => file.toLowerCase().endsWith(ext))) {\n continue;\n }\n const filePath = path.join(dirPath, file);\n const relativePath = path.relative(pmRoot, filePath);\n\n parseTasks.push(\n (async () => {\n try {\n const stat = await fs.stat(filePath);\n const mtimeMs = stat.mtimeMs;\n const ctimeMs = stat.ctimeMs;\n const { size } = stat;\n const itemFormat = getItemFormatFromPath(filePath) as ItemFormat;\n\n // Preserve onRead hook semantics even when served from cache, but only\n // when an extension actually observes reads. Surface hook warnings so\n // read-hook failures are not silently hidden.\n if (dispatchReadHooks) {\n for (const warning of await runActiveOnReadHooks({ path: filePath, scope: \"project\" })) {\n appendWarning(warnings, warning);\n }\n }\n\n const cachedEntry = previousEntries[relativePath];\n const metadataCached = cachedEntry !== undefined && statMatches(cachedEntry, mtimeMs, ctimeMs, size);\n const cachedBody = previousBodies[relativePath];\n const bodyCached = cachedBody !== undefined && statMatches(cachedBody, mtimeMs, ctimeMs, size);\n\n const needRead = !metadataCached || (includeBody && !bodyCached);\n let metadata: ItemMetadata;\n let bodyLength: number;\n let body: string | undefined;\n\n if (needRead) {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = parseItemDocument(raw, {\n format: itemFormat,\n schema,\n onWarning: (w) => appendWarning(warnings, w),\n });\n metadata = metadataCached ? cachedEntry.metadata : parsed.metadata;\n bodyLength = metadataCached ? cachedEntry.body_length : parsed.body.length;\n body = includeBody ? parsed.body : undefined;\n if (!metadataCached) {\n metadataMiss = true;\n }\n if (includeBody && !bodyCached) {\n bodyMiss = true;\n }\n } else {\n metadata = cachedEntry.metadata;\n bodyLength = cachedEntry.body_length;\n body = includeBody ? cachedBody.body : undefined;\n }\n\n newEntries[relativePath] = {\n mtime_ms: mtimeMs,\n ctime_ms: ctimeMs,\n size,\n metadata,\n body_length: bodyLength,\n };\n if (includeBody && body !== undefined) {\n newBodies[relativePath] = { mtime_ms: mtimeMs, ctime_ms: ctimeMs, size, body };\n }\n\n const existing = documentsById.get(metadata.id);\n const candidate: CachedDocumentCandidate = {\n metadata,\n body,\n item_format: itemFormat,\n item_path: filePath,\n };\n if (!existing) {\n documentsById.set(metadata.id, { candidate, itemFormat });\n } else {\n const shouldReplace = preferredFormat\n ? itemFormat === preferredFormat && existing.itemFormat !== preferredFormat\n : itemFormat === \"toon\" && existing.itemFormat !== \"toon\";\n if (shouldReplace) {\n documentsById.set(metadata.id, { candidate, itemFormat });\n }\n }\n } catch {\n appendWarning(warnings, `item_list_item_read_failed:${folder}/${file}`);\n }\n })(),\n );\n }\n }\n\n await Promise.all(parseTasks);\n\n // Rewrite a cache file only when its contents changed: any re-parsed (missing or\n // stale) entry, or a different set of keys (additions/deletions).\n const metadataDirty = metadataMiss || Object.keys(previousEntries).length !== Object.keys(newEntries).length;\n if (metadataDirty || existingCache === null || existingCache.context_fingerprint !== contextFingerprint) {\n await persistCache(getCachePath(pmRoot), {\n version: CACHE_VERSION,\n context_fingerprint: contextFingerprint,\n entries: newEntries,\n }).catch(() => {});\n }\n\n if (includeBody) {\n const bodyDirty = bodyMiss || Object.keys(previousBodies).length !== Object.keys(newBodies).length;\n if (bodyDirty || existingBodyCache === null || existingBodyCache.context_fingerprint !== contextFingerprint) {\n await persistCache(getBodyCachePath(pmRoot), {\n version: CACHE_VERSION,\n context_fingerprint: contextFingerprint,\n bodies: newBodies,\n }).catch(() => {});\n }\n }\n\n return [...documentsById.values()]\n .sort((left, right) => left.candidate.metadata.id.localeCompare(right.candidate.metadata.id))\n .map((entry) => entry.candidate);\n}\n\nexport async function listAllDocumentsCached(\n pmRoot: string,\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n warnings: string[] | undefined,\n schema: RuntimeSchemaSettings | undefined,\n): Promise<ItemDocument[]> {\n const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, {\n includeBody: false,\n });\n return candidates.map((candidate) => ({\n metadata: candidate.metadata,\n body: candidate.body ?? \"\",\n }));\n}\n"],"names":[],"mappings":"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","debugId":"10d5600e-92e0-5342-a6a7-6bb48f44a92f"}
|
|
1
|
+
{"version":3,"file":"front-matter-cache.js","sources":["core/store/front-matter-cache.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { hasActiveOnReadHooks, runActiveOnReadHooks } from \"../extensions/index.js\";\nimport { parseItemDocument } from \"../item/item-format.js\";\nimport { writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { ITEM_FILE_EXTENSIONS, getItemFormatFromPath } from \"./paths.js\";\nimport type { ItemDocument, ItemFormat, ItemMetadata, ItemType, RuntimeSchemaSettings } from \"../../types/index.js\";\n\nconst CACHE_VERSION = 6;\nconst CACHE_FILENAME = \"metadata-cache.json\";\nconst BODY_CACHE_FILENAME = \"metadata-cache-bodies.json\";\nconst COLLECTIONS_CACHE_FILENAME = \"metadata-cache-collections.json\";\n\n/**\n * Heavy \"collection\" front-matter fields. These arrays dominate the on-disk cache\n * (e.g. a single item's comment thread can be hundreds of KB) yet the hot list path\n * (`pm list`, stats, deps, activity, calendar, close) never reads them. They are\n * stored in a separate collections cache that is parsed only when a caller opts in\n * (`includeCollections`), keeping the always-loaded light cache an order of magnitude\n * smaller and its JSON.parse correspondingly cheaper.\n */\nexport const HEAVY_METADATA_KEYS = [\n \"comments\",\n \"notes\",\n \"learnings\",\n \"files\",\n \"tests\",\n \"test_runs\",\n \"docs\",\n] as const;\n\ninterface StatSignature {\n mtime_ms: number;\n ctime_ms: number;\n size: number;\n}\n\ninterface CachedEntry extends StatSignature {\n metadata: ItemMetadata;\n body_length: number;\n}\n\ninterface CachedBody extends StatSignature {\n body: string;\n}\n\ninterface CachedCollections extends StatSignature {\n collections: Record<string, unknown>;\n}\n\ninterface CacheEnvelope {\n version: number;\n context_fingerprint: string;\n entries: Record<string, CachedEntry>;\n}\n\ninterface BodyCacheEnvelope {\n version: number;\n context_fingerprint: string;\n bodies: Record<string, CachedBody>;\n}\n\ninterface CollectionsCacheEnvelope {\n version: number;\n context_fingerprint: string;\n collections: Record<string, CachedCollections>;\n}\n\n/**\n * Split parsed front-matter into the light scalar/small fields (everything except the\n * heavy collection arrays) and the heavy collection fields. Only keys that are actually\n * present are moved, so an item without comments stays without comments in both tiers.\n */\nfunction splitHeavyMetadata(metadata: ItemMetadata): {\n light: ItemMetadata;\n heavy: Record<string, unknown>;\n} {\n const light = { ...metadata } as Record<string, unknown>;\n const heavy: Record<string, unknown> = {};\n for (const key of HEAVY_METADATA_KEYS) {\n if (key in light) {\n heavy[key] = light[key];\n delete light[key];\n }\n }\n return { light: light as ItemMetadata, heavy };\n}\n\n/**\n * Recombine light metadata with cached heavy collection fields. Key order differs from\n * the on-disk document, but every downstream hash/serialization canonicalizes and\n * sorts keys (`stableStringify`), so the merged record is byte-identical once hashed.\n */\nfunction mergeHeavyMetadata(light: ItemMetadata, heavy: Record<string, unknown> | undefined): ItemMetadata {\n if (!heavy || Object.keys(heavy).length === 0) {\n return light;\n }\n return { ...light, ...heavy } as ItemMetadata;\n}\n\nexport interface CachedDocumentCandidate {\n metadata: ItemMetadata;\n body?: string;\n item_format: ItemFormat;\n item_path: string;\n}\n\nfunction computeContextFingerprint(\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n schema: RuntimeSchemaSettings | undefined,\n): string {\n const hash = createHash(\"sha256\");\n hash.update(`format:${preferredFormat ?? \"default\"}`);\n const sortedTypes = Object.entries(typeToFolder)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([type, folder]) => `${type}=${folder}`)\n .join(\",\");\n hash.update(`|types:${sortedTypes}`);\n if (schema) {\n hash.update(`|schema:${JSON.stringify(schema)}`);\n }\n return hash.digest(\"hex\").slice(0, 16);\n}\n\nfunction getCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", CACHE_FILENAME);\n}\n\nfunction getBodyCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", BODY_CACHE_FILENAME);\n}\n\nfunction getCollectionsCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", COLLECTIONS_CACHE_FILENAME);\n}\n\nasync function loadCache(pmRoot: string): Promise<CacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as CacheEnvelope;\n if (parsed.version !== CACHE_VERSION || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function loadBodyCache(pmRoot: string): Promise<BodyCacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getBodyCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as BodyCacheEnvelope;\n if (parsed.version !== CACHE_VERSION || typeof parsed.bodies !== \"object\" || parsed.bodies === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function loadCollectionsCache(pmRoot: string): Promise<CollectionsCacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getCollectionsCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as CollectionsCacheEnvelope;\n if (parsed.version !== CACHE_VERSION || typeof parsed.collections !== \"object\" || parsed.collections === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function persistCache(\n cachePath: string,\n envelope: CacheEnvelope | BodyCacheEnvelope | CollectionsCacheEnvelope,\n): Promise<void> {\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await writeFileAtomic(cachePath, JSON.stringify(envelope));\n}\n\nfunction appendWarning(warnings: string[] | undefined, warning: string): void {\n if (warnings && !warnings.includes(warning)) {\n warnings.push(warning);\n }\n}\n\nfunction statMatches(signature: StatSignature, mtimeMs: number, ctimeMs: number, size: number): boolean {\n return signature.mtime_ms === mtimeMs && signature.ctime_ms === ctimeMs && signature.size === size;\n}\n\nexport interface ListCacheOptions {\n /**\n * When false, item bodies are neither loaded from nor written to the separate\n * body cache. Metadata-only callers (`pm list`, stats, deps, activity, …) skip\n * the large body cache entirely; only body consumers (search/reindex) pay for it.\n */\n includeBody?: boolean;\n /**\n * When false, heavy collection fields (comments/notes/learnings/files/tests/\n * test_runs/docs) are neither loaded from nor written to the separate collections\n * cache, and are absent from the returned metadata. Light-only callers (`pm list`\n * compact, stats, deps, activity, calendar, close) skip the large collections cache\n * entirely. Defaults to true so any caller that does read those fields stays correct.\n */\n includeCollections?: boolean;\n}\n\n/**\n * List all item documents using a persistent on-disk metadata cache.\n *\n * Metadata and bodies are stored in two separate cache files so the hot path\n * (`pm list` and friends, which discard bodies) never loads or rewrites the much\n * larger body payload. Each file is rewritten only when its contents actually\n * change, and per-file onRead hooks are dispatched only when an extension\n * registers one. Only files whose mtime/ctime/size changed since the last run are\n * re-parsed.\n */\nexport async function listAllDocumentCandidatesCached(\n pmRoot: string,\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n warnings: string[] | undefined,\n schema: RuntimeSchemaSettings | undefined,\n options: ListCacheOptions = {},\n): Promise<CachedDocumentCandidate[]> {\n const includeBody = options.includeBody !== false;\n const includeCollections = options.includeCollections !== false;\n const contextFingerprint = computeContextFingerprint(preferredFormat, typeToFolder, schema);\n\n const existingCache = await loadCache(pmRoot);\n const previousEntries: Record<string, CachedEntry> =\n existingCache && existingCache.context_fingerprint === contextFingerprint ? existingCache.entries : {};\n\n const existingBodyCache = includeBody ? await loadBodyCache(pmRoot) : null;\n const previousBodies: Record<string, CachedBody> =\n existingBodyCache && existingBodyCache.context_fingerprint === contextFingerprint ? existingBodyCache.bodies : {};\n\n const existingCollectionsCache = includeCollections ? await loadCollectionsCache(pmRoot) : null;\n const previousCollections: Record<string, CachedCollections> =\n existingCollectionsCache && existingCollectionsCache.context_fingerprint === contextFingerprint\n ? existingCollectionsCache.collections\n : {};\n\n const entries = Object.entries(typeToFolder) as Array<[ItemType, string]>;\n const dirResults = await Promise.all(\n entries.map(async ([, folder]) => {\n const dirPath = path.join(pmRoot, folder);\n try {\n const files = await fs.readdir(dirPath);\n return { folder, dirPath, files };\n } catch (error: unknown) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code !== \"ENOENT\") {\n appendWarning(warnings, `item_list_directory_read_failed:${folder}`);\n }\n return { folder, dirPath, files: [] as string[] };\n }\n }),\n );\n\n const dispatchReadHooks = hasActiveOnReadHooks();\n const newEntries: Record<string, CachedEntry> = {};\n const newBodies: Record<string, CachedBody> = {};\n const newCollections: Record<string, CachedCollections> = {};\n const documentsById = new Map<string, { candidate: CachedDocumentCandidate; itemFormat: ItemFormat }>();\n let metadataMiss = false;\n let bodyMiss = false;\n let collectionsMiss = false;\n\n const parseTasks: Array<Promise<void>> = [];\n\n for (const { folder, dirPath, files } of dirResults) {\n for (const file of files) {\n if (!ITEM_FILE_EXTENSIONS.some((ext) => file.toLowerCase().endsWith(ext))) {\n continue;\n }\n const filePath = path.join(dirPath, file);\n const relativePath = path.relative(pmRoot, filePath);\n\n parseTasks.push(\n (async () => {\n try {\n const stat = await fs.stat(filePath);\n const mtimeMs = stat.mtimeMs;\n const ctimeMs = stat.ctimeMs;\n const { size } = stat;\n const itemFormat = getItemFormatFromPath(filePath) as ItemFormat;\n\n // Preserve onRead hook semantics even when served from cache, but only\n // when an extension actually observes reads. Surface hook warnings so\n // read-hook failures are not silently hidden.\n if (dispatchReadHooks) {\n for (const warning of await runActiveOnReadHooks({ path: filePath, scope: \"project\" })) {\n appendWarning(warnings, warning);\n }\n }\n\n const cachedEntry = previousEntries[relativePath];\n const metadataCached = cachedEntry !== undefined && statMatches(cachedEntry, mtimeMs, ctimeMs, size);\n const cachedBody = previousBodies[relativePath];\n const bodyCached = cachedBody !== undefined && statMatches(cachedBody, mtimeMs, ctimeMs, size);\n const cachedCollections = previousCollections[relativePath];\n const collectionsCached =\n cachedCollections !== undefined && statMatches(cachedCollections, mtimeMs, ctimeMs, size);\n\n const needRead =\n !metadataCached || (includeBody && !bodyCached) || (includeCollections && !collectionsCached);\n let lightMetadata: ItemMetadata;\n let heavyMetadata: Record<string, unknown> | undefined;\n let bodyLength: number;\n let body: string | undefined;\n\n if (needRead) {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = parseItemDocument(raw, {\n format: itemFormat,\n schema,\n onWarning: (w) => appendWarning(warnings, w),\n });\n const split = splitHeavyMetadata(parsed.metadata);\n lightMetadata = metadataCached ? cachedEntry.metadata : split.light;\n bodyLength = metadataCached ? cachedEntry.body_length : parsed.body.length;\n body = includeBody ? parsed.body : undefined;\n if (includeCollections) {\n heavyMetadata = collectionsCached ? cachedCollections.collections : split.heavy;\n }\n if (!metadataCached) {\n metadataMiss = true;\n }\n if (includeBody && !bodyCached) {\n bodyMiss = true;\n }\n if (includeCollections && !collectionsCached) {\n collectionsMiss = true;\n }\n } else {\n lightMetadata = cachedEntry.metadata;\n bodyLength = cachedEntry.body_length;\n body = includeBody ? cachedBody.body : undefined;\n heavyMetadata = includeCollections && cachedCollections ? cachedCollections.collections : undefined;\n }\n\n newEntries[relativePath] = {\n mtime_ms: mtimeMs,\n ctime_ms: ctimeMs,\n size,\n metadata: lightMetadata,\n body_length: bodyLength,\n };\n if (includeBody && body !== undefined) {\n newBodies[relativePath] = { mtime_ms: mtimeMs, ctime_ms: ctimeMs, size, body };\n }\n if (includeCollections && heavyMetadata !== undefined) {\n newCollections[relativePath] = { mtime_ms: mtimeMs, ctime_ms: ctimeMs, size, collections: heavyMetadata };\n }\n\n const metadata = includeCollections ? mergeHeavyMetadata(lightMetadata, heavyMetadata) : lightMetadata;\n const existing = documentsById.get(metadata.id);\n const candidate: CachedDocumentCandidate = {\n metadata,\n body,\n item_format: itemFormat,\n item_path: filePath,\n };\n if (!existing) {\n documentsById.set(metadata.id, { candidate, itemFormat });\n } else {\n const shouldReplace = preferredFormat\n ? itemFormat === preferredFormat && existing.itemFormat !== preferredFormat\n : itemFormat === \"toon\" && existing.itemFormat !== \"toon\";\n if (shouldReplace) {\n documentsById.set(metadata.id, { candidate, itemFormat });\n }\n }\n } catch {\n appendWarning(warnings, `item_list_item_read_failed:${folder}/${file}`);\n }\n })(),\n );\n }\n }\n\n await Promise.all(parseTasks);\n\n // Rewrite a cache file only when its contents changed: any re-parsed (missing or\n // stale) entry, or a different set of keys (additions/deletions).\n const metadataDirty = metadataMiss || Object.keys(previousEntries).length !== Object.keys(newEntries).length;\n if (metadataDirty || existingCache === null || existingCache.context_fingerprint !== contextFingerprint) {\n await persistCache(getCachePath(pmRoot), {\n version: CACHE_VERSION,\n context_fingerprint: contextFingerprint,\n entries: newEntries,\n }).catch(() => {});\n }\n\n if (includeBody) {\n const bodyDirty = bodyMiss || Object.keys(previousBodies).length !== Object.keys(newBodies).length;\n if (bodyDirty || existingBodyCache === null || existingBodyCache.context_fingerprint !== contextFingerprint) {\n await persistCache(getBodyCachePath(pmRoot), {\n version: CACHE_VERSION,\n context_fingerprint: contextFingerprint,\n bodies: newBodies,\n }).catch(() => {});\n }\n }\n\n if (includeCollections) {\n const collectionsDirty =\n collectionsMiss || Object.keys(previousCollections).length !== Object.keys(newCollections).length;\n if (\n collectionsDirty ||\n existingCollectionsCache === null ||\n existingCollectionsCache.context_fingerprint !== contextFingerprint\n ) {\n await persistCache(getCollectionsCachePath(pmRoot), {\n version: CACHE_VERSION,\n context_fingerprint: contextFingerprint,\n collections: newCollections,\n }).catch(() => {});\n }\n }\n\n return [...documentsById.values()]\n .sort((left, right) => left.candidate.metadata.id.localeCompare(right.candidate.metadata.id))\n .map((entry) => entry.candidate);\n}\n\nexport async function listAllDocumentsCached(\n pmRoot: string,\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n warnings: string[] | undefined,\n schema: RuntimeSchemaSettings | undefined,\n): Promise<ItemDocument[]> {\n const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, {\n includeBody: false,\n });\n return candidates.map((candidate) => ({\n metadata: candidate.metadata,\n body: candidate.body ?? \"\",\n }));\n}\n\n/**\n * Light variant of {@link listAllDocumentsCached}: returns metadata WITHOUT the heavy\n * collection fields (comments/notes/learnings/files/tests/test_runs/docs), skipping the\n * large collections cache entirely. Only safe for callers that read just the light\n * scalar/small fields (id/title/status/type/priority/parent/tags/dates/dependencies/…).\n */\nexport async function listAllDocumentsCachedLight(\n pmRoot: string,\n preferredFormat: ItemFormat | undefined,\n typeToFolder: Record<string, string>,\n warnings: string[] | undefined,\n schema: RuntimeSchemaSettings | undefined,\n): Promise<ItemDocument[]> {\n const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, {\n includeBody: false,\n includeCollections: false,\n });\n return candidates.map((candidate) => ({\n metadata: candidate.metadata,\n body: candidate.body ?? \"\",\n }));\n}\n"],"names":[],"mappings":"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","debugId":"a14ed5c7-eb26-57d5-8b28-58d736a3c11c"}
|
|
@@ -1,9 +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]="e2b899c8-8eef-565d-ba07-ee451132eb0e")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { runActiveOnWriteHooks } from "../extensions/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { readFileIfExists, removeFileIfExists, writeFileAtomic } from "../fs/fs-utils.js";
|
|
7
7
|
import { parseItemDocument, serializeItemDocument } from "../item/item-format.js";
|
|
8
8
|
import { TYPE_TO_FOLDER } from "../shared/constants.js";
|
|
9
9
|
import { getItemFormatFromPath, getItemPath } from "./paths.js";
|
|
@@ -55,7 +55,16 @@ export async function migrateItemFilesToFormat(pmRoot, targetFormat, op = "item_
|
|
|
55
55
|
for (const itemId of itemIds) {
|
|
56
56
|
const variants = variantsById.get(itemId);
|
|
57
57
|
scanned += 1;
|
|
58
|
-
|
|
58
|
+
// Items already present only in the target format need no migration: there
|
|
59
|
+
// is no legacy alternate-format file to convert or remove. Skip the
|
|
60
|
+
// read/parse/serialize/compare round-trip for them. This is the dominant
|
|
61
|
+
// cost of the pre-mutation format sync, which runs on every mutation and
|
|
62
|
+
// would otherwise re-parse the entire corpus (O(items)) each time.
|
|
63
|
+
const alternatePath = variants[alternateFormat];
|
|
64
|
+
if (!alternatePath) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const sourcePath = variants[targetFormat] ?? alternatePath;
|
|
59
68
|
const sourceFormat = sourcePath === variants[targetFormat] ? targetFormat : alternateFormat;
|
|
60
69
|
try {
|
|
61
70
|
const sourceRaw = await fs.readFile(sourcePath, "utf8");
|
|
@@ -76,17 +85,18 @@ export async function migrateItemFilesToFormat(pmRoot, targetFormat, op = "item_
|
|
|
76
85
|
})));
|
|
77
86
|
migratedIds.add(itemId);
|
|
78
87
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
88
|
+
// The legacy alternate (.md) was enumerated from disk above and is always
|
|
89
|
+
// a distinct path from the .toon target, so once the parse succeeds we
|
|
90
|
+
// remove it unconditionally. removeFileIfExists tolerates a concurrently
|
|
91
|
+
// removed file, so no pre-check is needed.
|
|
92
|
+
await removeFileIfExists(alternatePath);
|
|
93
|
+
removedPaths.add(normalizeRelativePath(pmRoot, alternatePath));
|
|
94
|
+
warnings.push(...(await runActiveOnWriteHooks({
|
|
95
|
+
path: alternatePath,
|
|
96
|
+
scope: "project",
|
|
97
|
+
op: `${op}:remove`,
|
|
98
|
+
})));
|
|
99
|
+
migratedIds.add(itemId);
|
|
90
100
|
}
|
|
91
101
|
catch (error) {
|
|
92
102
|
warnings.push(`item_format_migration_skipped:${normalizeRelativePath(pmRoot, sourcePath)}:${errorSummary(error)}`);
|
|
@@ -102,4 +112,4 @@ export async function migrateItemFilesToFormat(pmRoot, targetFormat, op = "item_
|
|
|
102
112
|
};
|
|
103
113
|
}
|
|
104
114
|
//# sourceMappingURL=item-format-migration.js.map
|
|
105
|
-
//# debugId=
|
|
115
|
+
//# debugId=e2b899c8-8eef-565d-ba07-ee451132eb0e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-format-migration.js","sources":["core/store/item-format-migration.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { runActiveOnWriteHooks } from \"../extensions/index.js\";\nimport { pathExists, readFileIfExists, removeFileIfExists, writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { parseItemDocument, serializeItemDocument } from \"../item/item-format.js\";\nimport { TYPE_TO_FOLDER } from \"../shared/constants.js\";\nimport { getItemFormatFromPath, getItemPath } from \"./paths.js\";\nimport type { ItemFormat, ItemType, RuntimeSchemaSettings } from \"../../types/index.js\";\n\ninterface ItemPathVariants {\n json_markdown?: string;\n toon?: string;\n}\n\nexport interface ItemFormatMigrationResult {\n target_format: ItemFormat;\n scanned: number;\n migrated: string[];\n removed: string[];\n warnings: string[];\n}\n\nfunction alternateItemFormat(_targetFormat: ItemFormat): ItemFormat {\n return \"json_markdown\";\n}\n\nfunction normalizeRelativePath(pmRoot: string, absolutePath: string): string {\n return path.relative(pmRoot, absolutePath).replaceAll(\"\\\\\", \"/\");\n}\n\nfunction errorSummary(error: unknown): string {\n return String(error).replaceAll(/[^a-zA-Z0-9._-]+/g, \"_\").slice(0, 120);\n}\n\nexport async function migrateItemFilesToFormat(\n pmRoot: string,\n targetFormat: ItemFormat,\n op = \"item_format:migrate\",\n typeToFolder: Record<string, string> = TYPE_TO_FOLDER,\n schema?: RuntimeSchemaSettings,\n): Promise<ItemFormatMigrationResult> {\n if (targetFormat !== \"toon\") {\n throw new Error(\"Only toon item-format migration targets are supported. Markdown item files are legacy read-only input.\");\n }\n const migratedIds = new Set<string>();\n const removedPaths = new Set<string>();\n const warnings: string[] = [];\n let scanned = 0;\n const alternateFormat = alternateItemFormat(targetFormat);\n const typeEntries = Object.entries(typeToFolder) as Array<[ItemType, string]>;\n\n for (const [itemType, folder] of typeEntries) {\n const directoryPath = path.join(pmRoot, folder);\n let files: string[] = [];\n try {\n files = await fs.readdir(directoryPath);\n } catch {\n continue;\n }\n\n const variantsById = new Map<string, ItemPathVariants>();\n for (const file of files) {\n const absolutePath = path.join(directoryPath, file);\n const itemFormat = getItemFormatFromPath(absolutePath);\n if (!itemFormat) {\n continue;\n }\n const extension = path.extname(file);\n const itemId = file.slice(0, file.length - extension.length).trim();\n if (itemId.length === 0) {\n continue;\n }\n const entry = variantsById.get(itemId) ?? {};\n entry[itemFormat] = absolutePath;\n variantsById.set(itemId, entry);\n }\n\n const itemIds = [...variantsById.keys()].sort((left, right) => left.localeCompare(right));\n for (const itemId of itemIds) {\n const variants = variantsById.get(itemId) as ItemPathVariants;\n scanned += 1;\n const sourcePath = (variants[targetFormat] ?? variants[alternateFormat]) as string;\n const sourceFormat = sourcePath === variants[targetFormat] ? targetFormat : alternateFormat;\n try {\n const sourceRaw = await fs.readFile(sourcePath, \"utf8\");\n const parsedDocument = parseItemDocument(sourceRaw, {\n format: sourceFormat,\n schema,\n onWarning: (warning) => warnings.push(`item_format_migration_parse_warning:${itemId}:${warning}`),\n });\n const targetPath = getItemPath(pmRoot, itemType, itemId, targetFormat, typeToFolder);\n const serializedTarget = serializeItemDocument(parsedDocument, { format: targetFormat, schema });\n const existingTargetRaw = await readFileIfExists(targetPath);\n if (existingTargetRaw !== serializedTarget) {\n await writeFileAtomic(targetPath, serializedTarget);\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: targetPath,\n scope: \"project\",\n op,\n })),\n );\n migratedIds.add(itemId);\n }\n\n const alternatePath = variants[alternateFormat];\n if (alternatePath && alternatePath !== targetPath && (await pathExists(alternatePath))) {\n await removeFileIfExists(alternatePath);\n removedPaths.add(normalizeRelativePath(pmRoot, alternatePath));\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: alternatePath,\n scope: \"project\",\n op: `${op}:remove`,\n })),\n );\n migratedIds.add(itemId);\n }\n } catch (error) {\n warnings.push(\n `item_format_migration_skipped:${normalizeRelativePath(pmRoot, sourcePath)}:${errorSummary(error)}`,\n );\n }\n }\n }\n\n return {\n target_format: targetFormat,\n scanned,\n migrated: [...migratedIds].sort((left, right) => left.localeCompare(right)),\n removed: [...removedPaths].sort((left, right) => left.localeCompare(right)),\n warnings,\n };\n}\n"],"names":[],"mappings":"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","debugId":"930ae1b6-e1d4-53f6-844b-8e79ce44a235"}
|
|
1
|
+
{"version":3,"file":"item-format-migration.js","sources":["core/store/item-format-migration.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { runActiveOnWriteHooks } from \"../extensions/index.js\";\nimport { readFileIfExists, removeFileIfExists, writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { parseItemDocument, serializeItemDocument } from \"../item/item-format.js\";\nimport { TYPE_TO_FOLDER } from \"../shared/constants.js\";\nimport { getItemFormatFromPath, getItemPath } from \"./paths.js\";\nimport type { ItemFormat, ItemType, RuntimeSchemaSettings } from \"../../types/index.js\";\n\ninterface ItemPathVariants {\n json_markdown?: string;\n toon?: string;\n}\n\nexport interface ItemFormatMigrationResult {\n target_format: ItemFormat;\n scanned: number;\n migrated: string[];\n removed: string[];\n warnings: string[];\n}\n\nfunction alternateItemFormat(_targetFormat: ItemFormat): ItemFormat {\n return \"json_markdown\";\n}\n\nfunction normalizeRelativePath(pmRoot: string, absolutePath: string): string {\n return path.relative(pmRoot, absolutePath).replaceAll(\"\\\\\", \"/\");\n}\n\nfunction errorSummary(error: unknown): string {\n return String(error).replaceAll(/[^a-zA-Z0-9._-]+/g, \"_\").slice(0, 120);\n}\n\nexport async function migrateItemFilesToFormat(\n pmRoot: string,\n targetFormat: ItemFormat,\n op = \"item_format:migrate\",\n typeToFolder: Record<string, string> = TYPE_TO_FOLDER,\n schema?: RuntimeSchemaSettings,\n): Promise<ItemFormatMigrationResult> {\n if (targetFormat !== \"toon\") {\n throw new Error(\"Only toon item-format migration targets are supported. Markdown item files are legacy read-only input.\");\n }\n const migratedIds = new Set<string>();\n const removedPaths = new Set<string>();\n const warnings: string[] = [];\n let scanned = 0;\n const alternateFormat = alternateItemFormat(targetFormat);\n const typeEntries = Object.entries(typeToFolder) as Array<[ItemType, string]>;\n\n for (const [itemType, folder] of typeEntries) {\n const directoryPath = path.join(pmRoot, folder);\n let files: string[] = [];\n try {\n files = await fs.readdir(directoryPath);\n } catch {\n continue;\n }\n\n const variantsById = new Map<string, ItemPathVariants>();\n for (const file of files) {\n const absolutePath = path.join(directoryPath, file);\n const itemFormat = getItemFormatFromPath(absolutePath);\n if (!itemFormat) {\n continue;\n }\n const extension = path.extname(file);\n const itemId = file.slice(0, file.length - extension.length).trim();\n if (itemId.length === 0) {\n continue;\n }\n const entry = variantsById.get(itemId) ?? {};\n entry[itemFormat] = absolutePath;\n variantsById.set(itemId, entry);\n }\n\n const itemIds = [...variantsById.keys()].sort((left, right) => left.localeCompare(right));\n for (const itemId of itemIds) {\n const variants = variantsById.get(itemId) as ItemPathVariants;\n scanned += 1;\n // Items already present only in the target format need no migration: there\n // is no legacy alternate-format file to convert or remove. Skip the\n // read/parse/serialize/compare round-trip for them. This is the dominant\n // cost of the pre-mutation format sync, which runs on every mutation and\n // would otherwise re-parse the entire corpus (O(items)) each time.\n const alternatePath = variants[alternateFormat];\n if (!alternatePath) {\n continue;\n }\n const sourcePath = variants[targetFormat] ?? alternatePath;\n const sourceFormat = sourcePath === variants[targetFormat] ? targetFormat : alternateFormat;\n try {\n const sourceRaw = await fs.readFile(sourcePath, \"utf8\");\n const parsedDocument = parseItemDocument(sourceRaw, {\n format: sourceFormat,\n schema,\n onWarning: (warning) => warnings.push(`item_format_migration_parse_warning:${itemId}:${warning}`),\n });\n const targetPath = getItemPath(pmRoot, itemType, itemId, targetFormat, typeToFolder);\n const serializedTarget = serializeItemDocument(parsedDocument, { format: targetFormat, schema });\n const existingTargetRaw = await readFileIfExists(targetPath);\n if (existingTargetRaw !== serializedTarget) {\n await writeFileAtomic(targetPath, serializedTarget);\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: targetPath,\n scope: \"project\",\n op,\n })),\n );\n migratedIds.add(itemId);\n }\n\n // The legacy alternate (.md) was enumerated from disk above and is always\n // a distinct path from the .toon target, so once the parse succeeds we\n // remove it unconditionally. removeFileIfExists tolerates a concurrently\n // removed file, so no pre-check is needed.\n await removeFileIfExists(alternatePath);\n removedPaths.add(normalizeRelativePath(pmRoot, alternatePath));\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: alternatePath,\n scope: \"project\",\n op: `${op}:remove`,\n })),\n );\n migratedIds.add(itemId);\n } catch (error) {\n warnings.push(\n `item_format_migration_skipped:${normalizeRelativePath(pmRoot, sourcePath)}:${errorSummary(error)}`,\n );\n }\n }\n }\n\n return {\n target_format: targetFormat,\n scanned,\n migrated: [...migratedIds].sort((left, right) => left.localeCompare(right)),\n removed: [...removedPaths].sort((left, right) => left.localeCompare(right)),\n warnings,\n };\n}\n"],"names":[],"mappings":"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","debugId":"e2b899c8-8eef-565d-ba07-ee451132eb0e"}
|
|
@@ -15,6 +15,13 @@ export declare function readLocatedItem(item: LocatedItem, options?: {
|
|
|
15
15
|
document: ItemDocument;
|
|
16
16
|
}>;
|
|
17
17
|
export declare function listAllFrontMatter(pmRoot: string, preferredFormat?: ItemFormat, typeToFolder?: Record<string, string>, warnings?: string[], schema?: RuntimeSchemaSettings): Promise<ItemFrontMatter[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Light variant of {@link listAllFrontMatter}: returns front-matter WITHOUT the heavy
|
|
20
|
+
* collection fields (comments/notes/learnings/files/tests/test_runs/docs). Skips the
|
|
21
|
+
* large collections cache so the hot list path stays cheap. Only use for callers that
|
|
22
|
+
* read just the light scalar/small fields — see {@link listAllDocumentsCachedLight}.
|
|
23
|
+
*/
|
|
24
|
+
export declare function listAllFrontMatterLight(pmRoot: string, preferredFormat?: ItemFormat, typeToFolder?: Record<string, string>, warnings?: string[], schema?: RuntimeSchemaSettings): Promise<ItemFrontMatter[]>;
|
|
18
25
|
export declare function listAllFrontMatterWithBody(pmRoot: string, preferredFormat?: ItemFormat, typeToFolder?: Record<string, string>, warnings?: string[], schema?: RuntimeSchemaSettings): Promise<Array<ItemFrontMatter & {
|
|
19
26
|
body: string;
|
|
20
27
|
}>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
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]="e156425f-15da-5c83-b5e6-6c1c1271bf05")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { getActiveExtensionRegistrations, runActiveOnReadHooks, runActiveOnWriteHooks, runActiveServiceOverride, } from "../extensions/index.js";
|
|
@@ -12,7 +12,7 @@ import { resolveItemTypeRegistry } from "../item/type-registry.js";
|
|
|
12
12
|
import { acquireLock } from "../lock/lock.js";
|
|
13
13
|
import { writeFileAtomic } from "../fs/fs-utils.js";
|
|
14
14
|
import { normalizeItemId, normalizeRawItemId } from "../item/id.js";
|
|
15
|
-
import { listAllDocumentCandidatesCached, listAllDocumentsCached } from "./front-matter-cache.js";
|
|
15
|
+
import { listAllDocumentCandidatesCached, listAllDocumentsCached, listAllDocumentsCachedLight } from "./front-matter-cache.js";
|
|
16
16
|
import { getHistoryPath, getItemPath, ITEM_FILE_EXTENSIONS } from "./paths.js";
|
|
17
17
|
import { resolveGovernanceKnobs } from "./settings.js";
|
|
18
18
|
import { nowIso } from "../shared/time.js";
|
|
@@ -85,6 +85,16 @@ export async function listAllFrontMatter(pmRoot, preferredFormat, typeToFolder =
|
|
|
85
85
|
const documents = await listAllDocumentsCached(pmRoot, preferredFormat, typeToFolder, warnings, schema);
|
|
86
86
|
return documents.map((document) => document.metadata);
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Light variant of {@link listAllFrontMatter}: returns front-matter WITHOUT the heavy
|
|
90
|
+
* collection fields (comments/notes/learnings/files/tests/test_runs/docs). Skips the
|
|
91
|
+
* large collections cache so the hot list path stays cheap. Only use for callers that
|
|
92
|
+
* read just the light scalar/small fields — see {@link listAllDocumentsCachedLight}.
|
|
93
|
+
*/
|
|
94
|
+
export async function listAllFrontMatterLight(pmRoot, preferredFormat, typeToFolder = TYPE_TO_FOLDER, warnings, schema) {
|
|
95
|
+
const documents = await listAllDocumentsCachedLight(pmRoot, preferredFormat, typeToFolder, warnings, schema);
|
|
96
|
+
return documents.map((document) => document.metadata);
|
|
97
|
+
}
|
|
88
98
|
export async function listAllFrontMatterWithBody(pmRoot, preferredFormat, typeToFolder = TYPE_TO_FOLDER, warnings, schema) {
|
|
89
99
|
const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, { includeBody: true });
|
|
90
100
|
return candidates.map((candidate) => ({
|
|
@@ -414,4 +424,4 @@ export async function deleteItem(params) {
|
|
|
414
424
|
}
|
|
415
425
|
}
|
|
416
426
|
//# sourceMappingURL=item-store.js.map
|
|
417
|
-
//# debugId=
|
|
427
|
+
//# debugId=e156425f-15da-5c83-b5e6-6c1c1271bf05
|