@unbrained/pm-cli 2026.3.9

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.
Files changed (245) hide show
  1. package/.pi/extensions/pm-cli/index.ts +778 -0
  2. package/AGENTS.md +475 -0
  3. package/LICENSE +21 -0
  4. package/PRD.md +1390 -0
  5. package/README.md +655 -0
  6. package/dist/cli/commands/activity.d.ts +14 -0
  7. package/dist/cli/commands/activity.js +80 -0
  8. package/dist/cli/commands/activity.js.map +1 -0
  9. package/dist/cli/commands/append.d.ts +13 -0
  10. package/dist/cli/commands/append.js +46 -0
  11. package/dist/cli/commands/append.js.map +1 -0
  12. package/dist/cli/commands/beads.d.ts +15 -0
  13. package/dist/cli/commands/beads.js +475 -0
  14. package/dist/cli/commands/beads.js.map +1 -0
  15. package/dist/cli/commands/claim.d.ts +19 -0
  16. package/dist/cli/commands/claim.js +79 -0
  17. package/dist/cli/commands/claim.js.map +1 -0
  18. package/dist/cli/commands/close.d.ts +12 -0
  19. package/dist/cli/commands/close.js +58 -0
  20. package/dist/cli/commands/close.js.map +1 -0
  21. package/dist/cli/commands/comments.d.ts +15 -0
  22. package/dist/cli/commands/comments.js +80 -0
  23. package/dist/cli/commands/comments.js.map +1 -0
  24. package/dist/cli/commands/completion.d.ts +10 -0
  25. package/dist/cli/commands/completion.js +469 -0
  26. package/dist/cli/commands/completion.js.map +1 -0
  27. package/dist/cli/commands/config.d.ts +15 -0
  28. package/dist/cli/commands/config.js +72 -0
  29. package/dist/cli/commands/config.js.map +1 -0
  30. package/dist/cli/commands/create.d.ts +60 -0
  31. package/dist/cli/commands/create.js +456 -0
  32. package/dist/cli/commands/create.js.map +1 -0
  33. package/dist/cli/commands/delete.d.ts +12 -0
  34. package/dist/cli/commands/delete.js +33 -0
  35. package/dist/cli/commands/delete.js.map +1 -0
  36. package/dist/cli/commands/docs.d.ts +16 -0
  37. package/dist/cli/commands/docs.js +113 -0
  38. package/dist/cli/commands/docs.js.map +1 -0
  39. package/dist/cli/commands/files.d.ts +17 -0
  40. package/dist/cli/commands/files.js +113 -0
  41. package/dist/cli/commands/files.js.map +1 -0
  42. package/dist/cli/commands/gc.d.ts +9 -0
  43. package/dist/cli/commands/gc.js +80 -0
  44. package/dist/cli/commands/gc.js.map +1 -0
  45. package/dist/cli/commands/get.d.ts +12 -0
  46. package/dist/cli/commands/get.js +28 -0
  47. package/dist/cli/commands/get.js.map +1 -0
  48. package/dist/cli/commands/health.d.ts +15 -0
  49. package/dist/cli/commands/health.js +288 -0
  50. package/dist/cli/commands/health.js.map +1 -0
  51. package/dist/cli/commands/history.d.ts +13 -0
  52. package/dist/cli/commands/history.js +72 -0
  53. package/dist/cli/commands/history.js.map +1 -0
  54. package/dist/cli/commands/index.d.ts +26 -0
  55. package/dist/cli/commands/index.js +27 -0
  56. package/dist/cli/commands/index.js.map +1 -0
  57. package/dist/cli/commands/init.d.ts +10 -0
  58. package/dist/cli/commands/init.js +59 -0
  59. package/dist/cli/commands/init.js.map +1 -0
  60. package/dist/cli/commands/install.d.ts +18 -0
  61. package/dist/cli/commands/install.js +87 -0
  62. package/dist/cli/commands/install.js.map +1 -0
  63. package/dist/cli/commands/list.d.ts +21 -0
  64. package/dist/cli/commands/list.js +137 -0
  65. package/dist/cli/commands/list.js.map +1 -0
  66. package/dist/cli/commands/reindex.d.ts +16 -0
  67. package/dist/cli/commands/reindex.js +154 -0
  68. package/dist/cli/commands/reindex.js.map +1 -0
  69. package/dist/cli/commands/restore.d.ts +20 -0
  70. package/dist/cli/commands/restore.js +208 -0
  71. package/dist/cli/commands/restore.js.map +1 -0
  72. package/dist/cli/commands/search.d.ts +45 -0
  73. package/dist/cli/commands/search.js +531 -0
  74. package/dist/cli/commands/search.js.map +1 -0
  75. package/dist/cli/commands/stats.d.ts +13 -0
  76. package/dist/cli/commands/stats.js +88 -0
  77. package/dist/cli/commands/stats.js.map +1 -0
  78. package/dist/cli/commands/test-all.d.ts +30 -0
  79. package/dist/cli/commands/test-all.js +157 -0
  80. package/dist/cli/commands/test-all.js.map +1 -0
  81. package/dist/cli/commands/test.d.ts +29 -0
  82. package/dist/cli/commands/test.js +492 -0
  83. package/dist/cli/commands/test.js.map +1 -0
  84. package/dist/cli/commands/update.d.ts +52 -0
  85. package/dist/cli/commands/update.js +467 -0
  86. package/dist/cli/commands/update.js.map +1 -0
  87. package/dist/cli/extension-command-options.d.ts +1 -0
  88. package/dist/cli/extension-command-options.js +76 -0
  89. package/dist/cli/extension-command-options.js.map +1 -0
  90. package/dist/cli/main.d.ts +2 -0
  91. package/dist/cli/main.js +1494 -0
  92. package/dist/cli/main.js.map +1 -0
  93. package/dist/cli.d.ts +2 -0
  94. package/dist/cli.js +3 -0
  95. package/dist/cli.js.map +1 -0
  96. package/dist/command-types.d.ts +1 -0
  97. package/dist/command-types.js +2 -0
  98. package/dist/command-types.js.map +1 -0
  99. package/dist/constants.d.ts +1 -0
  100. package/dist/constants.js +2 -0
  101. package/dist/constants.js.map +1 -0
  102. package/dist/core/extensions/builtins.d.ts +3 -0
  103. package/dist/core/extensions/builtins.js +47 -0
  104. package/dist/core/extensions/builtins.js.map +1 -0
  105. package/dist/core/extensions/index.d.ts +13 -0
  106. package/dist/core/extensions/index.js +88 -0
  107. package/dist/core/extensions/index.js.map +1 -0
  108. package/dist/core/extensions/loader.d.ts +301 -0
  109. package/dist/core/extensions/loader.js +917 -0
  110. package/dist/core/extensions/loader.js.map +1 -0
  111. package/dist/core/fs/fs-utils.d.ts +6 -0
  112. package/dist/core/fs/fs-utils.js +58 -0
  113. package/dist/core/fs/fs-utils.js.map +1 -0
  114. package/dist/core/fs/index.d.ts +1 -0
  115. package/dist/core/fs/index.js +2 -0
  116. package/dist/core/fs/index.js.map +1 -0
  117. package/dist/core/history/history.d.ts +12 -0
  118. package/dist/core/history/history.js +44 -0
  119. package/dist/core/history/history.js.map +1 -0
  120. package/dist/core/history/index.d.ts +1 -0
  121. package/dist/core/history/index.js +2 -0
  122. package/dist/core/history/index.js.map +1 -0
  123. package/dist/core/item/id.d.ts +3 -0
  124. package/dist/core/item/id.js +54 -0
  125. package/dist/core/item/id.js.map +1 -0
  126. package/dist/core/item/index.d.ts +3 -0
  127. package/dist/core/item/index.js +4 -0
  128. package/dist/core/item/index.js.map +1 -0
  129. package/dist/core/item/item-format.d.ts +9 -0
  130. package/dist/core/item/item-format.js +363 -0
  131. package/dist/core/item/item-format.js.map +1 -0
  132. package/dist/core/item/parse.d.ts +3 -0
  133. package/dist/core/item/parse.js +72 -0
  134. package/dist/core/item/parse.js.map +1 -0
  135. package/dist/core/lock/index.d.ts +1 -0
  136. package/dist/core/lock/index.js +2 -0
  137. package/dist/core/lock/index.js.map +1 -0
  138. package/dist/core/lock/lock.d.ts +1 -0
  139. package/dist/core/lock/lock.js +100 -0
  140. package/dist/core/lock/lock.js.map +1 -0
  141. package/dist/core/output/output.d.ts +7 -0
  142. package/dist/core/output/output.js +79 -0
  143. package/dist/core/output/output.js.map +1 -0
  144. package/dist/core/search/cache.d.ts +17 -0
  145. package/dist/core/search/cache.js +212 -0
  146. package/dist/core/search/cache.js.map +1 -0
  147. package/dist/core/search/embedding-batches.d.ts +7 -0
  148. package/dist/core/search/embedding-batches.js +54 -0
  149. package/dist/core/search/embedding-batches.js.map +1 -0
  150. package/dist/core/search/providers.d.ts +59 -0
  151. package/dist/core/search/providers.js +265 -0
  152. package/dist/core/search/providers.js.map +1 -0
  153. package/dist/core/search/vector-stores.d.ts +89 -0
  154. package/dist/core/search/vector-stores.js +546 -0
  155. package/dist/core/search/vector-stores.js.map +1 -0
  156. package/dist/core/shared/command-types.d.ts +7 -0
  157. package/dist/core/shared/command-types.js +2 -0
  158. package/dist/core/shared/command-types.js.map +1 -0
  159. package/dist/core/shared/constants.d.ts +19 -0
  160. package/dist/core/shared/constants.js +134 -0
  161. package/dist/core/shared/constants.js.map +1 -0
  162. package/dist/core/shared/errors.d.ts +4 -0
  163. package/dist/core/shared/errors.js +9 -0
  164. package/dist/core/shared/errors.js.map +1 -0
  165. package/dist/core/shared/index.d.ts +3 -0
  166. package/dist/core/shared/index.js +4 -0
  167. package/dist/core/shared/index.js.map +1 -0
  168. package/dist/core/shared/serialization.d.ts +3 -0
  169. package/dist/core/shared/serialization.js +70 -0
  170. package/dist/core/shared/serialization.js.map +1 -0
  171. package/dist/core/shared/time.d.ts +3 -0
  172. package/dist/core/shared/time.js +28 -0
  173. package/dist/core/shared/time.js.map +1 -0
  174. package/dist/core/store/index.d.ts +3 -0
  175. package/dist/core/store/index.js +4 -0
  176. package/dist/core/store/index.js.map +1 -0
  177. package/dist/core/store/item-store.d.ts +42 -0
  178. package/dist/core/store/item-store.js +186 -0
  179. package/dist/core/store/item-store.js.map +1 -0
  180. package/dist/core/store/paths.d.ts +8 -0
  181. package/dist/core/store/paths.js +29 -0
  182. package/dist/core/store/paths.js.map +1 -0
  183. package/dist/core/store/settings.d.ts +4 -0
  184. package/dist/core/store/settings.js +148 -0
  185. package/dist/core/store/settings.js.map +1 -0
  186. package/dist/errors.d.ts +1 -0
  187. package/dist/errors.js +2 -0
  188. package/dist/errors.js.map +1 -0
  189. package/dist/extensions/builtins/beads/index.d.ts +8 -0
  190. package/dist/extensions/builtins/beads/index.js +29 -0
  191. package/dist/extensions/builtins/beads/index.js.map +1 -0
  192. package/dist/extensions/builtins/todos/import-export.d.ts +26 -0
  193. package/dist/extensions/builtins/todos/import-export.js +460 -0
  194. package/dist/extensions/builtins/todos/import-export.js.map +1 -0
  195. package/dist/extensions/builtins/todos/index.d.ts +8 -0
  196. package/dist/extensions/builtins/todos/index.js +38 -0
  197. package/dist/extensions/builtins/todos/index.js.map +1 -0
  198. package/dist/fs-utils.d.ts +1 -0
  199. package/dist/fs-utils.js +2 -0
  200. package/dist/fs-utils.js.map +1 -0
  201. package/dist/history.d.ts +1 -0
  202. package/dist/history.js +2 -0
  203. package/dist/history.js.map +1 -0
  204. package/dist/id.d.ts +1 -0
  205. package/dist/id.js +2 -0
  206. package/dist/id.js.map +1 -0
  207. package/dist/item-format.d.ts +1 -0
  208. package/dist/item-format.js +2 -0
  209. package/dist/item-format.js.map +1 -0
  210. package/dist/item-store.d.ts +1 -0
  211. package/dist/item-store.js +2 -0
  212. package/dist/item-store.js.map +1 -0
  213. package/dist/lock.d.ts +1 -0
  214. package/dist/lock.js +2 -0
  215. package/dist/lock.js.map +1 -0
  216. package/dist/output.d.ts +1 -0
  217. package/dist/output.js +2 -0
  218. package/dist/output.js.map +1 -0
  219. package/dist/parse.d.ts +1 -0
  220. package/dist/parse.js +2 -0
  221. package/dist/parse.js.map +1 -0
  222. package/dist/paths.d.ts +1 -0
  223. package/dist/paths.js +2 -0
  224. package/dist/paths.js.map +1 -0
  225. package/dist/serialization.d.ts +1 -0
  226. package/dist/serialization.js +2 -0
  227. package/dist/serialization.js.map +1 -0
  228. package/dist/settings.d.ts +1 -0
  229. package/dist/settings.js +2 -0
  230. package/dist/settings.js.map +1 -0
  231. package/dist/time.d.ts +1 -0
  232. package/dist/time.js +2 -0
  233. package/dist/time.js.map +1 -0
  234. package/dist/types/index.d.ts +1 -0
  235. package/dist/types/index.js +2 -0
  236. package/dist/types/index.js.map +1 -0
  237. package/dist/types.d.ts +179 -0
  238. package/dist/types.js +21 -0
  239. package/dist/types.js.map +1 -0
  240. package/docs/ARCHITECTURE.md +246 -0
  241. package/docs/EXTENSIONS.md +329 -0
  242. package/docs/RELEASING.md +65 -0
  243. package/package.json +79 -0
  244. package/scripts/install.ps1 +112 -0
  245. package/scripts/install.sh +113 -0
@@ -0,0 +1,21 @@
1
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
2
+ import type { ItemFrontMatter, ItemStatus } from "../../types/index.js";
3
+ export interface ListOptions {
4
+ type?: string;
5
+ tag?: string;
6
+ priority?: string;
7
+ deadlineBefore?: string;
8
+ deadlineAfter?: string;
9
+ assignee?: string;
10
+ sprint?: string;
11
+ release?: string;
12
+ limit?: string;
13
+ excludeTerminal?: boolean;
14
+ }
15
+ export interface ListResult {
16
+ items: ItemFrontMatter[];
17
+ count: number;
18
+ filters: Record<string, unknown>;
19
+ now: string;
20
+ }
21
+ export declare function runList(status: ItemStatus | undefined, options: ListOptions, global: GlobalOptions): Promise<ListResult>;
@@ -0,0 +1,137 @@
1
+ import { pathExists } from "../../core/fs/fs-utils.js";
2
+ import { EXIT_CODE } from "../../core/shared/constants.js";
3
+ import { PmCliError } from "../../core/shared/errors.js";
4
+ import { nowIso, resolveIsoOrRelative } from "../../core/shared/time.js";
5
+ import { listAllFrontMatter } from "../../core/store/item-store.js";
6
+ import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
7
+ import { readSettings } from "../../core/store/settings.js";
8
+ const ITEM_TYPES_BY_LOWER = new Map([
9
+ ["epic", "Epic"],
10
+ ["feature", "Feature"],
11
+ ["task", "Task"],
12
+ ["chore", "Chore"],
13
+ ["issue", "Issue"],
14
+ ]);
15
+ function isTerminal(status) {
16
+ return status === "closed" || status === "canceled";
17
+ }
18
+ function sortItems(items) {
19
+ return [...items].sort((a, b) => {
20
+ const aTerminal = isTerminal(a.status);
21
+ const bTerminal = isTerminal(b.status);
22
+ if (aTerminal !== bTerminal) {
23
+ return aTerminal ? 1 : -1;
24
+ }
25
+ const byPriority = a.priority - b.priority;
26
+ if (byPriority !== 0)
27
+ return byPriority;
28
+ const byUpdated = b.updated_at.localeCompare(a.updated_at);
29
+ if (byUpdated !== 0)
30
+ return byUpdated;
31
+ return a.id.localeCompare(b.id);
32
+ });
33
+ }
34
+ function parsePriority(raw) {
35
+ if (raw === undefined)
36
+ return undefined;
37
+ const parsed = Number(raw);
38
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 4) {
39
+ throw new PmCliError("Priority filter must be 0..4", EXIT_CODE.USAGE);
40
+ }
41
+ return parsed;
42
+ }
43
+ function parseType(raw) {
44
+ if (raw === undefined)
45
+ return undefined;
46
+ const parsed = ITEM_TYPES_BY_LOWER.get(raw.trim().toLowerCase());
47
+ if (!parsed) {
48
+ throw new PmCliError("Type filter must be one of Epic|Feature|Task|Chore|Issue", EXIT_CODE.USAGE);
49
+ }
50
+ return parsed;
51
+ }
52
+ function parseDeadline(raw) {
53
+ if (raw === undefined)
54
+ return undefined;
55
+ return resolveIsoOrRelative(raw);
56
+ }
57
+ function parseLimit(raw) {
58
+ if (raw === undefined)
59
+ return undefined;
60
+ const parsed = Number(raw);
61
+ if (!Number.isInteger(parsed) || parsed < 0) {
62
+ throw new PmCliError("Limit filter must be a non-negative integer", EXIT_CODE.USAGE);
63
+ }
64
+ return parsed;
65
+ }
66
+ function applyFilters(items, status, options) {
67
+ const typeFilter = parseType(options.type);
68
+ const tagFilter = options.tag?.trim().toLowerCase();
69
+ const priorityFilter = parsePriority(options.priority);
70
+ const deadlineBefore = parseDeadline(options.deadlineBefore);
71
+ const deadlineAfter = parseDeadline(options.deadlineAfter);
72
+ const assigneeFilter = options.assignee?.trim();
73
+ const sprintFilter = options.sprint?.trim();
74
+ const releaseFilter = options.release?.trim();
75
+ return items.filter((item) => {
76
+ if (status && item.status !== status)
77
+ return false;
78
+ if (options.excludeTerminal && isTerminal(item.status))
79
+ return false;
80
+ if (typeFilter && item.type !== typeFilter)
81
+ return false;
82
+ if (tagFilter && !item.tags.includes(tagFilter))
83
+ return false;
84
+ if (priorityFilter !== undefined && item.priority !== priorityFilter)
85
+ return false;
86
+ if (deadlineBefore && (!item.deadline || item.deadline > deadlineBefore))
87
+ return false;
88
+ if (deadlineAfter && (!item.deadline || item.deadline < deadlineAfter))
89
+ return false;
90
+ if (assigneeFilter !== undefined) {
91
+ if (assigneeFilter.toLowerCase() === "none") {
92
+ if (item.assignee)
93
+ return false;
94
+ }
95
+ else {
96
+ if (item.assignee !== assigneeFilter)
97
+ return false;
98
+ }
99
+ }
100
+ if (sprintFilter !== undefined && item.sprint !== sprintFilter)
101
+ return false;
102
+ if (releaseFilter !== undefined && item.release !== releaseFilter)
103
+ return false;
104
+ return true;
105
+ });
106
+ }
107
+ export async function runList(status, options, global) {
108
+ const pmRoot = resolvePmRoot(process.cwd(), global.path);
109
+ if (!(await pathExists(getSettingsPath(pmRoot)))) {
110
+ throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
111
+ }
112
+ await readSettings(pmRoot);
113
+ const items = await listAllFrontMatter(pmRoot);
114
+ const filtered = applyFilters(items, status, options);
115
+ const sorted = sortItems(filtered);
116
+ const limit = parseLimit(options.limit);
117
+ const limited = limit === undefined ? sorted : sorted.slice(0, limit);
118
+ const now = nowIso();
119
+ return {
120
+ items: limited,
121
+ count: limited.length,
122
+ filters: {
123
+ status: status ?? null,
124
+ type: options.type ?? null,
125
+ tag: options.tag ?? null,
126
+ priority: options.priority ?? null,
127
+ deadline_before: options.deadlineBefore ?? null,
128
+ deadline_after: options.deadlineAfter ?? null,
129
+ assignee: options.assignee ?? null,
130
+ sprint: options.sprint ?? null,
131
+ release: options.release ?? null,
132
+ limit: options.limit ?? null,
133
+ },
134
+ now,
135
+ };
136
+ }
137
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
2
+ export interface ReindexOptions {
3
+ mode?: string;
4
+ }
5
+ export interface ReindexResult {
6
+ ok: boolean;
7
+ mode: "keyword" | "semantic" | "hybrid";
8
+ total_items: number;
9
+ artifacts: {
10
+ manifest: string;
11
+ embeddings: string;
12
+ };
13
+ warnings: string[];
14
+ generated_at: string;
15
+ }
16
+ export declare function runReindex(options: ReindexOptions, global: GlobalOptions): Promise<ReindexResult>;
@@ -0,0 +1,154 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { runActiveOnIndexHooks, runActiveOnReadHooks, runActiveOnWriteHooks } from "../../core/extensions/index.js";
4
+ import { pathExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
5
+ import { parseItemDocument } from "../../core/item/item-format.js";
6
+ import { executeEmbeddingBatchesWithRetry } from "../../core/search/embedding-batches.js";
7
+ import { resolveEmbeddingProviders } from "../../core/search/providers.js";
8
+ import { executeVectorUpsert, resolveVectorStores } from "../../core/search/vector-stores.js";
9
+ import { EXIT_CODE, TYPE_TO_FOLDER } from "../../core/shared/constants.js";
10
+ import { PmCliError } from "../../core/shared/errors.js";
11
+ import { nowIso } from "../../core/shared/time.js";
12
+ import { listAllFrontMatter } from "../../core/store/item-store.js";
13
+ import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
14
+ import { readSettings } from "../../core/store/settings.js";
15
+ const MANIFEST_PATH = "index/manifest.json";
16
+ const EMBEDDINGS_PATH = "search/embeddings.jsonl";
17
+ function parseMode(raw) {
18
+ const normalized = (raw ?? "keyword").trim().toLowerCase();
19
+ if (normalized === "keyword") {
20
+ return "keyword";
21
+ }
22
+ if (normalized === "semantic" || normalized === "hybrid") {
23
+ return normalized;
24
+ }
25
+ throw new PmCliError("Reindex mode must be one of keyword|semantic|hybrid", EXIT_CODE.USAGE);
26
+ }
27
+ async function loadDocuments(pmRoot) {
28
+ const items = await listAllFrontMatter(pmRoot);
29
+ const sortedItems = [...items].sort((a, b) => a.id.localeCompare(b.id));
30
+ const documents = [];
31
+ for (const item of sortedItems) {
32
+ const itemPath = path.join(pmRoot, TYPE_TO_FOLDER[item.type], `${item.id}.md`);
33
+ const raw = await fs.readFile(itemPath, "utf8");
34
+ await runActiveOnReadHooks({
35
+ path: itemPath,
36
+ scope: "project",
37
+ });
38
+ documents.push(parseItemDocument(raw));
39
+ }
40
+ return documents;
41
+ }
42
+ function buildKeywordRecord(document, mode) {
43
+ const item = document.front_matter;
44
+ return {
45
+ id: item.id,
46
+ mode,
47
+ updated_at: item.updated_at,
48
+ corpus: {
49
+ title: item.title,
50
+ description: item.description,
51
+ tags: item.tags,
52
+ status: item.status,
53
+ body: document.body,
54
+ comments: (item.comments ?? []).map((entry) => entry.text),
55
+ notes: (item.notes ?? []).map((entry) => entry.text),
56
+ learnings: (item.learnings ?? []).map((entry) => entry.text),
57
+ dependencies: (item.dependencies ?? []).map((entry) => ({
58
+ id: entry.id,
59
+ kind: entry.kind,
60
+ })),
61
+ },
62
+ };
63
+ }
64
+ function buildSemanticCorpusInput(document) {
65
+ return JSON.stringify(buildKeywordRecord(document, "semantic").corpus);
66
+ }
67
+ export async function runReindex(options, global) {
68
+ const requestedMode = parseMode(options.mode);
69
+ const pmRoot = resolvePmRoot(process.cwd(), global.path);
70
+ if (!(await pathExists(getSettingsPath(pmRoot)))) {
71
+ throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
72
+ }
73
+ const settings = await readSettings(pmRoot);
74
+ let activeEmbeddingProvider = null;
75
+ let activeVectorStore = null;
76
+ if (requestedMode !== "keyword") {
77
+ const providerResolution = resolveEmbeddingProviders(settings);
78
+ if (!providerResolution.active) {
79
+ throw new PmCliError(`Reindex mode '${requestedMode}' requires a configured embedding provider in settings.providers.openai or settings.providers.ollama`, EXIT_CODE.USAGE);
80
+ }
81
+ const vectorResolution = resolveVectorStores(settings);
82
+ if (!vectorResolution.active) {
83
+ throw new PmCliError(`Reindex mode '${requestedMode}' requires a configured vector store in settings.vector_store.qdrant or settings.vector_store.lancedb`, EXIT_CODE.USAGE);
84
+ }
85
+ activeEmbeddingProvider = providerResolution.active;
86
+ activeVectorStore = vectorResolution.active;
87
+ }
88
+ const mode = requestedMode;
89
+ const documents = await loadDocuments(pmRoot);
90
+ const generatedAt = nowIso();
91
+ const manifest = {
92
+ version: 1,
93
+ mode,
94
+ generated_at: generatedAt,
95
+ total_items: documents.length,
96
+ items: documents.map((document) => ({
97
+ id: document.front_matter.id,
98
+ type: document.front_matter.type,
99
+ status: document.front_matter.status,
100
+ priority: document.front_matter.priority,
101
+ updated_at: document.front_matter.updated_at,
102
+ })),
103
+ };
104
+ const manifestPath = path.join(pmRoot, MANIFEST_PATH);
105
+ const embeddingsPath = path.join(pmRoot, EMBEDDINGS_PATH);
106
+ const embeddingsLines = documents.map((document) => JSON.stringify(buildKeywordRecord(document, mode))).join("\n");
107
+ const semanticWarnings = [];
108
+ if (mode !== "keyword" && documents.length > 0 && activeEmbeddingProvider && activeVectorStore) {
109
+ const corpusInputs = documents.map((document) => buildSemanticCorpusInput(document));
110
+ const embeddingResult = await executeEmbeddingBatchesWithRetry(activeEmbeddingProvider, settings, corpusInputs);
111
+ semanticWarnings.push(...embeddingResult.warnings);
112
+ await executeVectorUpsert(activeVectorStore, documents.map((document, index) => ({
113
+ id: document.front_matter.id,
114
+ vector: embeddingResult.vectors[index],
115
+ payload: {
116
+ id: document.front_matter.id,
117
+ type: document.front_matter.type,
118
+ status: document.front_matter.status,
119
+ priority: document.front_matter.priority,
120
+ updated_at: document.front_matter.updated_at,
121
+ },
122
+ })));
123
+ }
124
+ await writeFileAtomic(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
125
+ await writeFileAtomic(embeddingsPath, `${embeddingsLines}\n`);
126
+ const hookWarnings = [
127
+ ...(await runActiveOnWriteHooks({
128
+ path: manifestPath,
129
+ scope: "project",
130
+ op: "reindex:manifest",
131
+ })),
132
+ ...(await runActiveOnWriteHooks({
133
+ path: embeddingsPath,
134
+ scope: "project",
135
+ op: "reindex:embeddings",
136
+ })),
137
+ ...(await runActiveOnIndexHooks({
138
+ mode,
139
+ total_items: documents.length,
140
+ })),
141
+ ];
142
+ return {
143
+ ok: true,
144
+ mode,
145
+ total_items: documents.length,
146
+ artifacts: {
147
+ manifest: MANIFEST_PATH,
148
+ embeddings: EMBEDDINGS_PATH,
149
+ },
150
+ warnings: [...semanticWarnings, ...hookWarnings],
151
+ generated_at: generatedAt,
152
+ };
153
+ }
154
+ //# sourceMappingURL=reindex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reindex.js","sourceRoot":"","sources":["../../../src/cli/commands/reindex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
2
+ import type { ItemFrontMatter } from "../../types/index.js";
3
+ export interface RestoreCommandOptions {
4
+ author?: string;
5
+ message?: string;
6
+ force?: boolean;
7
+ }
8
+ export interface RestoreResult {
9
+ item: ItemFrontMatter;
10
+ restored_from: {
11
+ kind: "version" | "timestamp";
12
+ target: string;
13
+ history_index: number;
14
+ entry_ts: string;
15
+ entry_op: string;
16
+ };
17
+ changed_fields: string[];
18
+ warnings: string[];
19
+ }
20
+ export declare function runRestore(id: string, target: string, options: RestoreCommandOptions, global: GlobalOptions): Promise<RestoreResult>;
@@ -0,0 +1,208 @@
1
+ import jsonPatch from "fast-json-patch";
2
+ import { pathExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
3
+ import { appendHistoryEntry, createHistoryEntry } from "../../core/history/history.js";
4
+ import { canonicalDocument, serializeItemDocument } from "../../core/item/item-format.js";
5
+ import { acquireLock } from "../../core/lock/lock.js";
6
+ import { EXIT_CODE, FRONT_MATTER_KEY_ORDER } from "../../core/shared/constants.js";
7
+ import { PmCliError } from "../../core/shared/errors.js";
8
+ import { nowIso } from "../../core/shared/time.js";
9
+ import { orderObject, sha256Hex, stableStringify } from "../../core/shared/serialization.js";
10
+ import { runActiveOnWriteHooks } from "../../core/extensions/index.js";
11
+ import { locateItem, readLocatedItem } from "../../core/store/item-store.js";
12
+ import { getHistoryPath, getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
13
+ import { readSettings } from "../../core/store/settings.js";
14
+ import { readHistoryEntries } from "./history.js";
15
+ const EMPTY_REPLAY_DOCUMENT = {
16
+ front_matter: {},
17
+ body: "",
18
+ };
19
+ function toAuthor(candidate, defaultAuthor) {
20
+ const resolved = candidate ?? process.env.PM_AUTHOR ?? defaultAuthor;
21
+ const trimmed = resolved.trim();
22
+ return trimmed || "unknown";
23
+ }
24
+ function toReplayDocument(document) {
25
+ const canonical = canonicalDocument(document);
26
+ return {
27
+ front_matter: orderObject(canonical.front_matter, FRONT_MATTER_KEY_ORDER),
28
+ body: canonical.body,
29
+ };
30
+ }
31
+ function replayHash(document) {
32
+ return sha256Hex(stableStringify(document));
33
+ }
34
+ function ensureReplayTarget(target, history) {
35
+ const trimmed = target.trim();
36
+ if (!trimmed) {
37
+ throw new PmCliError("Missing restore target. Use a timestamp or version number.", EXIT_CODE.USAGE);
38
+ }
39
+ if (/^\d+$/.test(trimmed)) {
40
+ const version = Number(trimmed);
41
+ if (!Number.isSafeInteger(version) || version < 1 || version > history.length) {
42
+ throw new PmCliError(`Restore version must be between 1 and ${history.length} for this item.`, EXIT_CODE.USAGE);
43
+ }
44
+ return {
45
+ kind: "version",
46
+ raw: trimmed,
47
+ historyIndex: version - 1,
48
+ };
49
+ }
50
+ const parsedTarget = Date.parse(trimmed);
51
+ if (!Number.isFinite(parsedTarget)) {
52
+ throw new PmCliError(`Invalid restore target "${target}". Use a positive version number or ISO timestamp.`, EXIT_CODE.USAGE);
53
+ }
54
+ let index = -1;
55
+ for (let i = 0; i < history.length; i += 1) {
56
+ const entryTimestamp = Date.parse(history[i].ts);
57
+ if (!Number.isFinite(entryTimestamp)) {
58
+ throw new PmCliError(`History for this item contains invalid timestamp at entry ${i + 1}.`, EXIT_CODE.GENERIC_FAILURE);
59
+ }
60
+ if (entryTimestamp <= parsedTarget) {
61
+ index = i;
62
+ }
63
+ }
64
+ if (index < 0) {
65
+ throw new PmCliError(`No history entries exist at or before timestamp ${trimmed}.`, EXIT_CODE.USAGE);
66
+ }
67
+ return {
68
+ kind: "timestamp",
69
+ raw: trimmed,
70
+ historyIndex: index,
71
+ };
72
+ }
73
+ function applyHistoryPatch(current, patch, entryNumber) {
74
+ try {
75
+ const applied = jsonPatch.applyPatch(structuredClone(current), patch, true, false).newDocument;
76
+ if (typeof applied !== "object" ||
77
+ applied === null ||
78
+ !("front_matter" in applied) ||
79
+ !("body" in applied) ||
80
+ typeof applied.body !== "string" ||
81
+ typeof applied.front_matter !== "object" ||
82
+ applied.front_matter === null) {
83
+ throw new PmCliError(`History replay produced an invalid document shape at entry ${entryNumber}.`, EXIT_CODE.GENERIC_FAILURE);
84
+ }
85
+ const replay = applied;
86
+ return {
87
+ front_matter: replay.front_matter,
88
+ body: replay.body,
89
+ };
90
+ }
91
+ catch (error) {
92
+ if (error instanceof PmCliError) {
93
+ throw error;
94
+ }
95
+ throw new PmCliError(`Failed to apply history patch at entry ${entryNumber}.`, EXIT_CODE.GENERIC_FAILURE);
96
+ }
97
+ }
98
+ function replayToTarget(history, targetIndex) {
99
+ let document = structuredClone(EMPTY_REPLAY_DOCUMENT);
100
+ for (let i = 0; i <= targetIndex; i += 1) {
101
+ const entry = history[i];
102
+ const beforeHash = replayHash(document);
103
+ if (beforeHash !== entry.before_hash) {
104
+ throw new PmCliError(`History hash mismatch before replay at entry ${i + 1}.`, EXIT_CODE.GENERIC_FAILURE);
105
+ }
106
+ document = applyHistoryPatch(document, entry.patch, i + 1);
107
+ const afterHash = replayHash(document);
108
+ if (afterHash !== entry.after_hash) {
109
+ throw new PmCliError(`History hash mismatch after replay at entry ${i + 1}.`, EXIT_CODE.GENERIC_FAILURE);
110
+ }
111
+ }
112
+ return document;
113
+ }
114
+ function changedFields(beforeDocument, afterDocument) {
115
+ const beforeReplay = toReplayDocument(beforeDocument);
116
+ const afterReplay = toReplayDocument(afterDocument);
117
+ const patch = jsonPatch.compare(beforeReplay, afterReplay);
118
+ const fields = new Set();
119
+ for (const op of patch) {
120
+ if (op.path === "/body" || op.path.startsWith("/body/")) {
121
+ fields.add("body");
122
+ continue;
123
+ }
124
+ const segment = op.path.replace(/^\/front_matter\/?/, "").split("/")[0];
125
+ fields.add(segment.replaceAll("~1", "/").replaceAll("~0", "~"));
126
+ }
127
+ return Array.from(fields).sort((a, b) => a.localeCompare(b));
128
+ }
129
+ export async function runRestore(id, target, options, global) {
130
+ const pmRoot = resolvePmRoot(process.cwd(), global.path);
131
+ if (!(await pathExists(getSettingsPath(pmRoot)))) {
132
+ throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
133
+ }
134
+ const settings = await readSettings(pmRoot);
135
+ const located = await locateItem(pmRoot, id, settings.id_prefix);
136
+ if (!located) {
137
+ throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);
138
+ }
139
+ const historyPath = getHistoryPath(pmRoot, located.id);
140
+ const history = await readHistoryEntries(historyPath, located.id);
141
+ if (history.length === 0) {
142
+ throw new PmCliError(`No history exists for ${located.id}; restore is unavailable.`, EXIT_CODE.NOT_FOUND);
143
+ }
144
+ const resolvedTarget = ensureReplayTarget(target, history);
145
+ const replayDocument = replayToTarget(history, resolvedTarget.historyIndex);
146
+ const restoredDocument = canonicalDocument({
147
+ front_matter: replayDocument.front_matter,
148
+ body: replayDocument.body,
149
+ });
150
+ if (restoredDocument.front_matter.id !== located.id) {
151
+ throw new PmCliError(`Restore target resolved to item ${restoredDocument.front_matter.id}, expected ${located.id}.`, EXIT_CODE.GENERIC_FAILURE);
152
+ }
153
+ const author = toAuthor(options.author, settings.author_default);
154
+ const releaseLock = await acquireLock(pmRoot, located.id, settings.locks.ttl_seconds, author, Boolean(options.force));
155
+ try {
156
+ const { raw: originalRaw, document: currentDocument } = await readLocatedItem(located);
157
+ const assigned = currentDocument.front_matter.assignee?.trim();
158
+ if (assigned && assigned !== author && !options.force) {
159
+ throw new PmCliError(`Item ${located.id} is assigned to ${assigned}. Use --force to override.`, EXIT_CODE.CONFLICT);
160
+ }
161
+ const serializedRestore = serializeItemDocument(restoredDocument);
162
+ await writeFileAtomic(located.itemPath, serializedRestore);
163
+ const historyEntry = createHistoryEntry({
164
+ nowIso: nowIso(),
165
+ author,
166
+ op: "restore",
167
+ before: currentDocument,
168
+ after: restoredDocument,
169
+ message: options.message,
170
+ });
171
+ try {
172
+ await appendHistoryEntry(historyPath, historyEntry);
173
+ }
174
+ catch (error) {
175
+ await writeFileAtomic(located.itemPath, originalRaw);
176
+ throw error;
177
+ }
178
+ const hookWarnings = [
179
+ ...(await runActiveOnWriteHooks({
180
+ path: located.itemPath,
181
+ scope: "project",
182
+ op: "restore",
183
+ })),
184
+ ...(await runActiveOnWriteHooks({
185
+ path: historyPath,
186
+ scope: "project",
187
+ op: "restore:history",
188
+ })),
189
+ ];
190
+ const targetEntry = history[resolvedTarget.historyIndex];
191
+ return {
192
+ item: restoredDocument.front_matter,
193
+ restored_from: {
194
+ kind: resolvedTarget.kind,
195
+ target: resolvedTarget.raw,
196
+ history_index: resolvedTarget.historyIndex + 1,
197
+ entry_ts: targetEntry.ts,
198
+ entry_op: targetEntry.op,
199
+ },
200
+ changed_fields: changedFields(currentDocument, restoredDocument),
201
+ warnings: hookWarnings,
202
+ };
203
+ }
204
+ finally {
205
+ await releaseLock();
206
+ }
207
+ }
208
+ //# sourceMappingURL=restore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../src/cli/commands/restore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
2
+ import type { ItemFrontMatter } from "../../types/index.js";
3
+ export interface SearchOptions {
4
+ mode?: string;
5
+ includeLinked?: boolean;
6
+ type?: string;
7
+ tag?: string;
8
+ priority?: string;
9
+ deadlineBefore?: string;
10
+ deadlineAfter?: string;
11
+ limit?: string;
12
+ }
13
+ type SearchMode = "keyword" | "semantic" | "hybrid";
14
+ export interface SearchHit {
15
+ item: ItemFrontMatter;
16
+ score: number;
17
+ matched_fields: string[];
18
+ }
19
+ export interface SearchResult {
20
+ query: string;
21
+ mode: SearchMode;
22
+ items: SearchHit[];
23
+ count: number;
24
+ filters: Record<string, unknown>;
25
+ now: string;
26
+ }
27
+ export interface SearchTuning {
28
+ title_exact_bonus: number;
29
+ title_weight: number;
30
+ description_weight: number;
31
+ tags_weight: number;
32
+ status_weight: number;
33
+ body_weight: number;
34
+ comments_weight: number;
35
+ notes_weight: number;
36
+ learnings_weight: number;
37
+ dependencies_weight: number;
38
+ linked_content_weight: number;
39
+ }
40
+ export declare function resolveSearchMaxResults(settings: unknown): number;
41
+ export declare function resolveSearchScoreThreshold(settings: unknown): number;
42
+ export declare function resolveHybridSemanticWeight(settings: unknown): number;
43
+ export declare function resolveSearchTuning(settings: unknown): SearchTuning;
44
+ export declare function runSearch(query: string, options: SearchOptions, global: GlobalOptions): Promise<SearchResult>;
45
+ export {};