tegami 0.0.0 → 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fuma Nama
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ import { _ as PublishResult, n as Awaitable, y as DraftPlan } from "../context-CC36jtz1.mjs";
2
+ import { t as Tegami } from "../index-DJ7YxxdM.mjs";
3
+ import { Command } from "commander";
4
+
5
+ //#region src/cli/index.d.ts
6
+ interface TegamiCLIOptions {
7
+ version?: () => Awaitable<DraftPlan>;
8
+ publish?: () => Awaitable<PublishResult>;
9
+ }
10
+ declare function createCli(tegami: Tegami, options?: TegamiCLIOptions): Command;
11
+ //#endregion
12
+ export { TegamiCLIOptions, createCli };
@@ -0,0 +1,199 @@
1
+ import { t as isCI } from "../constants-B9qjNfvr.mjs";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { join, resolve } from "node:path";
4
+ import { confirm, intro, isCancel, multiselect, note, outro, select, spinner, text } from "@clack/prompts";
5
+ import { Command } from "commander";
6
+ //#region src/cli/index.ts
7
+ var CancelledError = class extends Error {
8
+ constructor() {
9
+ super("Cancelled.");
10
+ }
11
+ };
12
+ function createCli(tegami, options = {}) {
13
+ const program = new Command();
14
+ program.name("tegami").description("Create changelogs, version packages, and publish releases.").action((commandOptions) => runAction(tegami, () => createChangelogs(tegami, {
15
+ ...commandOptions,
16
+ cli: options
17
+ })));
18
+ program.command("version").description("create a publish plan and update package versions").action((commandOptions) => runAction(tegami, () => versionPackages(tegami, {
19
+ ...commandOptions,
20
+ cli: options
21
+ })));
22
+ program.command("publish").description("publish packages from the current publish plan").option("--dry-run", "validate the publish plan without publishing packages").action((commandOptions) => runAction(tegami, () => publishPackages(tegami, {
23
+ ...commandOptions,
24
+ cli: options
25
+ })));
26
+ return program;
27
+ }
28
+ async function createChangelogs(tegami, _options) {
29
+ intro("Create changelogs");
30
+ const { graph, cwd, changelogDir } = await tegami._internal.context();
31
+ const packages = graph.getPackages();
32
+ let selectedPackages = [];
33
+ if (isCI()) selectedPackages = [];
34
+ else {
35
+ const selected = await multiselect({
36
+ message: "Select packages (leave empty to auto-generate from commits)",
37
+ required: false,
38
+ options: packages.map((pkg) => ({
39
+ value: pkg.id,
40
+ label: pkg.id,
41
+ hint: pkg.version
42
+ }))
43
+ });
44
+ if (isCancel(selected)) throw new CancelledError();
45
+ selectedPackages = selected;
46
+ }
47
+ if (selectedPackages.length === 0) {
48
+ if (!isCI()) {
49
+ const confirmed = await confirm({
50
+ message: "Auto-generate changelog files from commits?",
51
+ initialValue: true
52
+ });
53
+ if (isCancel(confirmed)) throw new CancelledError();
54
+ if (!confirmed) {
55
+ outro("No changelogs created.");
56
+ return;
57
+ }
58
+ }
59
+ const s = spinner();
60
+ s.start("Reading commits and creating changelogs");
61
+ const created = await tegami.generateChangelog();
62
+ s.stop(created.length === 1 ? "Created 1 changelog file" : `Created ${created.length} changelog files`);
63
+ if (created.length === 0) note("No matching conventional commits were found.", "No changelogs created");
64
+ else note(created.map((entry) => `${entry.filename} (${entry.changes} changes)`).join("\n"), "Created changelogs");
65
+ outro("Changelogs ready.");
66
+ return;
67
+ }
68
+ const type = await select({
69
+ message: "Select release type",
70
+ options: [
71
+ {
72
+ value: "patch",
73
+ label: "patch"
74
+ },
75
+ {
76
+ value: "minor",
77
+ label: "minor"
78
+ },
79
+ {
80
+ value: "major",
81
+ label: "major"
82
+ }
83
+ ]
84
+ });
85
+ if (isCancel(type)) throw new CancelledError();
86
+ const message = await text({
87
+ message: "Change message",
88
+ placeholder: "Add a concise release note",
89
+ validate(value) {
90
+ if (!value?.trim()) return "Enter a message.";
91
+ }
92
+ });
93
+ if (isCancel(message)) throw new CancelledError();
94
+ const filename = changelogFilename();
95
+ const directory = resolve(cwd, changelogDir);
96
+ const s = spinner();
97
+ s.start("Creating changelog");
98
+ await mkdir(directory, { recursive: true });
99
+ await writeFile(join(directory, filename), renderManualChangelog(selectedPackages, type, message.trim()));
100
+ s.stop("Created changelog file");
101
+ note(`${filename}\n${selectedPackages.join(", ")}: ${type}`, "Created changelog");
102
+ outro("Changelog ready.");
103
+ }
104
+ async function versionPackages(tegami, options) {
105
+ intro("Version Packages");
106
+ const { version: customVersion } = options.cli;
107
+ const draft = customVersion ? await customVersion() : await tegami.draft();
108
+ const packageIds = draft.getPackageIds();
109
+ if (packageIds.length === 0) {
110
+ note("No pending changelog entries matched workspace packages.", "Nothing to version");
111
+ outro("No versions changed.");
112
+ return;
113
+ }
114
+ note(packageIds.map((id) => {
115
+ const plan = draft.getPackage(id);
116
+ return `${id}: ${plan.type} (${plan.changelogIds.size} changelogs)`;
117
+ }).join("\n"), "Release plan");
118
+ if (draft.editable()) {
119
+ const s = spinner();
120
+ s.start("Updating package versions");
121
+ try {
122
+ await draft.createPublishPlan();
123
+ } catch (error) {
124
+ s.stop("Failed to create publish plan");
125
+ throw error;
126
+ }
127
+ s.stop("Package versions updated");
128
+ }
129
+ const context = await tegami._internal.context();
130
+ for (const plugin of context.plugins) try {
131
+ await plugin.cli?.afterVersion?.call(context, draft);
132
+ } catch (error) {
133
+ const details = error instanceof Error ? error.message : String(error);
134
+ throw new Error(`Plugin "${plugin.name}" failed during afterVersion:\n${details}`, { cause: error });
135
+ }
136
+ outro("Publish plan created.");
137
+ }
138
+ async function publishPackages(tegami, options) {
139
+ const dryRun = options.dryRun ?? false;
140
+ const { publish: customPublish } = options.cli;
141
+ intro(dryRun ? "Publish packages (dry run)" : "Publish packages");
142
+ const s = spinner();
143
+ s.start(dryRun ? "Validating publish plan" : "Publishing packages");
144
+ const result = customPublish ? await customPublish() : await tegami.publish({ dryRun });
145
+ if (result.state === "skipped") {
146
+ s.stop(dryRun ? "No publish plan to validate" : "Nothing to publish");
147
+ outro(`No publishable packages were found in ${result.planPath}.`);
148
+ return;
149
+ }
150
+ s.stop(dryRun ? "Publish plan validated" : "Publish complete");
151
+ note(result.packages.map((pkg) => {
152
+ const tag = pkg.distTag ? ` (${pkg.distTag})` : "";
153
+ const suffix = pkg.state === "failed" && pkg.error ? `: ${pkg.error}` : "";
154
+ return `${pkg.state === "success" ? "success" : "failed"} ${pkg.name}@${pkg.version}${tag}${suffix}`;
155
+ }).join("\n"), dryRun ? "Publish dry run" : "Publish result");
156
+ if (result.state === "failed") {
157
+ process.exitCode = 1;
158
+ outro("Some packages failed to publish.");
159
+ return;
160
+ }
161
+ outro(dryRun ? "Publish plan is valid." : "Packages published.");
162
+ }
163
+ function renderManualChangelog(packages, type, message) {
164
+ const heading = "#".repeat(type === "major" ? 1 : type === "minor" ? 2 : 3);
165
+ return [
166
+ "---",
167
+ `packages: ${JSON.stringify(packages)}`,
168
+ "---",
169
+ "",
170
+ `${heading} ${message}`,
171
+ ""
172
+ ].join("\n");
173
+ }
174
+ function changelogFilename() {
175
+ const date = /* @__PURE__ */ new Date();
176
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}-${Date.now().toString(36)}.md`;
177
+ }
178
+ async function runAction(tegami, action) {
179
+ try {
180
+ const context = await tegami._internal.context();
181
+ for (const plugin of context.plugins) try {
182
+ await plugin.cli?.init?.call(context);
183
+ } catch (error) {
184
+ const details = error instanceof Error ? error.message : String(error);
185
+ throw new Error(`Plugin "${plugin.name}" failed during cli.init:\n${details}`, { cause: error });
186
+ }
187
+ await action();
188
+ } catch (error) {
189
+ process.exitCode = 1;
190
+ if (error instanceof CancelledError) {
191
+ outro(error.message);
192
+ return;
193
+ }
194
+ note(error instanceof Error ? error.message : String(error), "Error");
195
+ outro("Command failed.");
196
+ }
197
+ }
198
+ //#endregion
199
+ export { createCli };
@@ -0,0 +1,4 @@
1
+ //#region src/utils/constants.ts
2
+ const isCI = () => Boolean(process.env.CI);
3
+ //#endregion
4
+ export { isCI as t };
@@ -2,48 +2,6 @@ import * as semver from "semver";
2
2
  import { SemVer } from "semver";
3
3
  import { z } from "zod";
4
4
 
5
- //#region src/workspace.d.ts
6
- /** Package discovered in the workspace. */
7
- declare abstract class WorkspacePackage {
8
- abstract readonly name: string;
9
- abstract readonly path: string;
10
- abstract readonly manager: string;
11
- abstract readonly version: string;
12
- abstract readonly publish: boolean;
13
- get distTag(): string | undefined;
14
- get id(): string;
15
- setVersion?(version: string): void;
16
- updateDependency?(target: WorkspacePackage, version: string, context: TegamiContext): Awaitable<void>;
17
- write?(): Awaitable<void>;
18
- protected updateRange(context: TegamiContext, spec: DependencySpec, next: semver.SemVer): Promise<DependencySpec>;
19
- }
20
- /** Dependency graph for discovered workspace packages. */
21
- declare class PackageGraph {
22
- private readonly byId;
23
- private readonly byName;
24
- constructor(packages?: WorkspacePackage[]);
25
- getPackages(): WorkspacePackage[];
26
- /** Get a package by exact id. */
27
- get(id: string): WorkspacePackage | undefined;
28
- /** Get packages by id, or every package matching a name. */
29
- getByName(nameOrId: string): WorkspacePackage[];
30
- /** scan package into graph, if the package id already exists, replace the existing one in graph */
31
- add(pkg: WorkspacePackage): void;
32
- delete(pkg: WorkspacePackage): void;
33
- }
34
- //#endregion
35
- //#region src/context.d.ts
36
- interface TegamiContext {
37
- cwd: string;
38
- changelogDir: string;
39
- planPath: string;
40
- options: TegamiOptions;
41
- plugins: TegamiPlugin[];
42
- graph: PackageGraph;
43
- /** error if doesn't exist */
44
- getRegistryClient(pkgOrId: WorkspacePackage | string): RegistryClient;
45
- }
46
- //#endregion
47
5
  //#region src/utils/semver.d.ts
48
6
  type BumpType = "major" | "minor" | "patch";
49
7
  //#endregion
@@ -89,6 +47,7 @@ declare class DraftPlan {
89
47
  deleteChangelog(id: string): boolean;
90
48
  /** Write the publish plan, update package versions, and consume changelog files. */
91
49
  createPublishPlan(): Promise<void>;
50
+ editable(): boolean;
92
51
  private assertPublishPlanFinished;
93
52
  private applyVersionChanges;
94
53
  private removeConsumedChangelogs;
@@ -157,14 +116,21 @@ interface PublishOptions {
157
116
  /** Validate the publish plan without publishing packages, creating tags, or running release plugins. */
158
117
  dryRun?: boolean;
159
118
  }
160
- interface PublishResult {
161
- /** Path to the publish plan that was executed. */
162
- planPath: string;
163
- state: "success" | "failed";
164
- packages: PackagePublishResult[];
165
- /** the persisted plan object. This is not a public API, can be changed without notice */
119
+ type PublishResult = {
120
+ state: "created";
121
+ packages: PackagePublishResult[]; /** Path to the publish plan that was executed. */
122
+ planPath: string; /** the persisted plan object. This is not a public API, can be changed without notice */
166
123
  _rawPlan: PlanStore;
167
- }
124
+ } | {
125
+ state: "failed";
126
+ error?: string;
127
+ packages: PackagePublishResult[]; /** Path to the publish plan that was executed. */
128
+ planPath: string; /** the persisted plan object. This is not a public API, can be changed without notice */
129
+ _rawPlan: PlanStore;
130
+ } | {
131
+ state: "skipped"; /** Path to the publish plan that was executed or missing. */
132
+ planPath: string;
133
+ };
168
134
  type PackagePublishResult = ({
169
135
  state: "failed";
170
136
  error?: string;
@@ -179,6 +145,36 @@ type PackagePublishResult = ({
179
145
  changelogs: ChangelogEntry[];
180
146
  };
181
147
  //#endregion
148
+ //#region src/workspace.d.ts
149
+ /** Package discovered in the workspace. */
150
+ declare abstract class WorkspacePackage {
151
+ abstract readonly name: string;
152
+ abstract readonly path: string;
153
+ abstract readonly manager: string;
154
+ abstract readonly version: string;
155
+ abstract readonly publish: boolean;
156
+ get distTag(): string | undefined;
157
+ get id(): string;
158
+ setVersion?(version: string): void;
159
+ updateDependency?(target: WorkspacePackage, version: string, context: TegamiContext): Awaitable<void>;
160
+ write?(): Awaitable<void>;
161
+ protected updateRange(context: TegamiContext, spec: DependencySpec, next: semver.SemVer): Promise<DependencySpec>;
162
+ }
163
+ /** Dependency graph for discovered workspace packages. */
164
+ declare class PackageGraph {
165
+ private readonly byId;
166
+ private readonly byName;
167
+ constructor(packages?: WorkspacePackage[]);
168
+ getPackages(): WorkspacePackage[];
169
+ /** Get a package by exact id. */
170
+ get(id: string): WorkspacePackage | undefined;
171
+ /** Get packages by id, or every package matching a name. */
172
+ getByName(nameOrId: string): WorkspacePackage[];
173
+ /** scan package into graph, if the package id already exists, replace the existing one in graph */
174
+ add(pkg: WorkspacePackage): void;
175
+ delete(pkg: WorkspacePackage): void;
176
+ }
177
+ //#endregion
182
178
  //#region src/providers/npm.d.ts
183
179
  declare class NpmPackage extends WorkspacePackage {
184
180
  readonly path: string;
@@ -219,6 +215,7 @@ interface LogGenerator {
219
215
  generate(this: TegamiContext, opts: {
220
216
  packageName: string;
221
217
  version: string;
218
+ distTag?: string;
222
219
  changelogs: ChangelogEntry[];
223
220
  }): string | Promise<string>;
224
221
  }
@@ -253,6 +250,11 @@ interface TegamiPlugin {
253
250
  afterPublish?(this: TegamiContext & {
254
251
  publishOptions: PublishOptions;
255
252
  }, result: PublishResult): Awaitable<PublishResult | void | undefined>;
253
+ /** CLI lifecycle hooks. */
254
+ cli?: {
255
+ /** Called once before a CLI command runs. */init?(this: TegamiContext): Awaitable<void>; /** Called after `tegami version` creates a publish plan. */
256
+ afterVersion?(this: TegamiContext, draft: DraftPlan): Awaitable<void>;
257
+ };
256
258
  /**
257
259
  * @param pkg - the package that referenced the dependency
258
260
  * @param spec - the referenced dependency & its range
@@ -280,4 +282,16 @@ interface DependencySpec {
280
282
  range: string;
281
283
  }
282
284
  //#endregion
283
- export { PackageOptions as _, TegamiOptions as a, PackageGraph as b, NpmClient as c, npm as d, PackagePublishResult as f, DraftPlan as g, PlanStore as h, RegistryClient as i, NpmPackage as l, PublishResult as m, LogGenerator as n, TegamiPlugin as o, PublishOptions as p, PublishPlanStatus as r, TegamiPluginOption as s, Awaitable as t, NpmRegistryClient as u, PackagePlan as v, WorkspacePackage as x, TegamiContext as y };
285
+ //#region src/context.d.ts
286
+ interface TegamiContext {
287
+ cwd: string;
288
+ changelogDir: string;
289
+ planPath: string;
290
+ options: TegamiOptions;
291
+ plugins: TegamiPlugin[];
292
+ graph: PackageGraph;
293
+ /** error if doesn't exist */
294
+ getRegistryClient(pkgOrId: WorkspacePackage | string): RegistryClient;
295
+ }
296
+ //#endregion
297
+ export { PublishResult as _, RegistryClient as a, PackageOptions as b, TegamiPluginOption as c, NpmRegistryClient as d, npm as f, PublishOptions as g, PackagePublishResult as h, PublishPlanStatus as i, NpmClient as l, WorkspacePackage as m, Awaitable as n, TegamiOptions as o, PackageGraph as p, LogGenerator as r, TegamiPlugin as s, TegamiContext as t, NpmPackage as u, PlanStore as v, PackagePlan as x, DraftPlan as y };
@@ -0,0 +1,12 @@
1
+ //#region src/utils/exec.ts
2
+ function commandOutput(result) {
3
+ return [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
4
+ }
5
+ function execFailure(context, result) {
6
+ const lines = [context, `(exit ${result.exitCode})`];
7
+ const output = commandOutput(result);
8
+ if (output) lines.push(output);
9
+ return lines.join("\n");
10
+ }
11
+ //#endregion
12
+ export { execFailure as t };
@@ -1,4 +1,4 @@
1
- import { n as LogGenerator } from "../types-DdIMewK9.mjs";
1
+ import { r as LogGenerator } from "../context-CC36jtz1.mjs";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
@@ -1,8 +1,9 @@
1
+ import { n as formatPackageVersion } from "../semver-FSWx3_34.mjs";
1
2
  //#region src/generators/simple.ts
2
3
  function simpleGenerator() {
3
- return { generate({ changelogs, version }) {
4
+ return { generate({ changelogs, version, packageName, distTag }) {
4
5
  return [
5
- `## ${version}`,
6
+ `## ${formatPackageVersion(packageName, version, distTag)}`,
6
7
  "",
7
8
  ...changelogs.flatMap((entry) => [
8
9
  `### ${entry.title}`,
@@ -0,0 +1,35 @@
1
+ import { _ as PublishResult, g as PublishOptions, o as TegamiOptions, p as PackageGraph, t as TegamiContext, y as DraftPlan } from "./context-CC36jtz1.mjs";
2
+
3
+ //#region src/changelog/create.d.ts
4
+ interface CreateChangelogOptions {
5
+ /** Start revision. Defaults to the latest reachable git tag, or all history if none exists. */
6
+ from?: string;
7
+ /** End revision. Defaults to HEAD. */
8
+ to?: string;
9
+ }
10
+ interface CreatedChangelog {
11
+ filename: string;
12
+ path: string;
13
+ packages: string[];
14
+ changes: number;
15
+ }
16
+ //#endregion
17
+ //#region src/index.d.ts
18
+ interface Tegami {
19
+ /** Create pending changelog files from git commit history. */
20
+ generateChangelog(options?: CreateChangelogOptions): Promise<CreatedChangelog[]>;
21
+ /** Build an editable draft from pending changelog files. */
22
+ draft(): Promise<DraftPlan>;
23
+ /** Publish the current publish plan. */
24
+ publish(options?: PublishOptions): Promise<PublishResult>;
25
+ /** Internal APIs, do not use it unless you know what you are doing */
26
+ _internal: {
27
+ context(): Promise<TegamiContext>;
28
+ graph(): Promise<PackageGraph>;
29
+ options: TegamiOptions;
30
+ };
31
+ }
32
+ /** Create a Tegami project handle. */
33
+ declare function tegami(options?: TegamiOptions): Tegami;
34
+ //#endregion
35
+ export { CreatedChangelog as i, tegami as n, CreateChangelogOptions as r, Tegami as t };
package/dist/index.d.mts CHANGED
@@ -1,31 +1,3 @@
1
- import { _ as PackageOptions, a as TegamiOptions, b as PackageGraph, f as PackagePublishResult, g as DraftPlan, i as RegistryClient, m as PublishResult, n as LogGenerator, o as TegamiPlugin, p as PublishOptions, s as TegamiPluginOption, v as PackagePlan, x as WorkspacePackage } from "./types-DdIMewK9.mjs";
2
-
3
- //#region src/changelog/create.d.ts
4
- interface CreateChangelogOptions {
5
- /** Start revision. Defaults to the latest reachable git tag, or all history if none exists. */
6
- from?: string;
7
- /** End revision. Defaults to HEAD. */
8
- to?: string;
9
- }
10
- interface CreatedChangelog {
11
- filename: string;
12
- path: string;
13
- packages: string[];
14
- changes: number;
15
- }
16
- //#endregion
17
- //#region src/index.d.ts
18
- interface Tegami {
19
- /** Create pending changelog files from git commit history. */
20
- createChangelog(options?: CreateChangelogOptions): Promise<CreatedChangelog[]>;
21
- /** Build an editable draft from pending changelog files. */
22
- draft(): Promise<DraftPlan>;
23
- /** Discover workspace packages and their dependency relationships. */
24
- graph(): Promise<PackageGraph>;
25
- /** Publish the current publish plan. */
26
- publish(options?: PublishOptions): Promise<PublishResult>;
27
- }
28
- /** Create a Tegami project handle. */
29
- declare function tegami(options?: TegamiOptions): Tegami;
30
- //#endregion
1
+ import { _ as PublishResult, a as RegistryClient, b as PackageOptions, c as TegamiPluginOption, g as PublishOptions, h as PackagePublishResult, m as WorkspacePackage, o as TegamiOptions, p as PackageGraph, r as LogGenerator, s as TegamiPlugin, x as PackagePlan, y as DraftPlan } from "./context-CC36jtz1.mjs";
2
+ import { i as CreatedChangelog, n as tegami, r as CreateChangelogOptions, t as Tegami } from "./index-DJ7YxxdM.mjs";
31
3
  export { type CreateChangelogOptions, type CreatedChangelog, type DraftPlan, type LogGenerator, type PackageGraph, type PackageOptions, type PackagePlan, type PackagePublishResult, type PublishOptions, type PublishResult, type RegistryClient, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { r as isNodeError, t as PackageGraph } from "./workspace-B5_i21S0.mjs";
2
2
  import { cargo } from "./providers/cargo.mjs";
3
- import { a as planStoreSchema, i as changelogFrontmatterSchema, r as npm } from "./npm-BSE_dtB3.mjs";
3
+ import { a as planStoreSchema, i as changelogFrontmatterSchema, r as npm } from "./npm-BpFlXy8I.mjs";
4
+ import { i as maxBump, t as bumpVersion } from "./semver-FSWx3_34.mjs";
4
5
  import { simpleGenerator } from "./generators/simple.mjs";
5
6
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
6
7
  import path, { basename, dirname, join, resolve } from "node:path";
7
8
  import { x } from "tinyexec";
8
- import { inc } from "semver";
9
9
  import { load } from "js-yaml";
10
10
  import { fromMarkdown } from "mdast-util-from-markdown";
11
11
  import { toMarkdown } from "mdast-util-to-markdown";
@@ -178,18 +178,6 @@ function resolvePlugins(plugins = []) {
178
178
  return plugins.flat(Infinity).sort((a, b) => PLUGIN_ORDER[a.enforce ?? "default"] - PLUGIN_ORDER[b.enforce ?? "default"]);
179
179
  }
180
180
  //#endregion
181
- //#region src/utils/semver.ts
182
- function maxBump(a, b) {
183
- if (a === "major" || b === "major") return "major";
184
- if (a === "minor" || b === "minor") return "minor";
185
- return "patch";
186
- }
187
- function bumpVersion(version, type) {
188
- const next = inc(version, type);
189
- if (!next) throw new Error(`Invalid semver version: ${version}`);
190
- return next;
191
- }
192
- //#endregion
193
181
  //#region src/draft.ts
194
182
  var DraftPlan = class {
195
183
  changelogs;
@@ -253,6 +241,9 @@ var DraftPlan = class {
253
241
  await writeFile(this.context.planPath, planStoreSchema.encode(plan));
254
242
  await this.removeConsumedChangelogs();
255
243
  }
244
+ editable() {
245
+ return !this.#created;
246
+ }
256
247
  async assertPublishPlanFinished() {
257
248
  const content = await readFile(this.context.planPath, "utf8").catch(() => void 0);
258
249
  if (!content) return;
@@ -312,6 +303,7 @@ var DraftPlan = class {
312
303
  const generated = await generator.generate.call(this.context, {
313
304
  packageName: pkg.name,
314
305
  version: pkg.version,
306
+ distTag: plan.distTag,
315
307
  changelogs
316
308
  });
317
309
  const path = join(pkg.path, "CHANGELOG.md");
@@ -470,17 +462,9 @@ function headingToBump(depth) {
470
462
  }
471
463
  //#endregion
472
464
  //#region src/publish.ts
473
- async function publishFromPlan(context, plan, options) {
474
- const packages = await publishStoredPlan(plan, context, options);
475
- return {
476
- planPath: context.planPath,
477
- state: packages.some((pkg) => pkg.state === "failed") ? "failed" : "success",
478
- packages,
479
- _rawPlan: plan
480
- };
481
- }
482
- async function publishStoredPlan(store, context, { dryRun = false }) {
483
- const results = [];
465
+ async function publishFromPlan(context, store, options) {
466
+ const { dryRun = false } = options;
467
+ const packages = [];
484
468
  for (const [id, plan] of Object.entries(store.packages)) {
485
469
  if (!plan.publish) continue;
486
470
  const pkg = context.graph.get(id);
@@ -496,7 +480,7 @@ async function publishStoredPlan(store, context, { dryRun = false }) {
496
480
  }
497
481
  if (!dryRun) {
498
482
  if (await context.getRegistryClient(pkg).packageVersionExists(pkg, pkg.version)) {
499
- results.push({
483
+ packages.push({
500
484
  id: pkg.id,
501
485
  name: pkg.name,
502
486
  version: pkg.version,
@@ -509,7 +493,7 @@ async function publishStoredPlan(store, context, { dryRun = false }) {
509
493
  }
510
494
  try {
511
495
  if (!dryRun) await context.getRegistryClient(pkg).publish(pkg, { distTag: plan.distTag });
512
- results.push({
496
+ packages.push({
513
497
  id: pkg.id,
514
498
  name: pkg.name,
515
499
  version: pkg.version,
@@ -518,7 +502,7 @@ async function publishStoredPlan(store, context, { dryRun = false }) {
518
502
  changelogs
519
503
  });
520
504
  } catch (error) {
521
- results.push({
505
+ packages.push({
522
506
  id: pkg.id,
523
507
  name: pkg.name,
524
508
  version: pkg.version,
@@ -529,32 +513,58 @@ async function publishStoredPlan(store, context, { dryRun = false }) {
529
513
  });
530
514
  }
531
515
  }
532
- return results;
516
+ if (packages.length === 0) return {
517
+ state: "skipped",
518
+ planPath: context.planPath
519
+ };
520
+ return {
521
+ planPath: context.planPath,
522
+ state: packages.some((pkg) => pkg.state === "failed") ? "failed" : "created",
523
+ packages,
524
+ _rawPlan: store
525
+ };
533
526
  }
534
527
  //#endregion
535
528
  //#region src/index.ts
536
529
  /** Create a Tegami project handle. */
537
530
  function tegami(options = {}) {
531
+ const $context = init();
532
+ async function init() {
533
+ return createTegamiContext(options);
534
+ }
538
535
  return {
539
- async createChangelog(createOptions = {}) {
540
- return createChangelog(await createTegamiContext(options), createOptions);
536
+ async generateChangelog(createOptions = {}) {
537
+ return createChangelog(await $context, createOptions);
538
+ },
539
+ _internal: {
540
+ options,
541
+ context() {
542
+ return $context;
543
+ },
544
+ async graph() {
545
+ return (await $context).graph;
546
+ }
541
547
  },
542
548
  async draft() {
543
- const context = await createTegamiContext(options);
549
+ const context = await $context;
544
550
  let plan = createDraftPlan(await readChangelogEntries(context.cwd, context.changelogDir), context);
545
551
  for (const plugin of context.plugins) plan = await plugin.initPlan?.call(context, plan) ?? plan;
546
552
  return plan;
547
553
  },
548
- async graph() {
549
- return (await createTegamiContext(options)).graph;
550
- },
551
554
  async publish(publishOptions = {}) {
552
- const context = await createTegamiContext(options);
555
+ const context = await $context;
556
+ if ((await readChangelogEntries(context.cwd, context.changelogDir)).length > 0) return {
557
+ state: "skipped",
558
+ planPath: context.planPath
559
+ };
553
560
  const parsed = await readFile(context.planPath, "utf8").then((content) => planStoreSchema.decode(content)).catch((error) => {
554
561
  if (isNodeError(error) && error.code === "ENOENT") return void 0;
555
562
  throw error;
556
563
  });
557
- if (parsed === void 0) throw new Error(`No publish plan found at ${context.planPath}.`);
564
+ if (parsed === void 0) return {
565
+ state: "skipped",
566
+ planPath: context.planPath
567
+ };
558
568
  let result = await publishFromPlan(context, parsed, publishOptions);
559
569
  const publishCtx = {
560
570
  ...context,
@@ -1,4 +1,5 @@
1
1
  import { n as WorkspacePackage, r as isNodeError } from "./workspace-B5_i21S0.mjs";
2
+ import { t as execFailure } from "./exec-hOS852t5.mjs";
2
3
  import { readFile, writeFile } from "node:fs/promises";
3
4
  import { join, normalize } from "node:path";
4
5
  import { x } from "tinyexec";
@@ -168,13 +169,13 @@ var NpmRegistryClient = class {
168
169
  return info;
169
170
  }
170
171
  async publish(pkg, options = {}) {
172
+ const client = await this.resolveClient();
171
173
  const args = ["publish"];
172
174
  const distTag = options.distTag ?? pkg.distTag;
173
175
  if (distTag) args.push("--tag", distTag);
174
- await x(await this.resolveClient(), args, {
175
- nodeOptions: { cwd: pkg.path },
176
- throwOnError: true
177
- });
176
+ if (client === "pnpm") args.push("--no-git-checks");
177
+ const result = await x(client, args, { nodeOptions: { cwd: pkg.path } });
178
+ if (result.exitCode !== 0) throw new Error(execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, result));
178
179
  }
179
180
  async publishPlanStatus(plan) {
180
181
  for (const [name, pkgPlan] of Object.entries(plan.packages)) {
@@ -1,9 +1,11 @@
1
- import { o as TegamiPlugin } from "../types-DdIMewK9.mjs";
1
+ import { s as TegamiPlugin } from "../context-CC36jtz1.mjs";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
5
5
  /** Set to false to skip creating git tags after all packages publish successfully. */
6
6
  createTags?: boolean;
7
+ /** Push created tags to origin. Defaults to true in CI. */
8
+ pushTags?: boolean;
7
9
  }
8
10
  /**
9
11
  * Basic Git integrations:
@@ -12,8 +14,5 @@ interface GitPluginOptions {
12
14
  * Note: you do not need this with `github` plugin enabled.
13
15
  */
14
16
  declare function git(options?: GitPluginOptions): TegamiPlugin;
15
- /** create a Git tag, ignored if already exists */
16
- declare function createGitTag(cwd: string, tag: string): Promise<void>;
17
- declare function gitTagExists(cwd: string, tag: string): Promise<boolean>;
18
17
  //#endregion
19
- export { GitPluginOptions, createGitTag, git, gitTagExists };
18
+ export { GitPluginOptions, git };
@@ -1,3 +1,5 @@
1
+ import { t as execFailure } from "../exec-hOS852t5.mjs";
2
+ import { t as isCI } from "../constants-B9qjNfvr.mjs";
1
3
  import { x } from "tinyexec";
2
4
  //#region src/plugins/git.ts
3
5
  /**
@@ -7,42 +9,72 @@ import { x } from "tinyexec";
7
9
  * Note: you do not need this with `github` plugin enabled.
8
10
  */
9
11
  function git(options = {}) {
10
- const { createTags = true } = options;
12
+ const { createTags = true, pushTags = isCI() } = options;
11
13
  return {
12
14
  name: "git",
13
15
  enforce: "pre",
16
+ cli: { async init() {
17
+ if (!isCI()) return;
18
+ const gitOptions = { nodeOptions: { cwd: this.cwd } };
19
+ for (const args of [[
20
+ "config",
21
+ "user.name",
22
+ "github-actions[bot]"
23
+ ], [
24
+ "config",
25
+ "user.email",
26
+ "41898282+github-actions[bot]@users.noreply.github.com"
27
+ ]]) {
28
+ const result = await x("git", [...args], gitOptions);
29
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to configure git user for GitHub Actions.", result));
30
+ }
31
+ } },
14
32
  async afterPublish(result) {
15
- const { graph, publishOptions: { dryRun = false } } = this;
16
- if (dryRun || !createTags || result.state === "failed") return result;
33
+ const { cwd, graph, publishOptions: { dryRun = false } } = this;
34
+ if (dryRun || !createTags || result.state !== "created") return result;
35
+ const createdTags = [];
17
36
  for (const pkg of result.packages) try {
18
37
  const gitTag = `${pkg.name}@${pkg.version}`;
19
- await createGitTag(graph.get(pkg.id).path, gitTag);
38
+ const packagePath = graph.get(pkg.id).path;
39
+ if (await createGitTag(packagePath, gitTag)) createdTags.push(gitTag);
20
40
  pkg.gitTag = gitTag;
21
41
  } catch (error) {
42
+ const errorMessage = error instanceof Error ? error.message : String(error);
22
43
  return {
23
44
  ...result,
24
45
  state: "failed",
46
+ error: errorMessage,
25
47
  packages: result.packages.map((pkgResult) => {
26
48
  if (pkgResult.id === pkg.id) return {
27
49
  ...pkgResult,
28
50
  state: "failed",
29
- error: error instanceof Error ? error.message : String(error)
51
+ error: errorMessage
30
52
  };
31
53
  return pkgResult;
32
54
  })
33
55
  };
34
56
  }
57
+ if (pushTags && createdTags.length > 0) try {
58
+ await pushGitTags(cwd, createdTags);
59
+ } catch (error) {
60
+ return {
61
+ ...result,
62
+ state: "failed",
63
+ error: error instanceof Error ? error.message : String(error)
64
+ };
65
+ }
35
66
  return result;
36
67
  }
37
68
  };
38
69
  }
39
70
  /** create a Git tag, ignored if already exists */
40
71
  async function createGitTag(cwd, tag) {
41
- if (await gitTagExists(cwd, tag)) return;
72
+ if (await gitTagExists(cwd, tag)) return false;
42
73
  await x("git", ["tag", tag], {
43
74
  nodeOptions: { cwd },
44
75
  throwOnError: true
45
76
  });
77
+ return true;
46
78
  }
47
79
  async function gitTagExists(cwd, tag) {
48
80
  return (await x("git", [
@@ -52,5 +84,16 @@ async function gitTagExists(cwd, tag) {
52
84
  `refs/tags/${tag}`
53
85
  ], { nodeOptions: { cwd } })).exitCode === 0;
54
86
  }
87
+ async function pushGitTags(cwd, tags) {
88
+ if (tags.length === 0) return;
89
+ await x("git", [
90
+ "push",
91
+ "origin",
92
+ ...tags
93
+ ], {
94
+ nodeOptions: { cwd },
95
+ throwOnError: true
96
+ });
97
+ }
55
98
  //#endregion
56
- export { createGitTag, git, gitTagExists };
99
+ export { git };
@@ -1,4 +1,4 @@
1
- import { f as PackagePublishResult, o as TegamiPlugin, t as Awaitable } from "../types-DdIMewK9.mjs";
1
+ import { h as PackagePublishResult, n as Awaitable, s as TegamiPlugin } from "../context-CC36jtz1.mjs";
2
2
  import { GitPluginOptions } from "./git.mjs";
3
3
 
4
4
  //#region src/plugins/github.d.ts
@@ -10,12 +10,30 @@ interface GithubRelease {
10
10
  /** Whether to mark release as prerelease */
11
11
  prerelease?: boolean;
12
12
  }
13
+ interface VersionPullRequestOptions {
14
+ /** Pull request branch. */
15
+ branch?: string;
16
+ /** Pull request base branch. */
17
+ base?: string;
18
+ /** Pull request title. */
19
+ title?: string;
20
+ /** Pull request body. */
21
+ body?: string;
22
+ }
13
23
  /** Options for creating GitHub releases after a successful publish. */
14
24
  interface GitHubPluginOptions extends GitPluginOptions {
15
25
  /** GitHub repository. */
16
26
  repo?: string;
17
27
  /** override release details, return `false` to skip */
18
28
  onCreateRelease?: (result: PackagePublishResult) => Awaitable<GithubRelease | false>;
29
+ cli?: {
30
+ /**
31
+ * Open a version pull request after versioning.
32
+ * Defaults to enabled in CI and disabled locally.
33
+ * Set to `true` to always create the pull request.
34
+ */
35
+ createVersionPR?: boolean | VersionPullRequestOptions;
36
+ };
19
37
  }
20
38
  /** Create GitHub releases for successfully published packages after the whole plan succeeds. */
21
39
  declare function github(options?: GitHubPluginOptions): TegamiPlugin[];
@@ -1,3 +1,6 @@
1
+ import { t as execFailure } from "../exec-hOS852t5.mjs";
2
+ import { a as previousVersion, r as formatVersionBump } from "../semver-FSWx3_34.mjs";
3
+ import { t as isCI } from "../constants-B9qjNfvr.mjs";
1
4
  import { git } from "./git.mjs";
2
5
  import { x } from "tinyexec";
3
6
  //#region src/plugins/github.ts
@@ -18,16 +21,118 @@ function github(options = {}) {
18
21
  ];
19
22
  if (options.repo) args.push("--repo", options.repo);
20
23
  if (release.prerelease) args.push("--prerelease");
21
- await x("gh", args, { throwOnError: true });
24
+ const result = await x("gh", args);
25
+ if (result.exitCode !== 0) throw new Error(execFailure(`Failed to create GitHub release for ${pkg.name}@${pkg.version}.`, result));
26
+ }
27
+ function resolvePROptions() {
28
+ const setting = options.cli?.createVersionPR ?? isCI();
29
+ if (setting === false) return [false];
30
+ return [true, typeof setting === "object" ? setting : {}];
22
31
  }
23
32
  return [git(options), {
24
33
  name: "github",
34
+ cli: {
35
+ async init() {
36
+ if (!isCI()) return;
37
+ const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
38
+ const repository = options.repo ?? process.env.GITHUB_REPOSITORY;
39
+ if (!token || !repository) return;
40
+ const result = await x("git", [
41
+ "remote",
42
+ "set-url",
43
+ "origin",
44
+ `https://x-access-token:${token}@github.com/${repository}.git`
45
+ ], { nodeOptions: { cwd: this.cwd } });
46
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to configure git remote for GitHub Actions.", result));
47
+ },
48
+ async afterVersion(draft) {
49
+ const { cwd } = this;
50
+ const [enabled, config] = resolvePROptions();
51
+ if (!enabled || !await hasGitChanges(cwd)) return;
52
+ const { branch = "tegami/version-packages", base = "main", title = "Version Packages", body = defaultVersionPRBody(draft, this) } = config;
53
+ const gitOptions = { nodeOptions: { cwd } };
54
+ let result = await x("git", [
55
+ "checkout",
56
+ "-B",
57
+ branch
58
+ ], gitOptions);
59
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to create the version pull request branch.", result));
60
+ result = await x("git", ["add", "-A"], gitOptions);
61
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to stage version changes.", result));
62
+ result = await x("git", [
63
+ "commit",
64
+ "-m",
65
+ title
66
+ ], gitOptions);
67
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to commit version changes.", result));
68
+ result = await x("git", [
69
+ "push",
70
+ "--force",
71
+ "-u",
72
+ "origin",
73
+ branch
74
+ ], gitOptions);
75
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to push the version branch to origin. Ensure `origin` is configured and you have push access.", result));
76
+ if (await hasOpenPullRequest(branch, options.repo)) return;
77
+ const args = [
78
+ "pr",
79
+ "create",
80
+ "--title",
81
+ title,
82
+ "--body",
83
+ body,
84
+ "--head",
85
+ branch,
86
+ "--base",
87
+ base
88
+ ];
89
+ if (options.repo) args.push("--repo", options.repo);
90
+ const prResult = await x("gh", args);
91
+ if (prResult.exitCode !== 0) throw new Error(execFailure("Failed to create the version pull request.", prResult));
92
+ }
93
+ },
25
94
  async afterPublish(result) {
26
- if (result.state !== "success") return;
95
+ if (result.state !== "created") return;
27
96
  await Promise.all(result.packages.map(createGithubRelease));
28
97
  }
29
98
  }];
30
99
  }
100
+ async function hasGitChanges(cwd) {
101
+ return (await x("git", ["status", "--porcelain"], { nodeOptions: { cwd } })).stdout.trim().length > 0;
102
+ }
103
+ async function hasOpenPullRequest(branch, repo) {
104
+ const args = [
105
+ "pr",
106
+ "list",
107
+ "--head",
108
+ branch,
109
+ "--state",
110
+ "open",
111
+ "--json",
112
+ "number"
113
+ ];
114
+ if (repo) args.push("--repo", repo);
115
+ const result = await x("gh", args);
116
+ if (result.exitCode !== 0) throw new Error(execFailure("Failed to check for an existing version pull request.", result));
117
+ return result.stdout.trim() !== "[]";
118
+ }
119
+ function defaultVersionPRBody(draft, context) {
120
+ const packageLines = [];
121
+ for (const id of draft.getPackageIds()) {
122
+ const packagePlan = draft.getPackage(id);
123
+ if (!packagePlan) continue;
124
+ const pkg = context.graph.get(id);
125
+ if (!pkg) continue;
126
+ const publish = packagePlan.publish ? "" : " (no publish)";
127
+ const previous = previousVersion(pkg.version, packagePlan.type);
128
+ packageLines.push(`- ${formatVersionBump(pkg.name, previous, pkg.version, packagePlan.distTag)}${publish}`);
129
+ }
130
+ const changelogLines = draft.getChangelogIds().map((id) => draft.getChangelog(id)).filter((entry) => entry !== void 0).map((entry) => `- ${entry.title}`);
131
+ const sections = ["## Summary", ...packageLines];
132
+ if (changelogLines.length > 0) sections.push("", "## Changelogs", ...changelogLines);
133
+ sections.push("", "Merge this PR to publish the versioned packages.");
134
+ return sections.join("\n");
135
+ }
31
136
  function defaultNotes(pkg) {
32
137
  const entries = pkg.changelogs;
33
138
  if (entries.length > 0) return entries.map((entry) => [`### ${entry.title}`, entry.content].filter(Boolean).join("\n\n")).join("\n\n");
@@ -1,4 +1,4 @@
1
- import { b as PackageGraph, h as PlanStore, i as RegistryClient, o as TegamiPlugin, r as PublishPlanStatus, x as WorkspacePackage, y as TegamiContext } from "../types-DdIMewK9.mjs";
1
+ import { a as RegistryClient, i as PublishPlanStatus, m as WorkspacePackage, p as PackageGraph, s as TegamiPlugin, t as TegamiContext, v as PlanStore } from "../context-CC36jtz1.mjs";
2
2
  import { TomlTable } from "smol-toml";
3
3
 
4
4
  //#region src/providers/cargo.d.ts
@@ -3,7 +3,7 @@ import { readFile, writeFile } from "node:fs/promises";
3
3
  import { join, normalize } from "node:path";
4
4
  import { x } from "tinyexec";
5
5
  import * as semver from "semver";
6
- import { parse, stringify } from "smol-toml";
6
+ import { parse as parse$1, stringify } from "smol-toml";
7
7
  import { glob } from "tinyglobby";
8
8
  //#region src/providers/cargo.ts
9
9
  const DEP_FIELDS = [
@@ -173,7 +173,7 @@ function dependencyTables(manifest) {
173
173
  return tables;
174
174
  }
175
175
  async function readCargoManifest(path) {
176
- return parse(await readFile(join(path, "Cargo.toml"), "utf8"));
176
+ return parse$1(await readFile(join(path, "Cargo.toml"), "utf8"));
177
177
  }
178
178
  function tableValue(value) {
179
179
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
@@ -1,2 +1,2 @@
1
- import { c as NpmClient, d as npm, l as NpmPackage, u as NpmRegistryClient } from "../types-DdIMewK9.mjs";
1
+ import { d as NpmRegistryClient, f as npm, l as NpmClient, u as NpmPackage } from "../context-CC36jtz1.mjs";
2
2
  export { NpmClient, NpmPackage, NpmRegistryClient, npm };
@@ -1,2 +1,2 @@
1
- import { n as NpmRegistryClient, r as npm, t as NpmPackage } from "../npm-BSE_dtB3.mjs";
1
+ import { n as NpmRegistryClient, r as npm, t as NpmPackage } from "../npm-BpFlXy8I.mjs";
2
2
  export { NpmPackage, NpmRegistryClient, npm };
@@ -0,0 +1,35 @@
1
+ import { inc, parse } from "semver";
2
+ //#region src/utils/semver.ts
3
+ function formatPackageVersion(name, version, distTag) {
4
+ return `${name}@${version}${distTag ? ` (${distTag})` : ""}`;
5
+ }
6
+ function previousVersion(version, type) {
7
+ const parsed = parse(version);
8
+ if (!parsed) throw new Error(`Invalid semver version: ${version}`);
9
+ if (type === "major") {
10
+ parsed.major = Math.max(0, parsed.major - 1);
11
+ parsed.minor = 0;
12
+ parsed.patch = 0;
13
+ } else if (type === "minor") {
14
+ parsed.minor = Math.max(0, parsed.minor - 1);
15
+ parsed.patch = 0;
16
+ } else parsed.patch = Math.max(0, parsed.patch - 1);
17
+ parsed.prerelease = [];
18
+ parsed.build = [];
19
+ return parsed.format();
20
+ }
21
+ function formatVersionBump(name, from, to, distTag) {
22
+ return `${name}@${from} → ${name}@${to}${distTag ? ` (${distTag})` : ""}`;
23
+ }
24
+ function maxBump(a, b) {
25
+ if (a === "major" || b === "major") return "major";
26
+ if (a === "minor" || b === "minor") return "minor";
27
+ return "patch";
28
+ }
29
+ function bumpVersion(version, type) {
30
+ const next = inc(version, type);
31
+ if (!next) throw new Error(`Invalid semver version: ${version}`);
32
+ return next;
33
+ }
34
+ //#endregion
35
+ export { previousVersion as a, maxBump as i, formatPackageVersion as n, formatVersionBump as r, bumpVersion as t };
package/package.json CHANGED
@@ -1,32 +1,12 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "0.0.0",
4
- "description": "Utility for package versioning & publish",
5
- "license": "MIT",
6
- "author": "Fuma Nama",
7
- "repository": "github:fuma-nama/tegami",
8
- "files": [
9
- "dist"
10
- ],
11
- "type": "module",
12
- "exports": {
13
- ".": "./dist/index.mjs",
14
- "./generators/simple": "./dist/generators/simple.mjs",
15
- "./plugins/git": "./dist/plugins/git.mjs",
16
- "./plugins/github": "./dist/plugins/github.mjs",
17
- "./providers/cargo": "./dist/providers/cargo.mjs",
18
- "./providers/npm": "./dist/providers/npm.mjs",
19
- "./package.json": "./package.json"
20
- },
3
+ "version": "0.0.1",
21
4
  "publishConfig": {
22
5
  "access": "public"
23
6
  },
24
- "scripts": {
25
- "types:check": "tsc --noEmit",
26
- "build": "tsdown",
27
- "dev": "tsdown --watch"
28
- },
29
7
  "dependencies": {
8
+ "@clack/prompts": "^1.5.1",
9
+ "commander": "^15.0.0",
30
10
  "js-yaml": "^4.2.0",
31
11
  "mdast-util-from-markdown": "^2.0.3",
32
12
  "mdast-util-to-markdown": "^2.1.2",
@@ -38,12 +18,38 @@
38
18
  "zod": "^4.4.3"
39
19
  },
40
20
  "devDependencies": {
41
- "@repo/typescript-config": "workspace:*",
42
21
  "@types/js-yaml": "^4.0.9",
43
22
  "@types/mdast": "^4.0.4",
44
23
  "@types/node": "^25.5.0",
45
24
  "@types/semver": "^7.7.1",
46
25
  "tsdown": "^0.22.2",
47
- "typescript": "6.0.3"
26
+ "typescript": "6.0.3",
27
+ "@repo/typescript-config": "0.0.0"
28
+ },
29
+ "description": "Utility for package versioning & publish",
30
+ "license": "MIT",
31
+ "author": "Fuma Nama",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "github:fuma-nama/tegami"
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "type": "module",
40
+ "exports": {
41
+ ".": "./dist/index.mjs",
42
+ "./cli": "./dist/cli/index.mjs",
43
+ "./generators/simple": "./dist/generators/simple.mjs",
44
+ "./plugins/git": "./dist/plugins/git.mjs",
45
+ "./plugins/github": "./dist/plugins/github.mjs",
46
+ "./providers/cargo": "./dist/providers/cargo.mjs",
47
+ "./providers/npm": "./dist/providers/npm.mjs",
48
+ "./package.json": "./package.json"
49
+ },
50
+ "scripts": {
51
+ "types:check": "tsc --noEmit",
52
+ "build": "tsdown",
53
+ "dev": "tsdown --watch"
48
54
  }
49
- }
55
+ }