@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.
- package/.pi/extensions/pm-cli/index.ts +778 -0
- package/AGENTS.md +475 -0
- package/LICENSE +21 -0
- package/PRD.md +1390 -0
- package/README.md +655 -0
- package/dist/cli/commands/activity.d.ts +14 -0
- package/dist/cli/commands/activity.js +80 -0
- package/dist/cli/commands/activity.js.map +1 -0
- package/dist/cli/commands/append.d.ts +13 -0
- package/dist/cli/commands/append.js +46 -0
- package/dist/cli/commands/append.js.map +1 -0
- package/dist/cli/commands/beads.d.ts +15 -0
- package/dist/cli/commands/beads.js +475 -0
- package/dist/cli/commands/beads.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +19 -0
- package/dist/cli/commands/claim.js +79 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/close.d.ts +12 -0
- package/dist/cli/commands/close.js +58 -0
- package/dist/cli/commands/close.js.map +1 -0
- package/dist/cli/commands/comments.d.ts +15 -0
- package/dist/cli/commands/comments.js +80 -0
- package/dist/cli/commands/comments.js.map +1 -0
- package/dist/cli/commands/completion.d.ts +10 -0
- package/dist/cli/commands/completion.js +469 -0
- package/dist/cli/commands/completion.js.map +1 -0
- package/dist/cli/commands/config.d.ts +15 -0
- package/dist/cli/commands/config.js +72 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/create.d.ts +60 -0
- package/dist/cli/commands/create.js +456 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +12 -0
- package/dist/cli/commands/delete.js +33 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/docs.d.ts +16 -0
- package/dist/cli/commands/docs.js +113 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/files.d.ts +17 -0
- package/dist/cli/commands/files.js +113 -0
- package/dist/cli/commands/files.js.map +1 -0
- package/dist/cli/commands/gc.d.ts +9 -0
- package/dist/cli/commands/gc.js +80 -0
- package/dist/cli/commands/gc.js.map +1 -0
- package/dist/cli/commands/get.d.ts +12 -0
- package/dist/cli/commands/get.js +28 -0
- package/dist/cli/commands/get.js.map +1 -0
- package/dist/cli/commands/health.d.ts +15 -0
- package/dist/cli/commands/health.js +288 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/history.d.ts +13 -0
- package/dist/cli/commands/history.js +72 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/index.d.ts +26 -0
- package/dist/cli/commands/index.js +27 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +59 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +18 -0
- package/dist/cli/commands/install.js +87 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/list.d.ts +21 -0
- package/dist/cli/commands/list.js +137 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/reindex.d.ts +16 -0
- package/dist/cli/commands/reindex.js +154 -0
- package/dist/cli/commands/reindex.js.map +1 -0
- package/dist/cli/commands/restore.d.ts +20 -0
- package/dist/cli/commands/restore.js +208 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/search.d.ts +45 -0
- package/dist/cli/commands/search.js +531 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +13 -0
- package/dist/cli/commands/stats.js +88 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/test-all.d.ts +30 -0
- package/dist/cli/commands/test-all.js +157 -0
- package/dist/cli/commands/test-all.js.map +1 -0
- package/dist/cli/commands/test.d.ts +29 -0
- package/dist/cli/commands/test.js +492 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/commands/update.d.ts +52 -0
- package/dist/cli/commands/update.js +467 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/extension-command-options.d.ts +1 -0
- package/dist/cli/extension-command-options.js +76 -0
- package/dist/cli/extension-command-options.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +1494 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-types.d.ts +1 -0
- package/dist/command-types.js +2 -0
- package/dist/command-types.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/extensions/builtins.d.ts +3 -0
- package/dist/core/extensions/builtins.js +47 -0
- package/dist/core/extensions/builtins.js.map +1 -0
- package/dist/core/extensions/index.d.ts +13 -0
- package/dist/core/extensions/index.js +88 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +301 -0
- package/dist/core/extensions/loader.js +917 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/fs/fs-utils.d.ts +6 -0
- package/dist/core/fs/fs-utils.js +58 -0
- package/dist/core/fs/fs-utils.js.map +1 -0
- package/dist/core/fs/index.d.ts +1 -0
- package/dist/core/fs/index.js +2 -0
- package/dist/core/fs/index.js.map +1 -0
- package/dist/core/history/history.d.ts +12 -0
- package/dist/core/history/history.js +44 -0
- package/dist/core/history/history.js.map +1 -0
- package/dist/core/history/index.d.ts +1 -0
- package/dist/core/history/index.js +2 -0
- package/dist/core/history/index.js.map +1 -0
- package/dist/core/item/id.d.ts +3 -0
- package/dist/core/item/id.js +54 -0
- package/dist/core/item/id.js.map +1 -0
- package/dist/core/item/index.d.ts +3 -0
- package/dist/core/item/index.js +4 -0
- package/dist/core/item/index.js.map +1 -0
- package/dist/core/item/item-format.d.ts +9 -0
- package/dist/core/item/item-format.js +363 -0
- package/dist/core/item/item-format.js.map +1 -0
- package/dist/core/item/parse.d.ts +3 -0
- package/dist/core/item/parse.js +72 -0
- package/dist/core/item/parse.js.map +1 -0
- package/dist/core/lock/index.d.ts +1 -0
- package/dist/core/lock/index.js +2 -0
- package/dist/core/lock/index.js.map +1 -0
- package/dist/core/lock/lock.d.ts +1 -0
- package/dist/core/lock/lock.js +100 -0
- package/dist/core/lock/lock.js.map +1 -0
- package/dist/core/output/output.d.ts +7 -0
- package/dist/core/output/output.js +79 -0
- package/dist/core/output/output.js.map +1 -0
- package/dist/core/search/cache.d.ts +17 -0
- package/dist/core/search/cache.js +212 -0
- package/dist/core/search/cache.js.map +1 -0
- package/dist/core/search/embedding-batches.d.ts +7 -0
- package/dist/core/search/embedding-batches.js +54 -0
- package/dist/core/search/embedding-batches.js.map +1 -0
- package/dist/core/search/providers.d.ts +59 -0
- package/dist/core/search/providers.js +265 -0
- package/dist/core/search/providers.js.map +1 -0
- package/dist/core/search/vector-stores.d.ts +89 -0
- package/dist/core/search/vector-stores.js +546 -0
- package/dist/core/search/vector-stores.js.map +1 -0
- package/dist/core/shared/command-types.d.ts +7 -0
- package/dist/core/shared/command-types.js +2 -0
- package/dist/core/shared/command-types.js.map +1 -0
- package/dist/core/shared/constants.d.ts +19 -0
- package/dist/core/shared/constants.js +134 -0
- package/dist/core/shared/constants.js.map +1 -0
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +9 -0
- package/dist/core/shared/errors.js.map +1 -0
- package/dist/core/shared/index.d.ts +3 -0
- package/dist/core/shared/index.js +4 -0
- package/dist/core/shared/index.js.map +1 -0
- package/dist/core/shared/serialization.d.ts +3 -0
- package/dist/core/shared/serialization.js +70 -0
- package/dist/core/shared/serialization.js.map +1 -0
- package/dist/core/shared/time.d.ts +3 -0
- package/dist/core/shared/time.js +28 -0
- package/dist/core/shared/time.js.map +1 -0
- package/dist/core/store/index.d.ts +3 -0
- package/dist/core/store/index.js +4 -0
- package/dist/core/store/index.js.map +1 -0
- package/dist/core/store/item-store.d.ts +42 -0
- package/dist/core/store/item-store.js +186 -0
- package/dist/core/store/item-store.js.map +1 -0
- package/dist/core/store/paths.d.ts +8 -0
- package/dist/core/store/paths.js +29 -0
- package/dist/core/store/paths.js.map +1 -0
- package/dist/core/store/settings.d.ts +4 -0
- package/dist/core/store/settings.js +148 -0
- package/dist/core/store/settings.js.map +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensions/builtins/beads/index.d.ts +8 -0
- package/dist/extensions/builtins/beads/index.js +29 -0
- package/dist/extensions/builtins/beads/index.js.map +1 -0
- package/dist/extensions/builtins/todos/import-export.d.ts +26 -0
- package/dist/extensions/builtins/todos/import-export.js +460 -0
- package/dist/extensions/builtins/todos/import-export.js.map +1 -0
- package/dist/extensions/builtins/todos/index.d.ts +8 -0
- package/dist/extensions/builtins/todos/index.js +38 -0
- package/dist/extensions/builtins/todos/index.js.map +1 -0
- package/dist/fs-utils.d.ts +1 -0
- package/dist/fs-utils.js +2 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/history.d.ts +1 -0
- package/dist/history.js +2 -0
- package/dist/history.js.map +1 -0
- package/dist/id.d.ts +1 -0
- package/dist/id.js +2 -0
- package/dist/id.js.map +1 -0
- package/dist/item-format.d.ts +1 -0
- package/dist/item-format.js +2 -0
- package/dist/item-format.js.map +1 -0
- package/dist/item-store.d.ts +1 -0
- package/dist/item-store.js +2 -0
- package/dist/item-store.js.map +1 -0
- package/dist/lock.d.ts +1 -0
- package/dist/lock.js +2 -0
- package/dist/lock.js.map +1 -0
- package/dist/output.d.ts +1 -0
- package/dist/output.js +2 -0
- package/dist/output.js.map +1 -0
- package/dist/parse.d.ts +1 -0
- package/dist/parse.js +2 -0
- package/dist/parse.js.map +1 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.js +2 -0
- package/dist/paths.js.map +1 -0
- package/dist/serialization.d.ts +1 -0
- package/dist/serialization.js +2 -0
- package/dist/serialization.js.map +1 -0
- package/dist/settings.d.ts +1 -0
- package/dist/settings.js +2 -0
- package/dist/settings.js.map +1 -0
- package/dist/time.d.ts +1 -0
- package/dist/time.js +2 -0
- package/dist/time.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types.d.ts +179 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/docs/ARCHITECTURE.md +246 -0
- package/docs/EXTENSIONS.md +329 -0
- package/docs/RELEASING.md +65 -0
- package/package.json +79 -0
- package/scripts/install.ps1 +112 -0
- package/scripts/install.sh +113 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./core/store/settings.js";
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
|
package/dist/time.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./core/shared/time.js";
|
package/dist/time.js
ADDED
package/dist/time.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
export declare const ITEM_TYPE_VALUES: readonly ["Epic", "Feature", "Task", "Chore", "Issue"];
|
|
2
|
+
export type ItemType = (typeof ITEM_TYPE_VALUES)[number];
|
|
3
|
+
export declare const STATUS_VALUES: readonly ["draft", "open", "in_progress", "blocked", "closed", "canceled"];
|
|
4
|
+
export type ItemStatus = (typeof STATUS_VALUES)[number];
|
|
5
|
+
export declare const DEPENDENCY_KIND_VALUES: readonly ["blocks", "parent", "child", "related", "discovered_from"];
|
|
6
|
+
export type DependencyKind = (typeof DEPENDENCY_KIND_VALUES)[number];
|
|
7
|
+
export declare const SCOPE_VALUES: readonly ["project", "global"];
|
|
8
|
+
export type LinkScope = (typeof SCOPE_VALUES)[number];
|
|
9
|
+
export declare const RISK_VALUES: readonly ["low", "medium", "high", "critical"];
|
|
10
|
+
export type RiskLevel = (typeof RISK_VALUES)[number];
|
|
11
|
+
export declare const ISSUE_SEVERITY_VALUES: readonly ["low", "medium", "high", "critical"];
|
|
12
|
+
export type IssueSeverity = (typeof ISSUE_SEVERITY_VALUES)[number];
|
|
13
|
+
export declare const CONFIDENCE_TEXT_VALUES: readonly ["low", "medium", "high"];
|
|
14
|
+
export type ConfidenceTextLevel = (typeof CONFIDENCE_TEXT_VALUES)[number];
|
|
15
|
+
export type ConfidenceValue = number | ConfidenceTextLevel;
|
|
16
|
+
export interface Dependency {
|
|
17
|
+
id: string;
|
|
18
|
+
kind: DependencyKind;
|
|
19
|
+
created_at: string;
|
|
20
|
+
author?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Comment {
|
|
23
|
+
created_at: string;
|
|
24
|
+
author: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}
|
|
27
|
+
export interface LogNote {
|
|
28
|
+
created_at: string;
|
|
29
|
+
author: string;
|
|
30
|
+
text: string;
|
|
31
|
+
}
|
|
32
|
+
export interface LinkedFile {
|
|
33
|
+
path: string;
|
|
34
|
+
scope: LinkScope;
|
|
35
|
+
note?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface LinkedTest {
|
|
38
|
+
command?: string;
|
|
39
|
+
path?: string;
|
|
40
|
+
scope: LinkScope;
|
|
41
|
+
timeout_seconds?: number;
|
|
42
|
+
note?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface LinkedDoc {
|
|
45
|
+
path: string;
|
|
46
|
+
scope: LinkScope;
|
|
47
|
+
note?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ItemFrontMatter {
|
|
50
|
+
id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
description: string;
|
|
53
|
+
type: ItemType;
|
|
54
|
+
status: ItemStatus;
|
|
55
|
+
priority: 0 | 1 | 2 | 3 | 4;
|
|
56
|
+
tags: string[];
|
|
57
|
+
created_at: string;
|
|
58
|
+
updated_at: string;
|
|
59
|
+
deadline?: string;
|
|
60
|
+
assignee?: string;
|
|
61
|
+
author?: string;
|
|
62
|
+
estimated_minutes?: number;
|
|
63
|
+
acceptance_criteria?: string;
|
|
64
|
+
definition_of_ready?: string;
|
|
65
|
+
order?: number;
|
|
66
|
+
goal?: string;
|
|
67
|
+
objective?: string;
|
|
68
|
+
value?: string;
|
|
69
|
+
impact?: string;
|
|
70
|
+
outcome?: string;
|
|
71
|
+
why_now?: string;
|
|
72
|
+
parent?: string;
|
|
73
|
+
reviewer?: string;
|
|
74
|
+
risk?: "low" | "medium" | "high" | "critical";
|
|
75
|
+
confidence?: ConfidenceValue;
|
|
76
|
+
sprint?: string;
|
|
77
|
+
release?: string;
|
|
78
|
+
blocked_by?: string;
|
|
79
|
+
blocked_reason?: string;
|
|
80
|
+
unblock_note?: string;
|
|
81
|
+
reporter?: string;
|
|
82
|
+
severity?: IssueSeverity;
|
|
83
|
+
environment?: string;
|
|
84
|
+
repro_steps?: string;
|
|
85
|
+
resolution?: string;
|
|
86
|
+
expected_result?: string;
|
|
87
|
+
actual_result?: string;
|
|
88
|
+
affected_version?: string;
|
|
89
|
+
fixed_version?: string;
|
|
90
|
+
component?: string;
|
|
91
|
+
regression?: boolean;
|
|
92
|
+
customer_impact?: string;
|
|
93
|
+
dependencies?: Dependency[];
|
|
94
|
+
comments?: Comment[];
|
|
95
|
+
notes?: LogNote[];
|
|
96
|
+
learnings?: LogNote[];
|
|
97
|
+
files?: LinkedFile[];
|
|
98
|
+
tests?: LinkedTest[];
|
|
99
|
+
docs?: LinkedDoc[];
|
|
100
|
+
close_reason?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface ItemDocument {
|
|
103
|
+
front_matter: ItemFrontMatter;
|
|
104
|
+
body: string;
|
|
105
|
+
}
|
|
106
|
+
export interface HistoryPatchOp {
|
|
107
|
+
op: "add" | "remove" | "replace" | "move" | "copy" | "test";
|
|
108
|
+
path: string;
|
|
109
|
+
from?: string;
|
|
110
|
+
value?: unknown;
|
|
111
|
+
}
|
|
112
|
+
export interface HistoryEntry {
|
|
113
|
+
ts: string;
|
|
114
|
+
author: string;
|
|
115
|
+
op: string;
|
|
116
|
+
patch: HistoryPatchOp[];
|
|
117
|
+
before_hash: string;
|
|
118
|
+
after_hash: string;
|
|
119
|
+
message?: string;
|
|
120
|
+
}
|
|
121
|
+
export interface PmSettings {
|
|
122
|
+
version: number;
|
|
123
|
+
id_prefix: string;
|
|
124
|
+
author_default: string;
|
|
125
|
+
locks: {
|
|
126
|
+
ttl_seconds: number;
|
|
127
|
+
};
|
|
128
|
+
output: {
|
|
129
|
+
default_format: "toon" | "json";
|
|
130
|
+
};
|
|
131
|
+
workflow: {
|
|
132
|
+
definition_of_done: string[];
|
|
133
|
+
};
|
|
134
|
+
extensions: {
|
|
135
|
+
enabled: string[];
|
|
136
|
+
disabled: string[];
|
|
137
|
+
};
|
|
138
|
+
search: {
|
|
139
|
+
score_threshold: number;
|
|
140
|
+
hybrid_semantic_weight: number;
|
|
141
|
+
max_results: number;
|
|
142
|
+
embedding_model: string;
|
|
143
|
+
embedding_batch_size: number;
|
|
144
|
+
scanner_max_batch_retries: number;
|
|
145
|
+
tuning?: {
|
|
146
|
+
title_exact_bonus?: number;
|
|
147
|
+
title_weight?: number;
|
|
148
|
+
description_weight?: number;
|
|
149
|
+
tags_weight?: number;
|
|
150
|
+
status_weight?: number;
|
|
151
|
+
body_weight?: number;
|
|
152
|
+
comments_weight?: number;
|
|
153
|
+
notes_weight?: number;
|
|
154
|
+
learnings_weight?: number;
|
|
155
|
+
dependencies_weight?: number;
|
|
156
|
+
linked_content_weight?: number;
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
providers: {
|
|
160
|
+
openai: {
|
|
161
|
+
base_url: string;
|
|
162
|
+
api_key: string;
|
|
163
|
+
model: string;
|
|
164
|
+
};
|
|
165
|
+
ollama: {
|
|
166
|
+
base_url: string;
|
|
167
|
+
model: string;
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
vector_store: {
|
|
171
|
+
qdrant: {
|
|
172
|
+
url: string;
|
|
173
|
+
api_key: string;
|
|
174
|
+
};
|
|
175
|
+
lancedb: {
|
|
176
|
+
path: string;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const ITEM_TYPE_VALUES = ["Epic", "Feature", "Task", "Chore", "Issue"];
|
|
2
|
+
export const STATUS_VALUES = [
|
|
3
|
+
"draft",
|
|
4
|
+
"open",
|
|
5
|
+
"in_progress",
|
|
6
|
+
"blocked",
|
|
7
|
+
"closed",
|
|
8
|
+
"canceled",
|
|
9
|
+
];
|
|
10
|
+
export const DEPENDENCY_KIND_VALUES = [
|
|
11
|
+
"blocks",
|
|
12
|
+
"parent",
|
|
13
|
+
"child",
|
|
14
|
+
"related",
|
|
15
|
+
"discovered_from",
|
|
16
|
+
];
|
|
17
|
+
export const SCOPE_VALUES = ["project", "global"];
|
|
18
|
+
export const RISK_VALUES = ["low", "medium", "high", "critical"];
|
|
19
|
+
export const ISSUE_SEVERITY_VALUES = ["low", "medium", "high", "critical"];
|
|
20
|
+
export const CONFIDENCE_TEXT_VALUES = ["low", "medium", "high"];
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAGvF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO;IACP,MAAM;IACN,aAAa;IACb,SAAS;IACT,QAAQ;IACR,UAAU;CACF,CAAC;AAGX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,SAAS;IACT,iBAAiB;CACT,CAAC;AAGX,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAG1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAGpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# pm-cli Architecture
|
|
2
|
+
|
|
3
|
+
This document describes the internal architecture of `pm-cli` for contributors and maintainers.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`pm-cli` is a TypeScript ESM CLI built on Node.js 20+. It follows a clean separation between CLI wiring and domain logic:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
cli/ CLI layer: command registration, option parsing, output rendering
|
|
12
|
+
core/ Domain logic: storage, locking, history, search, extensions
|
|
13
|
+
extensions/ Built-in extension implementations (beads, todos)
|
|
14
|
+
types/ Shared TypeScript type definitions
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Source Tree
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
src/
|
|
21
|
+
cli.ts Main CLI entry (shim that imports cli/main.ts)
|
|
22
|
+
cli/
|
|
23
|
+
main.ts Command registration with commander; global option wiring
|
|
24
|
+
commands/
|
|
25
|
+
init.ts pm init
|
|
26
|
+
create.ts pm create (full schema flag surface)
|
|
27
|
+
get.ts pm get
|
|
28
|
+
update.ts pm update
|
|
29
|
+
append.ts pm append
|
|
30
|
+
close.ts pm close
|
|
31
|
+
delete.ts pm delete
|
|
32
|
+
claim.ts pm claim / release
|
|
33
|
+
release.ts (re-exports from claim.ts)
|
|
34
|
+
list.ts pm list (active-only: excludes closed/canceled) / list-all / list-* commands
|
|
35
|
+
comments.ts pm comments
|
|
36
|
+
files.ts pm files
|
|
37
|
+
docs.ts pm docs
|
|
38
|
+
test.ts pm test (add/remove/run linked tests)
|
|
39
|
+
test-all.ts pm test-all (orchestration)
|
|
40
|
+
search.ts pm search (keyword / semantic / hybrid)
|
|
41
|
+
reindex.ts pm reindex
|
|
42
|
+
history.ts pm history
|
|
43
|
+
activity.ts pm activity
|
|
44
|
+
restore.ts pm restore
|
|
45
|
+
stats.ts pm stats
|
|
46
|
+
health.ts pm health
|
|
47
|
+
gc.ts pm gc
|
|
48
|
+
config.ts pm config
|
|
49
|
+
install.ts pm install pi
|
|
50
|
+
completion.ts pm completion
|
|
51
|
+
beads.ts pm beads (subcommand router to built-in extension)
|
|
52
|
+
index.ts barrel re-export
|
|
53
|
+
extension-command-options.ts Loose option parser for dynamic extension commands
|
|
54
|
+
core/
|
|
55
|
+
extensions/
|
|
56
|
+
loader.ts Extension manifest discovery, load, activate
|
|
57
|
+
builtins.ts Built-in extension registrations
|
|
58
|
+
index.ts barrel
|
|
59
|
+
fs/
|
|
60
|
+
fs-utils.ts Atomic write, path existence, mkdirp
|
|
61
|
+
index.ts barrel
|
|
62
|
+
history/
|
|
63
|
+
history.ts RFC6902 patch generation, history append, replay
|
|
64
|
+
index.ts barrel
|
|
65
|
+
item/
|
|
66
|
+
id.ts ID generation (cryptographic random base36) and normalization
|
|
67
|
+
item-format.ts Item front-matter serializer (canonical key order, determinism)
|
|
68
|
+
parse.ts Markdown item file parser (JSON front-matter + body)
|
|
69
|
+
index.ts barrel
|
|
70
|
+
lock/
|
|
71
|
+
lock.ts Exclusive lock acquire/release with TTL and stale detection
|
|
72
|
+
index.ts barrel
|
|
73
|
+
output/
|
|
74
|
+
output.ts TOON / JSON output rendering
|
|
75
|
+
search/
|
|
76
|
+
cache.ts Keyword index artifact read/write (manifest.json + embeddings.jsonl)
|
|
77
|
+
embedding-batches.ts Deterministic batch embedding generation with retry
|
|
78
|
+
providers.ts OpenAI / Ollama embedding provider abstraction
|
|
79
|
+
vector-stores.ts Qdrant / LanceDB vector store abstraction
|
|
80
|
+
shared/
|
|
81
|
+
command-types.ts GlobalOptions, shared command type definitions
|
|
82
|
+
constants.ts Exit codes, required directory names
|
|
83
|
+
errors.ts PmCliError with exit code
|
|
84
|
+
serialization.ts Deterministic JSON serialization (stable key order)
|
|
85
|
+
time.ts ISO timestamp helpers, relative deadline parsing
|
|
86
|
+
index.ts barrel
|
|
87
|
+
store/
|
|
88
|
+
item-store.ts File-backed item CRUD with lock/atomic write contract
|
|
89
|
+
paths.ts PM root resolution (PM_PATH, --path, cwd)
|
|
90
|
+
settings.ts settings.json read/write
|
|
91
|
+
index.ts barrel
|
|
92
|
+
types/
|
|
93
|
+
index.ts ItemFrontMatter, ItemType, ItemStatus, Dependency, etc.
|
|
94
|
+
extensions/
|
|
95
|
+
builtins/
|
|
96
|
+
beads/
|
|
97
|
+
index.ts Beads JSONL import extension
|
|
98
|
+
todos/
|
|
99
|
+
index.ts todos extension activate()
|
|
100
|
+
import-export.ts todos import/export logic
|
|
101
|
+
command-types.ts (re-export shim)
|
|
102
|
+
constants.ts (re-export shim)
|
|
103
|
+
errors.ts (re-export shim)
|
|
104
|
+
... (other re-export shims for backward compat)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Item Storage
|
|
108
|
+
|
|
109
|
+
Each item is stored as a Markdown file:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
.agents/pm/
|
|
113
|
+
<type-plural>/<id>.md e.g. tasks/pm-a1b2.md
|
|
114
|
+
history/<id>.jsonl append-only RFC6902 patch log
|
|
115
|
+
locks/<id>.lock exclusive lock metadata (JSON)
|
|
116
|
+
settings.json project configuration
|
|
117
|
+
index/manifest.json keyword index cache (optional, rebuildable)
|
|
118
|
+
search/embeddings.jsonl keyword corpus records (optional, rebuildable)
|
|
119
|
+
extensions/ project-local extensions
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Item File Format
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
{
|
|
126
|
+
"id": "pm-a1b2",
|
|
127
|
+
"title": "...",
|
|
128
|
+
...
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Optional markdown body here.
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Fields are serialized in canonical key order (defined in `item-format.ts`).
|
|
135
|
+
|
|
136
|
+
## Mutation Contract
|
|
137
|
+
|
|
138
|
+
Every item mutation follows this sequence:
|
|
139
|
+
|
|
140
|
+
1. **Acquire lock** — exclusive open on `locks/<id>.lock`; reject if stale and no `--force`
|
|
141
|
+
2. **Read current item** — parse front-matter + body
|
|
142
|
+
3. **Compute `before_hash`** — SHA-256 of canonical `{ front_matter, body }` JSON
|
|
143
|
+
4. **Apply mutation** — in-memory model update
|
|
144
|
+
5. **Update `updated_at`** — every mutation must change this timestamp
|
|
145
|
+
6. **Compute patch + `after_hash`** — RFC6902 diff; SHA-256 of new canonical state
|
|
146
|
+
7. **Atomic write** — write to temp file; `rename` to target (single syscall, OS-atomic)
|
|
147
|
+
8. **Append history line** — JSONL append to `history/<id>.jsonl`
|
|
148
|
+
9. **Release lock** — unlink lock file
|
|
149
|
+
|
|
150
|
+
If step 7 or 8 fails, the item file is rolled back (if write succeeded) before returning failure.
|
|
151
|
+
|
|
152
|
+
## History and Restore
|
|
153
|
+
|
|
154
|
+
Each history entry is a JSONL line:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"ts": "ISO timestamp",
|
|
159
|
+
"author": "string",
|
|
160
|
+
"op": "create|update|append|...|restore",
|
|
161
|
+
"patch": [ /* RFC6902 ops */ ],
|
|
162
|
+
"before_hash": "sha256-hex",
|
|
163
|
+
"after_hash": "sha256-hex",
|
|
164
|
+
"message": "optional"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`pm restore <ID> <TIMESTAMP|VERSION>` replays patches from `op=create` through the target entry, rebuilding exact canonical state.
|
|
169
|
+
|
|
170
|
+
## Extension System
|
|
171
|
+
|
|
172
|
+
Extensions are Node.js modules with an `activate(api)` export:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
export function activate(api: ExtensionApi): void {
|
|
176
|
+
api.registerCommand({ name: "my command", run: async (args, opts, global) => { ... } });
|
|
177
|
+
api.hooks.beforeCommand((ctx) => { ... });
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Load order: **core built-ins → global (`~/.pm-cli/extensions/`) → project (`.agents/pm/extensions/`)**.
|
|
182
|
+
|
|
183
|
+
Project-local extensions override global by default. See [EXTENSIONS.md](./EXTENSIONS.md) for the full API reference.
|
|
184
|
+
|
|
185
|
+
## Search Architecture
|
|
186
|
+
|
|
187
|
+
- **Keyword mode** (always available): multi-factor lexical scoring with configurable field weights
|
|
188
|
+
- **Semantic mode** (requires provider + vector store config): embedding-based vector similarity
|
|
189
|
+
- **Hybrid mode** (default when semantic available): blended lexical + semantic ranking
|
|
190
|
+
|
|
191
|
+
Providers: OpenAI-compatible, Ollama
|
|
192
|
+
Vector stores: Qdrant, LanceDB
|
|
193
|
+
|
|
194
|
+
### Keyword Scoring
|
|
195
|
+
|
|
196
|
+
Each item is scored across: `title` (8×), `description` (5×), `tags` (6×), `status` (2×), `body` (1×), `comments`/`notes`/`learnings` (1× each), `dependencies` (3×). Exact title token matches add a bonus (10×).
|
|
197
|
+
|
|
198
|
+
Weights are configurable via `settings.json` under `search.tuning`.
|
|
199
|
+
|
|
200
|
+
## Configuration
|
|
201
|
+
|
|
202
|
+
`settings.json` is read from the PM root at startup. Key sections:
|
|
203
|
+
|
|
204
|
+
| Key | Description |
|
|
205
|
+
|-----|-------------|
|
|
206
|
+
| `id_prefix` | Prefix for generated IDs (default `pm-`) |
|
|
207
|
+
| `author_default` | Default author for mutations |
|
|
208
|
+
| `locks.ttl_seconds` | Lock TTL (default 1800) |
|
|
209
|
+
| `output.default_format` | `toon` or `json` |
|
|
210
|
+
| `search.*` | Search provider and tuning settings |
|
|
211
|
+
| `providers.openai` / `providers.ollama` | Embedding provider config |
|
|
212
|
+
| `vector_store.qdrant` / `vector_store.lancedb` | Vector store config |
|
|
213
|
+
|
|
214
|
+
Precedence: CLI flags > env vars (`PM_PATH`, `PM_AUTHOR`, etc.) > `settings.json` > hard defaults.
|
|
215
|
+
|
|
216
|
+
## Exit Codes
|
|
217
|
+
|
|
218
|
+
| Code | Meaning |
|
|
219
|
+
|------|---------|
|
|
220
|
+
| 0 | Success |
|
|
221
|
+
| 1 | Generic failure |
|
|
222
|
+
| 2 | Usage / invalid args |
|
|
223
|
+
| 3 | Not found |
|
|
224
|
+
| 4 | Conflict (lock / ownership) |
|
|
225
|
+
| 5 | Dependency failed (test-all) |
|
|
226
|
+
|
|
227
|
+
## Testing
|
|
228
|
+
|
|
229
|
+
Tests live in `tests/`:
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
tests/
|
|
233
|
+
unit/ Unit tests (item format, lock, search, commands, extensions, etc.)
|
|
234
|
+
integration/ Integration tests (CLI subprocess spawn, CI contract, README contract)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
All tests run in sandboxed temp directories (`PM_PATH` + `PM_GLOBAL_PATH` isolated per suite). Coverage is enforced at 100% for lines, branches, functions, and statements.
|
|
238
|
+
|
|
239
|
+
Run all tests:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
node scripts/run-tests.mjs test # sandbox-safe, tests only
|
|
243
|
+
node scripts/run-tests.mjs coverage # sandbox-safe, with coverage gate
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The `scripts/run-tests.mjs` wrapper creates a temp directory, sets `PM_PATH` and `PM_GLOBAL_PATH`, runs Vitest, then cleans up.
|