@releasekit/notes 0.3.0 → 0.3.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.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+
4
+ declare function createNotesCommand(): Command;
5
+
6
+ export { createNotesCommand };
package/dist/cli.js CHANGED
@@ -1 +1,197 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ NotesError,
4
+ getDefaultConfig,
5
+ getExitCode,
6
+ loadConfig,
7
+ parseVersionOutput,
8
+ runPipeline,
9
+ saveAuth
10
+ } from "./chunk-ENAWZXFG.js";
11
+ import {
12
+ EXIT_CODES,
13
+ error,
14
+ info,
15
+ readPackageVersion,
16
+ setLogLevel,
17
+ setQuietMode,
18
+ success
19
+ } from "./chunk-E4454SIS.js";
20
+
21
+ // src/cli.ts
22
+ import * as fs from "fs";
23
+ import * as readline from "readline";
24
+ import { fileURLToPath } from "url";
25
+ import { Command } from "commander";
26
+ function createNotesCommand() {
27
+ const cmd = new Command("notes").description(
28
+ "Generate changelogs with LLM-powered enhancement and flexible templating"
29
+ );
30
+ cmd.command("generate", { isDefault: true }).description("Generate changelog from input data").option("-i, --input <file>", "Input file (default: stdin)").option("-o, --output <spec>", "Output spec (format:file)", collectOutputs, []).option("-t, --template <path>", "Template file or directory").option("-e, --engine <engine>", "Template engine (handlebars|liquid|ejs)").option("--monorepo <mode>", "Monorepo mode (root|packages|both)").option("--llm-provider <provider>", "LLM provider").option("--llm-model <model>", "LLM model").option("--llm-base-url <url>", "LLM base URL (for openai-compatible provider)").option("--llm-tasks <tasks>", "Comma-separated LLM tasks").option("--no-llm", "Disable LLM processing").option("--target <package>", "Filter to a specific package name").option("--config <path>", "Config file path").option("--dry-run", "Preview without writing").option("--regenerate", "Regenerate entire changelog").option("-v, --verbose", "Increase verbosity", increaseVerbosity, 0).option("-q, --quiet", "Suppress non-error output").action(async (options) => {
31
+ setVerbosity(options.verbose);
32
+ if (options.quiet) setQuietMode(true);
33
+ try {
34
+ const config = loadConfig(process.cwd(), options.config);
35
+ if (options.output.length > 0) {
36
+ config.output = options.output;
37
+ }
38
+ if (config.output.length === 0) {
39
+ config.output = getDefaultConfig().output;
40
+ }
41
+ if (options.regenerate) {
42
+ config.updateStrategy = "regenerate";
43
+ }
44
+ if (options.template) {
45
+ config.templates = { ...config.templates, path: options.template };
46
+ }
47
+ if (options.engine) {
48
+ config.templates = { ...config.templates, engine: options.engine };
49
+ }
50
+ if (options.llm === false) {
51
+ info("LLM processing disabled via --no-llm flag");
52
+ delete config.llm;
53
+ } else if (options.llmProvider || options.llmModel || options.llmBaseUrl || options.llmTasks) {
54
+ config.llm = config.llm ?? { provider: "openai-compatible", model: "" };
55
+ if (options.llmProvider) config.llm.provider = options.llmProvider;
56
+ if (options.llmModel) config.llm.model = options.llmModel;
57
+ if (options.llmBaseUrl) config.llm.baseURL = options.llmBaseUrl;
58
+ if (options.llmTasks) {
59
+ const taskNames = options.llmTasks.split(",").map((t) => t.trim());
60
+ config.llm.tasks = {
61
+ enhance: taskNames.includes("enhance"),
62
+ summarize: taskNames.includes("summarize"),
63
+ categorize: taskNames.includes("categorize"),
64
+ releaseNotes: taskNames.includes("release-notes") || taskNames.includes("releaseNotes")
65
+ };
66
+ }
67
+ info(`LLM configured: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
68
+ if (config.llm.baseURL) {
69
+ info(`LLM base URL: ${config.llm.baseURL}`);
70
+ }
71
+ const taskList = Object.entries(config.llm.tasks || {}).filter(([, enabled]) => enabled).map(([name]) => name).join(", ");
72
+ if (taskList) {
73
+ info(`LLM tasks: ${taskList}`);
74
+ }
75
+ }
76
+ let inputJson;
77
+ if (options.input) {
78
+ inputJson = fs.readFileSync(options.input, "utf-8");
79
+ } else {
80
+ inputJson = await readStdin();
81
+ }
82
+ const input = parseVersionOutput(inputJson);
83
+ if (options.target) {
84
+ const before = input.packages.length;
85
+ input.packages = input.packages.filter((p) => p.packageName === options.target);
86
+ if (input.packages.length === 0) {
87
+ info(`No changelog found for package "${options.target}" (had ${before} package(s))`);
88
+ return;
89
+ }
90
+ info(`Filtered to package: ${options.target}`);
91
+ }
92
+ if (options.monorepo) {
93
+ config.monorepo = { ...config.monorepo, mode: options.monorepo };
94
+ }
95
+ await runPipeline(input, config, options.dryRun ?? false);
96
+ if (options.dryRun) {
97
+ info("Dry run complete - no files were written");
98
+ } else {
99
+ success("Changelog generation complete");
100
+ }
101
+ } catch (err) {
102
+ handleError(err);
103
+ }
104
+ });
105
+ cmd.command("init").description("Create default configuration file").option("-f, --force", "Overwrite existing config").action((options) => {
106
+ const configPath = "releasekit.config.json";
107
+ if (fs.existsSync(configPath) && !options.force) {
108
+ error(`Config file already exists at ${configPath}. Use --force to overwrite.`);
109
+ process.exit(EXIT_CODES.GENERAL_ERROR);
110
+ }
111
+ const defaultConfig = {
112
+ $schema: "https://releasekit.dev/schema.json",
113
+ notes: {
114
+ output: [{ format: "markdown", file: "CHANGELOG.md" }],
115
+ updateStrategy: "prepend"
116
+ }
117
+ };
118
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
119
+ success(`Created config file at ${configPath}`);
120
+ });
121
+ cmd.command("auth <provider>").description("Configure API key for an LLM provider").option("--key <key>", "API key (omit to be prompted)").action(async (provider, options) => {
122
+ let apiKey;
123
+ if (options.key) {
124
+ apiKey = options.key;
125
+ } else {
126
+ apiKey = await promptSecret(`Enter API key for ${provider}: `);
127
+ }
128
+ if (!apiKey.trim()) {
129
+ error("API key cannot be empty");
130
+ process.exit(EXIT_CODES.GENERAL_ERROR);
131
+ }
132
+ saveAuth(provider, apiKey.trim());
133
+ success(`API key saved for ${provider}`);
134
+ });
135
+ cmd.command("providers").description("List available LLM providers").action(() => {
136
+ info("Available LLM providers:");
137
+ console.log(" openai - OpenAI (GPT models)");
138
+ console.log(" anthropic - Anthropic (Claude models)");
139
+ console.log(" ollama - Ollama (local models)");
140
+ console.log(" openai-compatible - Any OpenAI-compatible endpoint");
141
+ });
142
+ return cmd;
143
+ }
144
+ function collectOutputs(value, previous) {
145
+ const parts = value.split(":");
146
+ const format = parts[0] ?? "markdown";
147
+ const file = parts[1];
148
+ const spec = { format };
149
+ if (file) {
150
+ spec.file = file;
151
+ }
152
+ return [...previous, spec];
153
+ }
154
+ function increaseVerbosity(_, previous) {
155
+ return previous + 1;
156
+ }
157
+ function setVerbosity(level) {
158
+ const levels = ["info", "debug", "trace"];
159
+ setLogLevel(levels[Math.min(level, levels.length - 1)] ?? "info");
160
+ }
161
+ async function readStdin() {
162
+ const chunks = [];
163
+ for await (const chunk of process.stdin) {
164
+ chunks.push(chunk);
165
+ }
166
+ return chunks.join("");
167
+ }
168
+ function promptSecret(prompt) {
169
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
170
+ return new Promise((resolve) => {
171
+ rl.question(prompt, (answer) => {
172
+ rl.close();
173
+ resolve(answer);
174
+ });
175
+ });
176
+ }
177
+ function handleError(err) {
178
+ if (err instanceof NotesError) {
179
+ err.logError();
180
+ process.exit(getExitCode(err));
181
+ }
182
+ error(err instanceof Error ? err.message : String(err));
183
+ process.exit(EXIT_CODES.GENERAL_ERROR);
184
+ }
185
+ var isMain = (() => {
186
+ try {
187
+ return process.argv[1] ? fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url) : false;
188
+ } catch {
189
+ return false;
190
+ }
191
+ })();
192
+ if (isMain) {
193
+ createNotesCommand().name("releasekit-notes").version(readPackageVersion(import.meta.url)).parse();
194
+ }
195
+ export {
196
+ createNotesCommand
197
+ };
@@ -0,0 +1,8 @@
1
+ export { getDefaultConfig, loadAuth, loadConfig, saveAuth } from './core/config.ts';
2
+ export { PipelineResult, createTemplateContext, processInput, runPipeline } from './core/pipeline.ts';
3
+ export * from './core/types.ts';
4
+ export * from './errors/index.ts';
5
+ export { parseVersionOutput, parseVersionOutputFile, parseVersionOutputStdin } from './input/version-output.ts';
6
+ export { aggregateToRoot, detectMonorepo, writeMonorepoChangelogs } from './monorepo/aggregator.ts';
7
+ export { renderJson, writeJson } from './output/json.ts';
8
+ export { formatVersion, renderMarkdown, writeMarkdown } from './output/markdown.ts';
package/dist/index.js ADDED
@@ -0,0 +1,58 @@
1
+ import {
2
+ ConfigError,
3
+ GitHubError,
4
+ InputParseError,
5
+ LLMError,
6
+ NotesError,
7
+ TemplateError,
8
+ createTemplateContext,
9
+ getDefaultConfig,
10
+ getExitCode,
11
+ loadAuth,
12
+ loadConfig,
13
+ parseVersionOutput,
14
+ parseVersionOutputFile,
15
+ parseVersionOutputStdin,
16
+ processInput,
17
+ renderJson,
18
+ runPipeline,
19
+ saveAuth,
20
+ writeJson
21
+ } from "./chunk-ENAWZXFG.js";
22
+ import {
23
+ aggregateToRoot,
24
+ detectMonorepo,
25
+ writeMonorepoChangelogs
26
+ } from "./chunk-DCQ32FVH.js";
27
+ import {
28
+ formatVersion,
29
+ renderMarkdown,
30
+ writeMarkdown
31
+ } from "./chunk-E4454SIS.js";
32
+ export {
33
+ ConfigError,
34
+ GitHubError,
35
+ InputParseError,
36
+ LLMError,
37
+ NotesError,
38
+ TemplateError,
39
+ aggregateToRoot,
40
+ createTemplateContext,
41
+ detectMonorepo,
42
+ formatVersion,
43
+ getDefaultConfig,
44
+ getExitCode,
45
+ loadAuth,
46
+ loadConfig,
47
+ parseVersionOutput,
48
+ parseVersionOutputFile,
49
+ parseVersionOutputStdin,
50
+ processInput,
51
+ renderJson,
52
+ renderMarkdown,
53
+ runPipeline,
54
+ saveAuth,
55
+ writeJson,
56
+ writeMarkdown,
57
+ writeMonorepoChangelogs
58
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@releasekit/notes",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Release notes and changelog generation with LLM-powered enhancement and flexible templating",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -65,8 +65,8 @@
65
65
  "tsup": "^8.5.1",
66
66
  "typescript": "^5.9.3",
67
67
  "vitest": "^4.1.0",
68
- "@releasekit/config": "0.0.0",
69
- "@releasekit/core": "0.0.0"
68
+ "@releasekit/core": "0.0.0",
69
+ "@releasekit/config": "0.0.0"
70
70
  },
71
71
  "engines": {
72
72
  "node": ">=20"