@hivelore/cli 0.31.0 → 0.34.1

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.
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ui
4
+ } from "./chunk-GGDCU7PH.js";
5
+
6
+ // src/commands/memory-import-changelog.ts
7
+ import { existsSync } from "fs";
8
+ import { readFile, mkdir, writeFile } from "fs/promises";
9
+ import path from "path";
10
+ import "commander";
11
+ import {
12
+ buildFrontmatter,
13
+ findProjectRoot,
14
+ resolveHaivePaths,
15
+ serializeMemory
16
+ } from "@hivelore/core";
17
+ function parseChangelog(content) {
18
+ const entries = [];
19
+ const versionRe = /^#{1,3}\s+(?:\[?)([0-9]+\.[0-9]+[.0-9]*)/m;
20
+ const sections = content.split(/^#{1,3}\s+/m).slice(1);
21
+ for (const section of sections) {
22
+ const versionMatch = section.match(/^(?:\[?)([0-9]+\.[0-9]+[.0-9]*)/);
23
+ const version = versionMatch?.[1];
24
+ if (!version) continue;
25
+ const entry = {
26
+ version,
27
+ breaking: [],
28
+ deprecated: [],
29
+ removed: [],
30
+ fixed: [],
31
+ added: []
32
+ };
33
+ const subSections = section.split(/^#{2,4}\s+/m);
34
+ for (const sub of subSections) {
35
+ const firstLine = (sub.split("\n")[0] ?? "").toLowerCase().trim();
36
+ const items = sub.split("\n").slice(1).filter((l) => l.trim().startsWith("-") || l.trim().startsWith("*")).map((l) => l.replace(/^[\s\-*]+/, "").trim()).filter(Boolean);
37
+ if (/breaking/.test(firstLine)) {
38
+ entry.breaking.push(...items);
39
+ } else if (/deprecated/.test(firstLine)) {
40
+ entry.deprecated.push(...items);
41
+ } else if (/removed/.test(firstLine)) {
42
+ entry.removed.push(...items);
43
+ } else if (/fixed|bug/.test(firstLine)) {
44
+ entry.fixed.push(...items);
45
+ } else if (/added|new|feat/.test(firstLine)) {
46
+ entry.added.push(...items);
47
+ }
48
+ for (const sub2 of subSections) {
49
+ for (const line of sub2.split("\n")) {
50
+ const breakingMatch = line.match(/BREAKING CHANGE[S]?:\s*(.+)/i);
51
+ const breakingText = breakingMatch?.[1]?.trim();
52
+ if (breakingText && !entry.breaking.includes(breakingText)) {
53
+ entry.breaking.push(breakingText);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ if (entry.breaking.length === 0) {
59
+ for (const line of section.split("\n")) {
60
+ if (/breaking|⚠|deprecated|removed/.test(line.toLowerCase())) {
61
+ const item = line.replace(/^[\s\-*#]+/, "").trim();
62
+ if (item) entry.breaking.push(item);
63
+ }
64
+ }
65
+ }
66
+ const hasContent = entry.breaking.length > 0 || entry.deprecated.length > 0 || entry.removed.length > 0;
67
+ if (hasContent) entries.push(entry);
68
+ }
69
+ void versionRe;
70
+ return entries;
71
+ }
72
+ function registerMemoryImportChangelog(memory) {
73
+ memory.command("import-changelog", { hidden: true }).description(
74
+ "Import breaking changes from a CHANGELOG.md as Hivelore memories.\n\n Parses Keep-a-Changelog and Angular commit format changelogs,\n extracts breaking changes, deprecations, and removals,\n and saves each version's changes as a gotcha memory.\n\n Examples:\n hivelore memory import-changelog --from node_modules/@company/sdk/CHANGELOG.md --package @company/sdk\n hivelore memory import-changelog --from CHANGELOG.md\n hivelore memory import-changelog --from CHANGELOG.md --versions 2.0.0,2.1.0\n"
75
+ ).requiredOption("--from <file>", "path to the CHANGELOG.md file").option("--package <name>", "name of the package (used in memory title and tags)").option("--scope <scope>", "memory scope: team | personal (default: team)", "team").option(
76
+ "--versions <csv>",
77
+ "only import specific versions (comma-separated), or 'latest' for the most recent breaking version"
78
+ ).option("-d, --dir <dir>", "project root").action(async (opts) => runImportChangelog({ ...opts, fromChangelog: opts.from ?? opts.fromChangelog }));
79
+ }
80
+ async function runImportChangelog(opts) {
81
+ const root = findProjectRoot(opts.dir);
82
+ const paths = resolveHaivePaths(root);
83
+ const changelogPath = path.resolve(root, opts.fromChangelog);
84
+ if (!existsSync(changelogPath)) {
85
+ ui.error(`CHANGELOG not found: ${changelogPath}`);
86
+ process.exitCode = 1;
87
+ return;
88
+ }
89
+ const content = await readFile(changelogPath, "utf8");
90
+ let entries = parseChangelog(content);
91
+ if (entries.length === 0) {
92
+ ui.warn("No breaking changes, deprecations, or removals found in the CHANGELOG.");
93
+ return;
94
+ }
95
+ if (opts.versions) {
96
+ if (opts.versions === "latest") {
97
+ const latest = entries[0];
98
+ entries = latest ? [latest] : [];
99
+ } else {
100
+ const requested = opts.versions.split(",").map((v) => v.trim());
101
+ entries = entries.filter((e) => requested.includes(e.version));
102
+ }
103
+ }
104
+ const pkgName = opts.package ?? path.basename(path.dirname(changelogPath));
105
+ const scope = opts.scope ?? "team";
106
+ const teamDir = path.join(paths.memoriesDir, scope);
107
+ await mkdir(teamDir, { recursive: true });
108
+ let saved = 0;
109
+ for (const entry of entries) {
110
+ const lines = [];
111
+ lines.push(`## ${pkgName} v${entry.version} \u2014 Breaking Changes & Deprecations
112
+ `);
113
+ if (entry.breaking.length > 0) {
114
+ lines.push("### \u{1F534} Breaking Changes\n");
115
+ for (const item of entry.breaking) lines.push(`- ${item}`);
116
+ lines.push("");
117
+ }
118
+ if (entry.deprecated.length > 0) {
119
+ lines.push("### \u{1F7E1} Deprecated\n");
120
+ for (const item of entry.deprecated) lines.push(`- ${item}`);
121
+ lines.push("");
122
+ }
123
+ if (entry.removed.length > 0) {
124
+ lines.push("### \u26AB Removed\n");
125
+ for (const item of entry.removed) lines.push(`- ${item}`);
126
+ lines.push("");
127
+ }
128
+ lines.push(
129
+ `**Source:** \`${path.relative(root, changelogPath)}\`
130
+ **Action:** Update all usages of ${pkgName} if they rely on any of the above.`
131
+ );
132
+ const slug = `changelog-${pkgName.replace(/[^a-z0-9]/gi, "-").toLowerCase()}-v${entry.version.replace(/\./g, "-")}`;
133
+ const fm = buildFrontmatter({
134
+ type: "gotcha",
135
+ slug,
136
+ scope,
137
+ status: "validated",
138
+ tags: [
139
+ "changelog",
140
+ "breaking-change",
141
+ pkgName.replace(/[^a-z0-9]/gi, "-").toLowerCase(),
142
+ `v${entry.version}`
143
+ ],
144
+ paths: [path.relative(root, changelogPath)],
145
+ topic: `changelog-${pkgName}-${entry.version}`
146
+ });
147
+ await writeFile(
148
+ path.join(teamDir, `${fm.id}.md`),
149
+ serializeMemory({ frontmatter: fm, body: lines.join("\n") }),
150
+ "utf8"
151
+ );
152
+ console.log(ui.green(` \u2713 ${fm.id}`));
153
+ saved++;
154
+ }
155
+ console.log(
156
+ `
157
+ ${ui.bold(`Imported ${saved} changelog entr${saved === 1 ? "y" : "ies"} from ${pkgName}`)}`
158
+ );
159
+ if (saved > 0) {
160
+ console.log(
161
+ ui.dim(` Memories saved to .ai/memories/${scope}/`)
162
+ );
163
+ console.log(
164
+ ui.dim(` Run \`hivelore briefing --task "update ${pkgName}"\` to see them in context.`)
165
+ );
166
+ }
167
+ }
168
+
169
+ export {
170
+ registerMemoryImportChangelog,
171
+ runImportChangelog
172
+ };
173
+ //# sourceMappingURL=chunk-X6Y2B3TJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/memory-import-changelog.ts"],"sourcesContent":["/**\n * hivelore memory import --from-changelog CHANGELOG.md [--package <name>]\n *\n * Parses a CHANGELOG.md file (Keep-a-Changelog format or common variants),\n * extracts breaking changes and notable gotchas from recent versions,\n * and saves them as Hivelore memories.\n *\n * Supports:\n * - Keep a Changelog (https://keepachangelog.com)\n * - Angular commit-based CHANGELOG format\n * - Plain Markdown changelogs with ## headers\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile, mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n buildFrontmatter,\n findProjectRoot,\n resolveHaivePaths,\n serializeMemory,\n} from \"@hivelore/core\";\nimport { ui } from \"../utils/ui.js\";\n\nexport interface ImportChangelogOptions {\n fromChangelog: string;\n package?: string;\n scope?: string;\n versions?: string; // e.g. \"2.0.0,2.1.0\" or \"latest\"\n dir?: string;\n}\n\ninterface ChangelogEntry {\n version: string;\n breaking: string[];\n deprecated: string[];\n removed: string[];\n fixed: string[];\n added: string[];\n}\n\n// ── Parser ─────────────────────────────────────────────────────────────────\n\nfunction parseChangelog(content: string): ChangelogEntry[] {\n const entries: ChangelogEntry[] = [];\n const versionRe = /^#{1,3}\\s+(?:\\[?)([0-9]+\\.[0-9]+[.0-9]*)/m;\n const sections = content.split(/^#{1,3}\\s+/m).slice(1);\n\n for (const section of sections) {\n const versionMatch = section.match(/^(?:\\[?)([0-9]+\\.[0-9]+[.0-9]*)/);\n const version = versionMatch?.[1];\n if (!version) continue;\n\n const entry: ChangelogEntry = {\n version,\n breaking: [],\n deprecated: [],\n removed: [],\n fixed: [],\n added: [],\n };\n\n // Extract sub-sections\n const subSections = section.split(/^#{2,4}\\s+/m);\n for (const sub of subSections) {\n const firstLine = (sub.split(\"\\n\")[0] ?? \"\").toLowerCase().trim();\n const items = sub\n .split(\"\\n\")\n .slice(1)\n .filter((l) => l.trim().startsWith(\"-\") || l.trim().startsWith(\"*\"))\n .map((l) => l.replace(/^[\\s\\-*]+/, \"\").trim())\n .filter(Boolean);\n\n if (/breaking/.test(firstLine)) {\n entry.breaking.push(...items);\n } else if (/deprecated/.test(firstLine)) {\n entry.deprecated.push(...items);\n } else if (/removed/.test(firstLine)) {\n entry.removed.push(...items);\n } else if (/fixed|bug/.test(firstLine)) {\n entry.fixed.push(...items);\n } else if (/added|new|feat/.test(firstLine)) {\n entry.added.push(...items);\n }\n\n // Also scan for BREAKING CHANGE: prefixes in all items (Angular format)\n for (const sub2 of subSections) {\n for (const line of sub2.split(\"\\n\")) {\n const breakingMatch = line.match(/BREAKING CHANGE[S]?:\\s*(.+)/i);\n const breakingText = breakingMatch?.[1]?.trim();\n if (breakingText && !entry.breaking.includes(breakingText)) {\n entry.breaking.push(breakingText);\n }\n }\n }\n }\n\n // If no sub-sections matched, do a raw scan for breaking change indicators\n if (entry.breaking.length === 0) {\n for (const line of section.split(\"\\n\")) {\n if (/breaking|⚠|deprecated|removed/.test(line.toLowerCase())) {\n const item = line.replace(/^[\\s\\-*#]+/, \"\").trim();\n if (item) entry.breaking.push(item);\n }\n }\n }\n\n const hasContent =\n entry.breaking.length > 0 ||\n entry.deprecated.length > 0 ||\n entry.removed.length > 0;\n\n if (hasContent) entries.push(entry);\n }\n\n void versionRe; // used implicitly in section splitting\n return entries;\n}\n\n// ── CLI command ─────────────────────────────────────────────────────────────\n\nexport function registerMemoryImportChangelog(memory: Command): void {\n memory\n .command(\"import-changelog\", { hidden: true })\n .description(\n \"Import breaking changes from a CHANGELOG.md as Hivelore memories.\\n\\n\" +\n \" Parses Keep-a-Changelog and Angular commit format changelogs,\\n\" +\n \" extracts breaking changes, deprecations, and removals,\\n\" +\n \" and saves each version's changes as a gotcha memory.\\n\\n\" +\n \" Examples:\\n\" +\n \" hivelore memory import-changelog --from node_modules/@company/sdk/CHANGELOG.md --package @company/sdk\\n\" +\n \" hivelore memory import-changelog --from CHANGELOG.md\\n\" +\n \" hivelore memory import-changelog --from CHANGELOG.md --versions 2.0.0,2.1.0\\n\",\n )\n .requiredOption(\"--from <file>\", \"path to the CHANGELOG.md file\")\n .option(\"--package <name>\", \"name of the package (used in memory title and tags)\")\n .option(\"--scope <scope>\", \"memory scope: team | personal (default: team)\", \"team\")\n .option(\n \"--versions <csv>\",\n \"only import specific versions (comma-separated), or 'latest' for the most recent breaking version\",\n )\n .option(\"-d, --dir <dir>\", \"project root\")\n // Commander maps `--from` to opts.from; the impl reads `fromChangelog` (name kept to avoid\n // colliding with `memory import --from` when both flags coexist on the merged verb).\n .action(async (opts: ImportChangelogOptions & { from?: string }) =>\n runImportChangelog({ ...opts, fromChangelog: opts.from ?? opts.fromChangelog }));\n}\n\nexport async function runImportChangelog(opts: ImportChangelogOptions): Promise<void> {\n const root = findProjectRoot(opts.dir);\n const paths = resolveHaivePaths(root);\n\n const changelogPath = path.resolve(root, opts.fromChangelog);\n if (!existsSync(changelogPath)) {\n ui.error(`CHANGELOG not found: ${changelogPath}`);\n process.exitCode = 1;\n return;\n }\n\n const content = await readFile(changelogPath, \"utf8\");\n let entries = parseChangelog(content);\n\n if (entries.length === 0) {\n ui.warn(\"No breaking changes, deprecations, or removals found in the CHANGELOG.\");\n return;\n }\n\n // Filter by versions if specified\n if (opts.versions) {\n if (opts.versions === \"latest\") {\n const latest = entries[0];\n entries = latest ? [latest] : [];\n } else {\n const requested = opts.versions.split(\",\").map((v) => v.trim());\n entries = entries.filter((e) => requested.includes(e.version));\n }\n }\n\n const pkgName = opts.package ?? path.basename(path.dirname(changelogPath));\n const scope = (opts.scope ?? \"team\") as \"team\" | \"personal\";\n const teamDir = path.join(paths.memoriesDir, scope);\n await mkdir(teamDir, { recursive: true });\n\n let saved = 0;\n for (const entry of entries) {\n const lines: string[] = [];\n lines.push(`## ${pkgName} v${entry.version} — Breaking Changes & Deprecations\\n`);\n\n if (entry.breaking.length > 0) {\n lines.push(\"### 🔴 Breaking Changes\\n\");\n for (const item of entry.breaking) lines.push(`- ${item}`);\n lines.push(\"\");\n }\n if (entry.deprecated.length > 0) {\n lines.push(\"### 🟡 Deprecated\\n\");\n for (const item of entry.deprecated) lines.push(`- ${item}`);\n lines.push(\"\");\n }\n if (entry.removed.length > 0) {\n lines.push(\"### ⚫ Removed\\n\");\n for (const item of entry.removed) lines.push(`- ${item}`);\n lines.push(\"\");\n }\n\n lines.push(\n `**Source:** \\`${path.relative(root, changelogPath)}\\` \\n` +\n `**Action:** Update all usages of ${pkgName} if they rely on any of the above.`,\n );\n\n const slug = `changelog-${pkgName.replace(/[^a-z0-9]/gi, \"-\").toLowerCase()}-v${entry.version.replace(/\\./g, \"-\")}`;\n const fm = buildFrontmatter({\n type: \"gotcha\",\n slug,\n scope,\n status: \"validated\",\n tags: [\n \"changelog\",\n \"breaking-change\",\n pkgName.replace(/[^a-z0-9]/gi, \"-\").toLowerCase(),\n `v${entry.version}`,\n ],\n paths: [path.relative(root, changelogPath)],\n topic: `changelog-${pkgName}-${entry.version}`,\n });\n\n await writeFile(\n path.join(teamDir, `${fm.id}.md`),\n serializeMemory({ frontmatter: fm, body: lines.join(\"\\n\") }),\n \"utf8\",\n );\n console.log(ui.green(` ✓ ${fm.id}`));\n saved++;\n }\n\n console.log(\n `\\n${ui.bold(`Imported ${saved} changelog entr${saved === 1 ? \"y\" : \"ies\"} from ${pkgName}`)}`,\n );\n if (saved > 0) {\n console.log(\n ui.dim(` Memories saved to .ai/memories/${scope}/`),\n );\n console.log(\n ui.dim(` Run \\`hivelore briefing --task \"update ${pkgName}\"\\` to see them in context.`),\n );\n }\n}\n"],"mappings":"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","names":[]}