@unbrained/pm-cli 2026.5.6 → 2026.5.10

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 (197) hide show
  1. package/.agents/pm/extensions/.managed-extensions.json +2 -2
  2. package/.agents/pm/extensions/beads/runtime.js +4 -4
  3. package/.agents/pm/extensions/beads/runtime.ts +5 -5
  4. package/.agents/pm/extensions/todos/runtime.js +7 -7
  5. package/.agents/pm/extensions/todos/runtime.ts +10 -10
  6. package/.agents/skills/HARNESS_COMPATIBILITY.md +45 -0
  7. package/.agents/skills/README.md +21 -0
  8. package/.agents/skills/pm-developer/SKILL.md +73 -0
  9. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +48 -0
  10. package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
  11. package/.agents/skills/pm-extensions/SKILL.md +57 -0
  12. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
  13. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
  14. package/.agents/skills/pm-sdk/SKILL.md +50 -0
  15. package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
  16. package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
  17. package/.agents/skills/pm-user/SKILL.md +59 -0
  18. package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
  19. package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
  20. package/.claude-plugin/marketplace.json +38 -0
  21. package/.pi/README.md +26 -0
  22. package/.pi/extensions/pm-cli/index.js +147 -0
  23. package/.pi/prompts/pm-workflow.md +5 -0
  24. package/.pi/skills/pm-native/SKILL.md +40 -0
  25. package/.pi/skills/pm-release/SKILL.md +35 -0
  26. package/AGENTS.md +1 -1
  27. package/CHANGELOG.md +6 -0
  28. package/PRD.md +16 -16
  29. package/README.md +22 -4
  30. package/dist/cli/commands/claim.js +6 -6
  31. package/dist/cli/commands/claim.js.map +1 -1
  32. package/dist/cli/commands/close.js +9 -9
  33. package/dist/cli/commands/close.js.map +1 -1
  34. package/dist/cli/commands/comments.d.ts +2 -0
  35. package/dist/cli/commands/comments.js +57 -8
  36. package/dist/cli/commands/comments.js.map +1 -1
  37. package/dist/cli/commands/completion.js +33 -4
  38. package/dist/cli/commands/completion.js.map +1 -1
  39. package/dist/cli/commands/config.js +6 -3
  40. package/dist/cli/commands/config.js.map +1 -1
  41. package/dist/cli/commands/contracts.js +4 -1
  42. package/dist/cli/commands/contracts.js.map +1 -1
  43. package/dist/cli/commands/create.d.ts +2 -2
  44. package/dist/cli/commands/create.js +4 -4
  45. package/dist/cli/commands/create.js.map +1 -1
  46. package/dist/cli/commands/docs.js +4 -4
  47. package/dist/cli/commands/docs.js.map +1 -1
  48. package/dist/cli/commands/files.js +10 -10
  49. package/dist/cli/commands/files.js.map +1 -1
  50. package/dist/cli/commands/get.js +5 -5
  51. package/dist/cli/commands/get.js.map +1 -1
  52. package/dist/cli/commands/guide.d.ts +55 -0
  53. package/dist/cli/commands/guide.js +260 -0
  54. package/dist/cli/commands/guide.js.map +1 -0
  55. package/dist/cli/commands/health.js +1 -1
  56. package/dist/cli/commands/health.js.map +1 -1
  57. package/dist/cli/commands/history.js +30 -10
  58. package/dist/cli/commands/history.js.map +1 -1
  59. package/dist/cli/commands/index.d.ts +1 -0
  60. package/dist/cli/commands/index.js +1 -0
  61. package/dist/cli/commands/index.js.map +1 -1
  62. package/dist/cli/commands/learnings.js +3 -3
  63. package/dist/cli/commands/learnings.js.map +1 -1
  64. package/dist/cli/commands/notes.js +3 -3
  65. package/dist/cli/commands/notes.js.map +1 -1
  66. package/dist/cli/commands/reindex.js +18 -32
  67. package/dist/cli/commands/reindex.js.map +1 -1
  68. package/dist/cli/commands/restore.d.ts +2 -2
  69. package/dist/cli/commands/restore.js +44 -24
  70. package/dist/cli/commands/restore.js.map +1 -1
  71. package/dist/cli/commands/search.d.ts +2 -0
  72. package/dist/cli/commands/search.js +30 -21
  73. package/dist/cli/commands/search.js.map +1 -1
  74. package/dist/cli/commands/test-all.d.ts +2 -0
  75. package/dist/cli/commands/test-all.js +2 -0
  76. package/dist/cli/commands/test-all.js.map +1 -1
  77. package/dist/cli/commands/test.d.ts +1 -0
  78. package/dist/cli/commands/test.js +4 -3
  79. package/dist/cli/commands/test.js.map +1 -1
  80. package/dist/cli/commands/update.js +118 -118
  81. package/dist/cli/commands/update.js.map +1 -1
  82. package/dist/cli/commands/validate.js +1 -1
  83. package/dist/cli/commands/validate.js.map +1 -1
  84. package/dist/cli/guide-topics.d.ts +25 -0
  85. package/dist/cli/guide-topics.js +283 -0
  86. package/dist/cli/guide-topics.js.map +1 -0
  87. package/dist/cli/help-content.js +25 -1
  88. package/dist/cli/help-content.js.map +1 -1
  89. package/dist/cli/register-list-query.js +38 -1
  90. package/dist/cli/register-list-query.js.map +1 -1
  91. package/dist/cli/register-mutation.js +17 -4
  92. package/dist/cli/register-mutation.js.map +1 -1
  93. package/dist/cli/register-setup.js +1 -1
  94. package/dist/cli/register-setup.js.map +1 -1
  95. package/dist/core/history/history.js +32 -11
  96. package/dist/core/history/history.js.map +1 -1
  97. package/dist/core/item/item-format.d.ts +2 -2
  98. package/dist/core/item/item-format.js +16 -16
  99. package/dist/core/item/item-format.js.map +1 -1
  100. package/dist/core/schema/runtime-field-filters.js +1 -1
  101. package/dist/core/schema/runtime-field-filters.js.map +1 -1
  102. package/dist/core/schema/runtime-field-values.js +2 -2
  103. package/dist/core/schema/runtime-field-values.js.map +1 -1
  104. package/dist/core/schema/runtime-schema.d.ts +1 -1
  105. package/dist/core/schema/runtime-schema.js +3 -3
  106. package/dist/core/schema/runtime-schema.js.map +1 -1
  107. package/dist/core/search/cache.js +7 -21
  108. package/dist/core/search/cache.js.map +1 -1
  109. package/dist/core/search/corpus.d.ts +13 -0
  110. package/dist/core/search/corpus.js +74 -0
  111. package/dist/core/search/corpus.js.map +1 -0
  112. package/dist/core/search/embedding-batches.js +90 -30
  113. package/dist/core/search/embedding-batches.js.map +1 -1
  114. package/dist/core/sentry/instrument.d.ts +3 -1
  115. package/dist/core/sentry/instrument.js +93 -9
  116. package/dist/core/sentry/instrument.js.map +1 -1
  117. package/dist/core/shared/constants.d.ts +1 -1
  118. package/dist/core/shared/constants.js +1 -1
  119. package/dist/core/shared/constants.js.map +1 -1
  120. package/dist/core/store/front-matter-cache.d.ts +1 -1
  121. package/dist/core/store/front-matter-cache.js +13 -13
  122. package/dist/core/store/front-matter-cache.js.map +1 -1
  123. package/dist/core/store/item-format-migration.js +5 -2
  124. package/dist/core/store/item-format-migration.js.map +1 -1
  125. package/dist/core/store/item-store.js +16 -15
  126. package/dist/core/store/item-store.js.map +1 -1
  127. package/dist/core/store/paths.js +1 -1
  128. package/dist/core/store/paths.js.map +1 -1
  129. package/dist/core/store/settings.js +6 -1
  130. package/dist/core/store/settings.js.map +1 -1
  131. package/dist/core/test/item-test-run-tracking.js +2 -2
  132. package/dist/core/test/item-test-run-tracking.js.map +1 -1
  133. package/dist/mcp/server.d.ts +2 -0
  134. package/dist/mcp/server.js +405 -0
  135. package/dist/mcp/server.js.map +1 -0
  136. package/dist/pi/native.d.ts +5 -0
  137. package/dist/pi/native.js +183 -0
  138. package/dist/pi/native.js.map +1 -0
  139. package/dist/sdk/cli-contracts.d.ts +3 -1
  140. package/dist/sdk/cli-contracts.js +67 -2
  141. package/dist/sdk/cli-contracts.js.map +1 -1
  142. package/dist/types.d.ts +10 -2
  143. package/dist/types.js.map +1 -1
  144. package/docs/AGENT_GUIDE.md +15 -0
  145. package/docs/ARCHITECTURE.md +2 -2
  146. package/docs/CLAUDE_CODE_PLUGIN.md +186 -0
  147. package/docs/CODEX_PLUGIN.md +33 -0
  148. package/docs/COMMANDS.md +6 -2
  149. package/docs/CONFIGURATION.md +2 -8
  150. package/docs/EXTENSIONS.md +1 -0
  151. package/docs/PI_PACKAGE.md +56 -0
  152. package/docs/QUICKSTART.md +1 -0
  153. package/docs/README.md +30 -1
  154. package/docs/RELEASING.md +4 -2
  155. package/docs/SDK.md +3 -2
  156. package/marketplace.json +34 -0
  157. package/package.json +38 -4
  158. package/plugins/pm-cli-claude/.claude-plugin/plugin.json +23 -0
  159. package/plugins/pm-cli-claude/.mcp.json +12 -0
  160. package/plugins/pm-cli-claude/README.md +184 -0
  161. package/plugins/pm-cli-claude/agents/pm-coordinator.md +48 -0
  162. package/plugins/pm-cli-claude/commands/pm-audit.md +39 -0
  163. package/plugins/pm-cli-claude/commands/pm-calendar.md +41 -0
  164. package/plugins/pm-cli-claude/commands/pm-close-task.md +20 -0
  165. package/plugins/pm-cli-claude/commands/pm-developer.md +38 -0
  166. package/plugins/pm-cli-claude/commands/pm-init.md +44 -0
  167. package/plugins/pm-cli-claude/commands/pm-list.md +39 -0
  168. package/plugins/pm-cli-claude/commands/pm-new.md +36 -0
  169. package/plugins/pm-cli-claude/commands/pm-planner.md +51 -0
  170. package/plugins/pm-cli-claude/commands/pm-release.md +41 -0
  171. package/plugins/pm-cli-claude/commands/pm-search.md +21 -0
  172. package/plugins/pm-cli-claude/commands/pm-start-task.md +27 -0
  173. package/plugins/pm-cli-claude/commands/pm-status.md +15 -0
  174. package/plugins/pm-cli-claude/commands/pm-triage.md +35 -0
  175. package/plugins/pm-cli-claude/commands/pm-workflow.md +49 -0
  176. package/plugins/pm-cli-claude/hooks/hooks.json +17 -0
  177. package/plugins/pm-cli-claude/hooks/session-start.mjs +55 -0
  178. package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +60 -0
  179. package/plugins/pm-cli-claude/skills/pm-audit/SKILL.md +88 -0
  180. package/plugins/pm-cli-claude/skills/pm-developer/SKILL.md +116 -0
  181. package/plugins/pm-cli-claude/skills/pm-planner/SKILL.md +118 -0
  182. package/plugins/pm-cli-claude/skills/pm-release/SKILL.md +83 -0
  183. package/plugins/pm-cli-claude/skills/pm-workflow/SKILL.md +148 -0
  184. package/plugins/pm-cli-codex/.codex-plugin/plugin.json +45 -0
  185. package/plugins/pm-cli-codex/.mcp.json +14 -0
  186. package/plugins/pm-cli-codex/README.md +30 -0
  187. package/plugins/pm-cli-codex/assets/pm-cli-small.svg +4 -0
  188. package/plugins/pm-cli-codex/commands/pm-audit.md +8 -0
  189. package/plugins/pm-cli-codex/commands/pm-close-task.md +9 -0
  190. package/plugins/pm-cli-codex/commands/pm-start-task.md +9 -0
  191. package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +54 -0
  192. package/plugins/pm-cli-codex/skills/pm-auditor/SKILL.md +21 -0
  193. package/plugins/pm-cli-codex/skills/pm-auditor/agents/openai.yaml +6 -0
  194. package/plugins/pm-cli-codex/skills/pm-native/SKILL.md +57 -0
  195. package/plugins/pm-cli-codex/skills/pm-native/agents/openai.yaml +6 -0
  196. package/plugins/pm-cli-codex/skills/pm-release/SKILL.md +19 -0
  197. package/plugins/pm-cli-codex/skills/pm-release/agents/openai.yaml +6 -0
@@ -0,0 +1,260 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { EXIT_CODE } from "../../core/shared/constants.js";
5
+ import { PmCliError } from "../../core/shared/errors.js";
6
+ import { listGuideTopicIds, listGuideTopics, resolveGuideTopic, } from "../guide-topics.js";
7
+ export const GUIDE_OUTPUT_VALUES = ["markdown", "toon", "json"];
8
+ export const GUIDE_DEPTH_VALUES = ["brief", "standard", "deep"];
9
+ const PACKAGE_ROOT_FROM_SOURCE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
10
+ function parseGuideOutputFormat(raw) {
11
+ if (!raw) {
12
+ return undefined;
13
+ }
14
+ const normalized = raw.trim().toLowerCase();
15
+ if (!GUIDE_OUTPUT_VALUES.includes(normalized)) {
16
+ throw new PmCliError("Guide format must be one of markdown|toon|json", EXIT_CODE.USAGE);
17
+ }
18
+ return normalized;
19
+ }
20
+ export function resolveGuideOutputFormat(options, global) {
21
+ const commandFormat = parseGuideOutputFormat(options.format);
22
+ if (global.json && commandFormat && commandFormat !== "json") {
23
+ throw new PmCliError("Cannot combine --json with --format markdown|toon", EXIT_CODE.USAGE);
24
+ }
25
+ if (global.json) {
26
+ return "json";
27
+ }
28
+ return commandFormat ?? "toon";
29
+ }
30
+ function parseGuideDepth(raw) {
31
+ if (!raw) {
32
+ return "brief";
33
+ }
34
+ const normalized = raw.trim().toLowerCase();
35
+ if (!GUIDE_DEPTH_VALUES.includes(normalized)) {
36
+ throw new PmCliError("Guide depth must be one of brief|standard|deep", EXIT_CODE.USAGE);
37
+ }
38
+ return normalized;
39
+ }
40
+ function resolvePackageRoot() {
41
+ const envRoot = process.env.PM_CLI_PACKAGE_ROOT;
42
+ if (typeof envRoot === "string" && envRoot.trim().length > 0) {
43
+ return path.resolve(envRoot.trim());
44
+ }
45
+ return PACKAGE_ROOT_FROM_SOURCE;
46
+ }
47
+ function normalizeLineEndings(value) {
48
+ return value.replaceAll("\r\n", "\n");
49
+ }
50
+ function toExcerpt(content, maxLines, maxCharacters) {
51
+ const normalized = normalizeLineEndings(content);
52
+ const lines = normalized.split("\n");
53
+ const lineSlice = lines.slice(0, maxLines);
54
+ let excerpt = lineSlice.join("\n");
55
+ let truncated = lines.length > maxLines;
56
+ if (excerpt.length > maxCharacters) {
57
+ excerpt = excerpt.slice(0, maxCharacters);
58
+ truncated = true;
59
+ }
60
+ return {
61
+ excerpt: excerpt.trimEnd(),
62
+ truncated,
63
+ lineCount: lines.length,
64
+ };
65
+ }
66
+ async function renderGuideDocs(topic, depth, packageRoot) {
67
+ const includeContent = depth !== "brief";
68
+ const contentMode = includeContent ? (depth === "deep" ? "full" : "excerpt") : "none";
69
+ const docs = [];
70
+ for (const doc of topic.docs) {
71
+ const absolutePath = path.resolve(packageRoot, doc.path);
72
+ if (!includeContent) {
73
+ docs.push({
74
+ path: doc.path,
75
+ purpose: doc.purpose,
76
+ optional: doc.optional === true,
77
+ exists: true,
78
+ line_count: null,
79
+ content_mode: "none",
80
+ content: null,
81
+ truncated: false,
82
+ });
83
+ continue;
84
+ }
85
+ try {
86
+ const rawContent = await readFile(absolutePath, "utf8");
87
+ if (depth === "deep") {
88
+ const normalized = normalizeLineEndings(rawContent).trimEnd();
89
+ docs.push({
90
+ path: doc.path,
91
+ purpose: doc.purpose,
92
+ optional: doc.optional === true,
93
+ exists: true,
94
+ line_count: normalized.length === 0 ? 0 : normalized.split("\n").length,
95
+ content_mode: "full",
96
+ content: normalized,
97
+ truncated: false,
98
+ });
99
+ }
100
+ else {
101
+ const excerpt = toExcerpt(rawContent, 120, 12_000);
102
+ docs.push({
103
+ path: doc.path,
104
+ purpose: doc.purpose,
105
+ optional: doc.optional === true,
106
+ exists: true,
107
+ line_count: excerpt.lineCount,
108
+ content_mode: contentMode,
109
+ content: excerpt.excerpt,
110
+ truncated: excerpt.truncated,
111
+ });
112
+ }
113
+ }
114
+ catch (error) {
115
+ const code = error?.code;
116
+ const missing = code === "ENOENT";
117
+ docs.push({
118
+ path: doc.path,
119
+ purpose: doc.purpose,
120
+ optional: doc.optional === true,
121
+ exists: false,
122
+ line_count: null,
123
+ content_mode: "none",
124
+ content: null,
125
+ truncated: false,
126
+ });
127
+ if (!missing) {
128
+ throw new PmCliError(`Failed to read guide document "${doc.path}".`, EXIT_CODE.GENERIC_FAILURE);
129
+ }
130
+ }
131
+ }
132
+ return docs;
133
+ }
134
+ function buildGuideIndex(depth) {
135
+ const topics = listGuideTopics().map((topic) => ({
136
+ id: topic.id,
137
+ aliases: topic.aliases,
138
+ title: topic.title,
139
+ summary: topic.summary,
140
+ intent: topic.intent,
141
+ quick_commands: depth === "brief" ? topic.commands.slice(0, 3) : topic.commands.slice(0, 6),
142
+ docs: topic.docs.map((doc) => ({ path: doc.path, purpose: doc.purpose })),
143
+ related: topic.related,
144
+ }));
145
+ return {
146
+ output_default: "toon",
147
+ mode: "index",
148
+ depth,
149
+ topics,
150
+ suggested_next_steps: [
151
+ "pm guide <topic>",
152
+ "pm guide <topic> --depth standard",
153
+ "pm guide <topic> --depth deep --format markdown",
154
+ "pm guide <topic> --json",
155
+ ],
156
+ };
157
+ }
158
+ function ensureGuideTopic(topic) {
159
+ const resolved = resolveGuideTopic(topic);
160
+ if (resolved) {
161
+ return resolved;
162
+ }
163
+ const available = listGuideTopicIds().join(", ");
164
+ throw new PmCliError(`Unknown guide topic "${topic ?? ""}". Available topics: ${available}. Use "pm guide --list" to browse.`, EXIT_CODE.USAGE);
165
+ }
166
+ export async function runGuide(options, global) {
167
+ const depth = parseGuideDepth(typeof options.depth === "string" ? options.depth : undefined);
168
+ const listRequested = options.list === true;
169
+ const topicRaw = typeof options.topic === "string" ? options.topic : undefined;
170
+ if (listRequested || !topicRaw) {
171
+ return buildGuideIndex(depth);
172
+ }
173
+ const topic = ensureGuideTopic(topicRaw);
174
+ const packageRoot = resolvePackageRoot();
175
+ const docs = await renderGuideDocs(topic, depth, packageRoot);
176
+ const warnings = docs
177
+ .filter((doc) => !doc.exists && !doc.optional)
178
+ .map((doc) => `Missing required guide document: ${doc.path}`);
179
+ return {
180
+ output_default: "toon",
181
+ mode: "topic",
182
+ depth,
183
+ requested_topic: topicRaw,
184
+ topic,
185
+ docs,
186
+ warnings,
187
+ };
188
+ }
189
+ function markdownCodeFence(content) {
190
+ return content.replaceAll("```", "``\\`");
191
+ }
192
+ export function renderGuideMarkdown(result) {
193
+ if (result.mode === "index") {
194
+ const lines = [
195
+ "# pm guide",
196
+ "",
197
+ "Token-efficient local documentation index for agent and maintainer workflows.",
198
+ "",
199
+ "## Topics",
200
+ ];
201
+ for (const topic of result.topics) {
202
+ lines.push(`- \`${topic.id}\` - ${topic.summary}`);
203
+ if (result.depth !== "brief") {
204
+ lines.push(` - intent: ${topic.intent}`);
205
+ lines.push(` - docs: ${topic.docs.map((doc) => `\`${doc.path}\``).join(", ")}`);
206
+ }
207
+ }
208
+ lines.push("", "## Next steps");
209
+ for (const step of result.suggested_next_steps) {
210
+ lines.push(`- \`${step}\``);
211
+ }
212
+ return lines.join("\n");
213
+ }
214
+ const lines = [
215
+ `# pm guide ${result.topic.id}`,
216
+ "",
217
+ result.topic.summary,
218
+ "",
219
+ "## Intent",
220
+ result.topic.intent,
221
+ "",
222
+ "## Key commands",
223
+ ...result.topic.commands.map((command) => `- \`${command}\``),
224
+ "",
225
+ "## Workflow prompts",
226
+ ];
227
+ for (const workflow of result.topic.workflows) {
228
+ lines.push(`### ${workflow.name}`);
229
+ lines.push(`goal: ${workflow.goal}`);
230
+ lines.push(`prompt: ${workflow.prompt}`);
231
+ lines.push("commands:");
232
+ lines.push(...workflow.commands.map((command) => `- \`${command}\``));
233
+ lines.push("");
234
+ }
235
+ lines.push("## Documents");
236
+ for (const doc of result.docs) {
237
+ const status = doc.exists ? "available" : doc.optional ? "missing (optional)" : "missing (required)";
238
+ lines.push(`- \`${doc.path}\` - ${doc.purpose} (${status})`);
239
+ if (doc.exists && doc.content_mode !== "none" && doc.content) {
240
+ lines.push("");
241
+ lines.push(`### Excerpt: \`${doc.path}\``);
242
+ if (doc.truncated) {
243
+ lines.push("_truncated for context efficiency_");
244
+ }
245
+ lines.push("```markdown");
246
+ lines.push(markdownCodeFence(doc.content));
247
+ lines.push("```");
248
+ }
249
+ }
250
+ if (result.topic.related.length > 0) {
251
+ lines.push("", "## Related topics");
252
+ lines.push(...result.topic.related.map((topic) => `- \`${topic}\``));
253
+ }
254
+ if (result.warnings.length > 0) {
255
+ lines.push("", "## Warnings");
256
+ lines.push(...result.warnings.map((warning) => `- ${warning}`));
257
+ }
258
+ return lines.join("\n");
259
+ }
260
+ //# sourceMappingURL=guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.js","sourceRoot":"/","sources":["cli/commands/guide.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport {\n listGuideTopicIds,\n listGuideTopics,\n resolveGuideTopic,\n type GuideTopicDefinition,\n} from \"../guide-topics.js\";\n\nexport const GUIDE_OUTPUT_VALUES = [\"markdown\", \"toon\", \"json\"] as const;\nexport type GuideOutputFormat = (typeof GUIDE_OUTPUT_VALUES)[number];\n\nexport const GUIDE_DEPTH_VALUES = [\"brief\", \"standard\", \"deep\"] as const;\nexport type GuideDepth = (typeof GUIDE_DEPTH_VALUES)[number];\n\nexport interface GuideOptions {\n topic?: string;\n list?: boolean;\n format?: string;\n depth?: string;\n [key: string]: unknown;\n}\n\nexport interface GuideDocRender {\n path: string;\n purpose: string;\n optional: boolean;\n exists: boolean;\n line_count: number | null;\n content_mode: \"none\" | \"excerpt\" | \"full\";\n content: string | null;\n truncated: boolean;\n}\n\nexport interface GuideIndexResult {\n output_default: \"toon\";\n mode: \"index\";\n depth: GuideDepth;\n topics: Array<{\n id: string;\n aliases: string[];\n title: string;\n summary: string;\n intent: string;\n quick_commands: string[];\n docs: Array<{ path: string; purpose: string }>;\n related: string[];\n }>;\n suggested_next_steps: string[];\n}\n\nexport interface GuideTopicResult {\n output_default: \"toon\";\n mode: \"topic\";\n depth: GuideDepth;\n requested_topic: string;\n topic: GuideTopicDefinition;\n docs: GuideDocRender[];\n warnings: string[];\n}\n\nexport type GuideResult = GuideIndexResult | GuideTopicResult;\n\nconst PACKAGE_ROOT_FROM_SOURCE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"..\", \"..\", \"..\");\n\nfunction parseGuideOutputFormat(raw: string | undefined): GuideOutputFormat | undefined {\n if (!raw) {\n return undefined;\n }\n const normalized = raw.trim().toLowerCase();\n if (!GUIDE_OUTPUT_VALUES.includes(normalized as GuideOutputFormat)) {\n throw new PmCliError(\"Guide format must be one of markdown|toon|json\", EXIT_CODE.USAGE);\n }\n return normalized as GuideOutputFormat;\n}\n\nexport function resolveGuideOutputFormat(options: GuideOptions, global: GlobalOptions): GuideOutputFormat {\n const commandFormat = parseGuideOutputFormat(options.format);\n if (global.json && commandFormat && commandFormat !== \"json\") {\n throw new PmCliError(\"Cannot combine --json with --format markdown|toon\", EXIT_CODE.USAGE);\n }\n if (global.json) {\n return \"json\";\n }\n return commandFormat ?? \"toon\";\n}\n\nfunction parseGuideDepth(raw: string | undefined): GuideDepth {\n if (!raw) {\n return \"brief\";\n }\n const normalized = raw.trim().toLowerCase();\n if (!GUIDE_DEPTH_VALUES.includes(normalized as GuideDepth)) {\n throw new PmCliError(\"Guide depth must be one of brief|standard|deep\", EXIT_CODE.USAGE);\n }\n return normalized as GuideDepth;\n}\n\nfunction resolvePackageRoot(): string {\n const envRoot = process.env.PM_CLI_PACKAGE_ROOT;\n if (typeof envRoot === \"string\" && envRoot.trim().length > 0) {\n return path.resolve(envRoot.trim());\n }\n return PACKAGE_ROOT_FROM_SOURCE;\n}\n\nfunction normalizeLineEndings(value: string): string {\n return value.replaceAll(\"\\r\\n\", \"\\n\");\n}\n\nfunction toExcerpt(content: string, maxLines: number, maxCharacters: number): { excerpt: string; truncated: boolean; lineCount: number } {\n const normalized = normalizeLineEndings(content);\n const lines = normalized.split(\"\\n\");\n const lineSlice = lines.slice(0, maxLines);\n let excerpt = lineSlice.join(\"\\n\");\n let truncated = lines.length > maxLines;\n if (excerpt.length > maxCharacters) {\n excerpt = excerpt.slice(0, maxCharacters);\n truncated = true;\n }\n return {\n excerpt: excerpt.trimEnd(),\n truncated,\n lineCount: lines.length,\n };\n}\n\nasync function renderGuideDocs(topic: GuideTopicDefinition, depth: GuideDepth, packageRoot: string): Promise<GuideDocRender[]> {\n const includeContent = depth !== \"brief\";\n const contentMode: GuideDocRender[\"content_mode\"] = includeContent ? (depth === \"deep\" ? \"full\" : \"excerpt\") : \"none\";\n const docs: GuideDocRender[] = [];\n for (const doc of topic.docs) {\n const absolutePath = path.resolve(packageRoot, doc.path);\n if (!includeContent) {\n docs.push({\n path: doc.path,\n purpose: doc.purpose,\n optional: doc.optional === true,\n exists: true,\n line_count: null,\n content_mode: \"none\",\n content: null,\n truncated: false,\n });\n continue;\n }\n try {\n const rawContent = await readFile(absolutePath, \"utf8\");\n if (depth === \"deep\") {\n const normalized = normalizeLineEndings(rawContent).trimEnd();\n docs.push({\n path: doc.path,\n purpose: doc.purpose,\n optional: doc.optional === true,\n exists: true,\n line_count: normalized.length === 0 ? 0 : normalized.split(\"\\n\").length,\n content_mode: \"full\",\n content: normalized,\n truncated: false,\n });\n } else {\n const excerpt = toExcerpt(rawContent, 120, 12_000);\n docs.push({\n path: doc.path,\n purpose: doc.purpose,\n optional: doc.optional === true,\n exists: true,\n line_count: excerpt.lineCount,\n content_mode: contentMode,\n content: excerpt.excerpt,\n truncated: excerpt.truncated,\n });\n }\n } catch (error) {\n const code = (error as { code?: string } | null)?.code;\n const missing = code === \"ENOENT\";\n docs.push({\n path: doc.path,\n purpose: doc.purpose,\n optional: doc.optional === true,\n exists: false,\n line_count: null,\n content_mode: \"none\",\n content: null,\n truncated: false,\n });\n if (!missing) {\n throw new PmCliError(`Failed to read guide document \"${doc.path}\".`, EXIT_CODE.GENERIC_FAILURE);\n }\n }\n }\n return docs;\n}\n\nfunction buildGuideIndex(depth: GuideDepth): GuideIndexResult {\n const topics = listGuideTopics().map((topic) => ({\n id: topic.id,\n aliases: topic.aliases,\n title: topic.title,\n summary: topic.summary,\n intent: topic.intent,\n quick_commands: depth === \"brief\" ? topic.commands.slice(0, 3) : topic.commands.slice(0, 6),\n docs: topic.docs.map((doc) => ({ path: doc.path, purpose: doc.purpose })),\n related: topic.related,\n }));\n return {\n output_default: \"toon\",\n mode: \"index\",\n depth,\n topics,\n suggested_next_steps: [\n \"pm guide <topic>\",\n \"pm guide <topic> --depth standard\",\n \"pm guide <topic> --depth deep --format markdown\",\n \"pm guide <topic> --json\",\n ],\n };\n}\n\nfunction ensureGuideTopic(topic: string | undefined): GuideTopicDefinition {\n const resolved = resolveGuideTopic(topic);\n if (resolved) {\n return resolved;\n }\n const available = listGuideTopicIds().join(\", \");\n throw new PmCliError(\n `Unknown guide topic \"${topic ?? \"\"}\". Available topics: ${available}. Use \"pm guide --list\" to browse.`,\n EXIT_CODE.USAGE,\n );\n}\n\nexport async function runGuide(options: GuideOptions, global: GlobalOptions): Promise<GuideResult> {\n const depth = parseGuideDepth(typeof options.depth === \"string\" ? options.depth : undefined);\n const listRequested = options.list === true;\n const topicRaw = typeof options.topic === \"string\" ? options.topic : undefined;\n if (listRequested || !topicRaw) {\n return buildGuideIndex(depth);\n }\n\n const topic = ensureGuideTopic(topicRaw);\n const packageRoot = resolvePackageRoot();\n const docs = await renderGuideDocs(topic, depth, packageRoot);\n const warnings = docs\n .filter((doc) => !doc.exists && !doc.optional)\n .map((doc) => `Missing required guide document: ${doc.path}`);\n\n return {\n output_default: \"toon\",\n mode: \"topic\",\n depth,\n requested_topic: topicRaw,\n topic,\n docs,\n warnings,\n };\n}\n\nfunction markdownCodeFence(content: string): string {\n return content.replaceAll(\"```\", \"``\\\\`\");\n}\n\nexport function renderGuideMarkdown(result: GuideResult): string {\n if (result.mode === \"index\") {\n const lines: string[] = [\n \"# pm guide\",\n \"\",\n \"Token-efficient local documentation index for agent and maintainer workflows.\",\n \"\",\n \"## Topics\",\n ];\n for (const topic of result.topics) {\n lines.push(`- \\`${topic.id}\\` - ${topic.summary}`);\n if (result.depth !== \"brief\") {\n lines.push(` - intent: ${topic.intent}`);\n lines.push(` - docs: ${topic.docs.map((doc) => `\\`${doc.path}\\``).join(\", \")}`);\n }\n }\n lines.push(\"\", \"## Next steps\");\n for (const step of result.suggested_next_steps) {\n lines.push(`- \\`${step}\\``);\n }\n return lines.join(\"\\n\");\n }\n\n const lines: string[] = [\n `# pm guide ${result.topic.id}`,\n \"\",\n result.topic.summary,\n \"\",\n \"## Intent\",\n result.topic.intent,\n \"\",\n \"## Key commands\",\n ...result.topic.commands.map((command) => `- \\`${command}\\``),\n \"\",\n \"## Workflow prompts\",\n ];\n for (const workflow of result.topic.workflows) {\n lines.push(`### ${workflow.name}`);\n lines.push(`goal: ${workflow.goal}`);\n lines.push(`prompt: ${workflow.prompt}`);\n lines.push(\"commands:\");\n lines.push(...workflow.commands.map((command) => `- \\`${command}\\``));\n lines.push(\"\");\n }\n lines.push(\"## Documents\");\n for (const doc of result.docs) {\n const status = doc.exists ? \"available\" : doc.optional ? \"missing (optional)\" : \"missing (required)\";\n lines.push(`- \\`${doc.path}\\` - ${doc.purpose} (${status})`);\n if (doc.exists && doc.content_mode !== \"none\" && doc.content) {\n lines.push(\"\");\n lines.push(`### Excerpt: \\`${doc.path}\\``);\n if (doc.truncated) {\n lines.push(\"_truncated for context efficiency_\");\n }\n lines.push(\"```markdown\");\n lines.push(markdownCodeFence(doc.content));\n lines.push(\"```\");\n }\n }\n if (result.topic.related.length > 0) {\n lines.push(\"\", \"## Related topics\");\n lines.push(...result.topic.related.map((topic) => `- \\`${topic}\\``));\n }\n if (result.warnings.length > 0) {\n lines.push(\"\", \"## Warnings\");\n lines.push(...result.warnings.map((warning) => `- ${warning}`));\n }\n return lines.join(\"\\n\");\n}\n\n"]}
@@ -778,7 +778,7 @@ async function buildHistoryDriftCheck(pmRoot, items) {
778
778
  }
779
779
  const { body, ...frontMatter } = item;
780
780
  const currentHash = hashDocument({
781
- front_matter: frontMatter,
781
+ metadata: frontMatter,
782
782
  body,
783
783
  });
784
784
  if (latestAfterHash !== currentHash) {