@kb-labs/release-manager-cli 2.82.0 → 2.88.0

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 (72) hide show
  1. package/dist/cli/commands/build.d.ts +10 -0
  2. package/dist/cli/commands/build.js +87 -0
  3. package/dist/cli/commands/build.js.map +1 -0
  4. package/dist/cli/commands/changelog.js +65 -57
  5. package/dist/cli/commands/changelog.js.map +1 -1
  6. package/dist/cli/commands/checks.d.ts +10 -0
  7. package/dist/cli/commands/checks.js +93 -0
  8. package/dist/cli/commands/checks.js.map +1 -0
  9. package/dist/cli/commands/git.d.ts +13 -0
  10. package/dist/cli/commands/git.js +93 -0
  11. package/dist/cli/commands/git.js.map +1 -0
  12. package/dist/cli/commands/pack.d.ts +10 -0
  13. package/dist/cli/commands/pack.js +83 -0
  14. package/dist/cli/commands/pack.js.map +1 -0
  15. package/dist/cli/commands/plan.js +40 -41
  16. package/dist/cli/commands/plan.js.map +1 -1
  17. package/dist/cli/commands/publish.js +225 -194
  18. package/dist/cli/commands/publish.js.map +1 -1
  19. package/dist/cli/commands/report.js +28 -31
  20. package/dist/cli/commands/report.js.map +1 -1
  21. package/dist/cli/commands/rollback.js +0 -3
  22. package/dist/cli/commands/rollback.js.map +1 -1
  23. package/dist/cli/commands/run.js +387 -300
  24. package/dist/cli/commands/run.js.map +1 -1
  25. package/dist/cli/commands/verify.js +29 -28
  26. package/dist/cli/commands/verify.js.map +1 -1
  27. package/dist/cli/commands/version.d.ts +12 -0
  28. package/dist/cli/commands/version.js +111 -0
  29. package/dist/cli/commands/version.js.map +1 -0
  30. package/dist/index.d.ts +6 -5
  31. package/dist/index.js +146 -13
  32. package/dist/index.js.map +1 -1
  33. package/dist/manifest.d.ts +9 -0
  34. package/dist/manifest.js +131 -0
  35. package/dist/manifest.js.map +1 -1
  36. package/dist/rest/handlers/build-handler.js +22 -20
  37. package/dist/rest/handlers/build-handler.js.map +1 -1
  38. package/dist/rest/handlers/changelog-generate-handler.js +75 -88
  39. package/dist/rest/handlers/changelog-generate-handler.js.map +1 -1
  40. package/dist/rest/handlers/changelog-handler.js +1 -4
  41. package/dist/rest/handlers/changelog-handler.js.map +1 -1
  42. package/dist/rest/handlers/changelog-save-handler.js +0 -2
  43. package/dist/rest/handlers/changelog-save-handler.js.map +1 -1
  44. package/dist/rest/handlers/checklist-handler.js +113 -99
  45. package/dist/rest/handlers/checklist-handler.js.map +1 -1
  46. package/dist/rest/handlers/generate-handler.js +0 -3
  47. package/dist/rest/handlers/generate-handler.js.map +1 -1
  48. package/dist/rest/handlers/git-timeline-handler.js.map +1 -1
  49. package/dist/rest/handlers/history-changelog-handler.js +0 -1
  50. package/dist/rest/handlers/history-changelog-handler.js.map +1 -1
  51. package/dist/rest/handlers/history-handler.js +2 -3
  52. package/dist/rest/handlers/history-handler.js.map +1 -1
  53. package/dist/rest/handlers/history-plan-handler.js +0 -1
  54. package/dist/rest/handlers/history-plan-handler.js.map +1 -1
  55. package/dist/rest/handlers/history-report-handler.js +0 -1
  56. package/dist/rest/handlers/history-report-handler.js.map +1 -1
  57. package/dist/rest/handlers/plan-handler.js +0 -3
  58. package/dist/rest/handlers/plan-handler.js.map +1 -1
  59. package/dist/rest/handlers/preview-handler.js +0 -1
  60. package/dist/rest/handlers/preview-handler.js.map +1 -1
  61. package/dist/rest/handlers/report-handler.js +1 -1
  62. package/dist/rest/handlers/report-handler.js.map +1 -1
  63. package/dist/rest/handlers/reset-handler.js +0 -1
  64. package/dist/rest/handlers/reset-handler.js.map +1 -1
  65. package/dist/rest/handlers/run-checks-handler.js +0 -1
  66. package/dist/rest/handlers/run-checks-handler.js.map +1 -1
  67. package/dist/rest/handlers/run-handler.js +72 -52
  68. package/dist/rest/handlers/run-handler.js.map +1 -1
  69. package/dist/rest/handlers/status-handler.js +0 -2
  70. package/dist/rest/handlers/status-handler.js.map +1 -1
  71. package/dist/setup/handler.js.map +1 -1
  72. package/package.json +9 -8
@@ -0,0 +1,83 @@
1
+ import { defineCommand, findRepoRoot, useConfig, useLoader } from '@kb-labs/sdk';
2
+ import { planRelease, verifyPackages } from '@kb-labs/release-manager-core';
3
+
4
+ // src/cli/commands/pack.ts
5
+
6
+ // src/cli/commands/pack.ts
7
+ function buildPackSections(results, symbols) {
8
+ const sections = [];
9
+ const passed = results.filter((r) => r.success);
10
+ const failed = results.filter((r) => !r.success);
11
+ if (passed.length > 0) {
12
+ sections.push({
13
+ header: "Verified",
14
+ items: passed.map((r) => `${symbols.success} ${r.name}`)
15
+ });
16
+ }
17
+ if (failed.length > 0) {
18
+ sections.push({
19
+ header: "Issues found",
20
+ items: failed.flatMap(
21
+ (r) => r.issues.map((issue) => `${symbols.error} ${r.name}: ${issue}`)
22
+ )
23
+ });
24
+ }
25
+ return sections;
26
+ }
27
+ var pack_default = defineCommand({
28
+ id: "release:pack",
29
+ description: "Verify built package artifacts via npm pack (checks exports, test leaks, syntax)",
30
+ handler: {
31
+ async execute(ctx, input) {
32
+ const { flags } = input;
33
+ const cwd = ctx.cwd || process.cwd();
34
+ const repoRoot = await findRepoRoot(cwd);
35
+ const fileConfig = await useConfig();
36
+ const config = fileConfig ?? {};
37
+ const planLoader = useLoader("Discovering packages...");
38
+ planLoader.start();
39
+ const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope });
40
+ planLoader.succeed(`Found ${plan.packages.length} package(s)`);
41
+ if (plan.packages.length === 0) {
42
+ const msg = `No packages found${flags.scope ? ` matching scope: ${flags.scope}` : ""}`;
43
+ if (flags.json) {
44
+ ctx.ui?.json?.({ ok: true, issues: [], results: [], message: msg });
45
+ } else {
46
+ ctx.ui?.write?.(msg);
47
+ }
48
+ console.log("::kb-output::" + JSON.stringify({ ok: true, issues: [] }));
49
+ return { exitCode: 0, ok: true, issues: [], results: [] };
50
+ }
51
+ const verifyLoader = useLoader(`Verifying ${plan.packages.length} package(s)...`);
52
+ verifyLoader.start();
53
+ const results = await verifyPackages(plan.packages, {
54
+ logger: ctx.platform?.logger,
55
+ onProgress: (name, result) => {
56
+ ctx.platform?.logger?.info?.(`Verified ${name}`, { ok: result.success, issues: result.issues.length });
57
+ }
58
+ });
59
+ const ok = results.every((r) => r.success);
60
+ const issues = results.flatMap((r) => r.issues.map((issue) => `${r.name}: ${issue}`));
61
+ if (ok) {
62
+ verifyLoader.succeed(`All ${results.length} package(s) verified`);
63
+ } else {
64
+ verifyLoader.fail(`${results.filter((r) => !r.success).length} package(s) have issues`);
65
+ }
66
+ console.log("::kb-output::" + JSON.stringify({ ok, issues }));
67
+ if (flags.json) {
68
+ ctx.ui?.json?.({ ok, issues, results });
69
+ return { exitCode: ok ? 0 : 1, ok, issues, results };
70
+ }
71
+ ctx.ui.sideBox({
72
+ title: "Pack Verification",
73
+ sections: buildPackSections(results, ctx.ui.symbols),
74
+ status: ok ? "success" : "error"
75
+ });
76
+ return { exitCode: ok ? 0 : 1, ok, issues, results };
77
+ }
78
+ }
79
+ });
80
+
81
+ export { pack_default as default };
82
+ //# sourceMappingURL=pack.js.map
83
+ //# sourceMappingURL=pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/pack.ts"],"names":[],"mappings":"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","file":"pack.js","sourcesContent":["/**\n * Release pack command — verify built artifacts via npm pack.\n * Atomic step: reads plan, runs npm pack checks, emits output marker for workflow.\n */\n\nimport { defineCommand, type CLIInput, type CommandResult, type PluginContextV3, useLoader, useConfig } from '@kb-labs/sdk';\nimport {\n planRelease,\n verifyPackages,\n type ReleaseConfig,\n type VerifyResult,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface PackFlags {\n scope?: string;\n json?: boolean;\n}\n\ntype ReleasePackResult = CommandResult & {\n ok?: boolean;\n issues?: string[];\n results?: VerifyResult[];\n};\n\nfunction buildPackSections(\n results: VerifyResult[],\n symbols: { success: string; error: string; warning: string },\n): Array<{ header?: string; items: string[] }> {\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n const passed = results.filter(r => r.success);\n const failed = results.filter(r => !r.success);\n\n if (passed.length > 0) {\n sections.push({\n header: 'Verified',\n items: passed.map(r => `${symbols.success} ${r.name}`),\n });\n }\n\n if (failed.length > 0) {\n sections.push({\n header: 'Issues found',\n items: failed.flatMap(r =>\n r.issues.map(issue => `${symbols.error} ${r.name}: ${issue}`),\n ),\n });\n }\n\n return sections;\n}\n\nexport default defineCommand({\n id: 'release:pack',\n description: 'Verify built package artifacts via npm pack (checks exports, test leaks, syntax)',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<PackFlags>): Promise<ReleasePackResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = fileConfig ?? {};\n\n const planLoader = useLoader('Discovering packages...');\n planLoader.start();\n const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope });\n planLoader.succeed(`Found ${plan.packages.length} package(s)`);\n\n if (plan.packages.length === 0) {\n const msg = `No packages found${flags.scope ? ` matching scope: ${flags.scope}` : ''}`;\n if (flags.json) { ctx.ui?.json?.({ ok: true, issues: [], results: [], message: msg }); }\n else { ctx.ui?.write?.(msg); }\n console.log('::kb-output::' + JSON.stringify({ ok: true, issues: [] }));\n return { exitCode: 0, ok: true, issues: [], results: [] };\n }\n\n const verifyLoader = useLoader(`Verifying ${plan.packages.length} package(s)...`);\n verifyLoader.start();\n\n const results = await verifyPackages(plan.packages, {\n logger: ctx.platform?.logger,\n onProgress: (name, result) => {\n ctx.platform?.logger?.info?.(`Verified ${name}`, { ok: result.success, issues: result.issues.length });\n },\n });\n\n const ok = results.every(r => r.success);\n const issues = results.flatMap(r => r.issues.map(issue => `${r.name}: ${issue}`));\n\n if (ok) {\n verifyLoader.succeed(`All ${results.length} package(s) verified`);\n } else {\n verifyLoader.fail(`${results.filter(r => !r.success).length} package(s) have issues`);\n }\n\n console.log('::kb-output::' + JSON.stringify({ ok, issues }));\n\n if (flags.json) {\n ctx.ui?.json?.({ ok, issues, results });\n return { exitCode: ok ? 0 : 1, ok, issues, results };\n }\n\n ctx.ui.sideBox({\n title: 'Pack Verification',\n sections: buildPackSections(results, ctx.ui.symbols),\n status: ok ? 'success' : 'error',\n });\n\n return { exitCode: ok ? 0 : 1, ok, issues, results };\n },\n },\n});\n"]}
@@ -1,8 +1,5 @@
1
1
  import { defineCommand, findRepoRoot, useLoader, useConfig, displayArtifacts } from '@kb-labs/sdk';
2
2
  import { planRelease } from '@kb-labs/release-manager-core';
3
- import 'path';
4
- import 'fs/promises';
5
- import 'globby';
6
3
 
7
4
  // src/cli/commands/plan.ts
8
5
  function scopeToDir(scope) {
@@ -10,6 +7,38 @@ function scopeToDir(scope) {
10
7
  }
11
8
 
12
9
  // src/cli/commands/plan.ts
10
+ function formatVersionInfo(pkg) {
11
+ if (pkg.currentVersion && pkg.nextVersion) {
12
+ return `${pkg.currentVersion} \u2192 ${pkg.nextVersion}`;
13
+ }
14
+ return pkg.nextVersion || "new";
15
+ }
16
+ function buildPlanSections(plan, artifacts, symbols) {
17
+ const sections = [];
18
+ sections.push({
19
+ header: "Summary",
20
+ items: [
21
+ `Strategy: ${plan.strategy}`,
22
+ `Registry: ${plan.registry}`,
23
+ `Packages: ${plan.packages.length}`
24
+ ]
25
+ });
26
+ if (plan.packages.length > 0) {
27
+ sections.push({
28
+ header: "Packages to release",
29
+ items: plan.packages.map((pkg) => `${symbols.success} ${pkg.name}: ${formatVersionInfo(pkg)}`)
30
+ });
31
+ } else {
32
+ sections.push({ items: ["No packages to release"] });
33
+ }
34
+ if (artifacts.length > 0) {
35
+ sections.push({
36
+ header: "Artifacts",
37
+ items: displayArtifacts(artifacts, { showSize: true, showTime: true, showDescription: true, maxItems: 10, title: "" })
38
+ });
39
+ }
40
+ return sections;
41
+ }
13
42
  var plan_default = defineCommand({
14
43
  id: "release:plan",
15
44
  description: "Analyze changes and prepare release plan",
@@ -62,49 +91,19 @@ var plan_default = defineCommand({
62
91
  strategy: plan.strategy,
63
92
  registry: plan.registry
64
93
  });
94
+ const firstPkg = plan.packages[0];
95
+ console.log("::kb-output::" + JSON.stringify({
96
+ version: firstPkg?.nextVersion ?? "",
97
+ packages: plan.packages.length,
98
+ bump: firstPkg?.bump ?? "auto",
99
+ planPath
100
+ }));
65
101
  if (flags.json) {
66
102
  ctx.ui?.json?.(plan);
67
103
  } else {
68
- const sections = [];
69
- sections.push({
70
- header: "Summary",
71
- items: [
72
- `Strategy: ${plan.strategy}`,
73
- `Registry: ${plan.registry}`,
74
- `Packages: ${plan.packages.length}`
75
- ]
76
- });
77
- if (plan.packages.length > 0) {
78
- const packageItems = [];
79
- for (const pkg of plan.packages) {
80
- const versionInfo = pkg.currentVersion && pkg.nextVersion ? `${pkg.currentVersion} \u2192 ${pkg.nextVersion}` : pkg.nextVersion || "new";
81
- packageItems.push(`${ctx.ui.symbols.success} ${pkg.name}: ${versionInfo}`);
82
- }
83
- sections.push({
84
- header: "Packages to release",
85
- items: packageItems
86
- });
87
- } else {
88
- sections.push({
89
- items: ["No packages to release"]
90
- });
91
- }
92
- if (artifacts.length > 0) {
93
- const artifactsLines = displayArtifacts(artifacts, {
94
- showSize: true,
95
- showTime: true,
96
- showDescription: true,
97
- maxItems: 10,
98
- title: ""
99
- });
100
- sections.push({
101
- header: "Artifacts",
102
- items: artifactsLines
103
- });
104
- }
105
104
  ctx.ui.sideBox({
106
105
  title: "Release Plan",
107
- sections,
106
+ sections: buildPlanSections(plan, artifacts, ctx.ui.symbols),
108
107
  status: "success"
109
108
  });
110
109
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/cli/commands/plan.ts"],"names":[],"mappings":"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","file":"plan.js","sourcesContent":["import { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport globby from 'globby';\n\nexport { findRepoRoot } from '@kb-labs/sdk';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n\n/**\n * Resolve scope name to absolute filesystem path.\n * Scans all package.json in repoRoot to find the matching package by name.\n */\nexport async function resolveScopePath(repoRoot: string, scope: string): Promise<string> {\n if (scope === 'root') {\n return repoRoot;\n }\n\n if (scope.startsWith('@')) {\n const packageJsonPaths = await globby('**/package.json', {\n cwd: repoRoot,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/.*/**'],\n });\n\n for (const pkgJsonPath of packageJsonPaths) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n if (pkg.name === scope) {\n return join(pkgJsonPath, '..');\n }\n } catch { /* skip */ }\n }\n }\n\n // Direct path or fallback\n return join(repoRoot, scope);\n}\n","/**\n * Release plan command\n */\n\nimport {\n defineCommand,\n type CLIInput,\n type CommandResult,\n type PluginContextV3,\n useLoader,\n displayArtifacts,\n type ArtifactInfo,\n useConfig,\n} from '@kb-labs/sdk';\nimport { planRelease, type VersionBump, type ReleaseConfig } from '@kb-labs/release-manager-core';\nimport { findRepoRoot, scopeToDir } from '../../shared/utils';\n\ninterface PlanFlags {\n scope?: string;\n flow?: string;\n bump?: 'patch' | 'minor' | 'major' | 'auto';\n strict?: boolean;\n json?: boolean;\n}\n\ntype ReleasePlanResult = CommandResult & {\n plan?: {\n strategy: string;\n registry: string;\n packages: Array<{\n name: string;\n currentVersion?: string;\n nextVersion?: string;\n }>;\n };\n};\n\nexport default defineCommand({\n id: 'release:plan',\n description: 'Analyze changes and prepare release plan',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<PlanFlags>): Promise<ReleasePlanResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n // Load configuration\n const configLoader = useLoader('Loading release configuration...');\n configLoader.start();\n\n const fileConfig = await useConfig<ReleaseConfig>();\n\n // Merge CLI overrides\n const config: ReleaseConfig = {\n ...fileConfig,\n ...(flags.bump && { bump: flags.bump }),\n ...(flags.strict !== undefined && { strict: flags.strict }),\n };\n\n configLoader.succeed('Configuration loaded');\n\n // Create release plan\n const planLoader = useLoader('Discovering packages and planning release...');\n planLoader.start();\n\n const plan = await planRelease({\n cwd: repoRoot,\n config,\n scope: flags.scope,\n flow: flags.flow,\n bumpOverride: flags.bump as VersionBump | undefined,\n });\n\n if (plan.packages.length === 0) {\n planLoader.fail(`No packages found matching scope: ${flags.scope || 'all'}`);\n } else {\n planLoader.succeed(`Found ${plan.packages.length} package(s) to release`);\n }\n\n // Save plan to .kb/release/plans/{scope}/current/plan.json\n const scopeDir = scopeToDir(flags.scope ?? 'root');\n const planDir = ctx.runtime.fs.join(repoRoot, '.kb', 'release', 'plans', scopeDir, 'current');\n const planPath = ctx.runtime.fs.join(planDir, 'plan.json');\n const artifacts: ArtifactInfo[] = [];\n\n if (!flags.json) {\n await ctx.runtime.fs.mkdir(planDir, { recursive: true });\n await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: 'utf-8' });\n\n const stats = await ctx.runtime.fs.stat(planPath);\n artifacts.push({\n name: 'Release Plan',\n path: planPath,\n size: stats.size,\n modified: new Date(stats.mtime),\n description: 'Detailed release plan (JSON)',\n });\n }\n\n ctx.platform?.logger?.info?.('Release plan completed', {\n packagesCount: plan.packages.length,\n strategy: plan.strategy,\n registry: plan.registry,\n });\n\n if (flags.json) {\n ctx.ui?.json?.(plan);\n } else {\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n // Summary\n sections.push({\n header: 'Summary',\n items: [\n `Strategy: ${plan.strategy}`,\n `Registry: ${plan.registry}`,\n `Packages: ${plan.packages.length}`,\n ],\n });\n\n // Packages section\n if (plan.packages.length > 0) {\n const packageItems: string[] = [];\n for (const pkg of plan.packages) {\n const versionInfo =\n pkg.currentVersion && pkg.nextVersion\n ? `${pkg.currentVersion} → ${pkg.nextVersion}`\n : pkg.nextVersion || 'new';\n packageItems.push(`${ctx.ui.symbols.success} ${pkg.name}: ${versionInfo}`);\n }\n sections.push({\n header: 'Packages to release',\n items: packageItems,\n });\n } else {\n sections.push({\n items: ['No packages to release'],\n });\n }\n\n // Artifacts section\n if (artifacts.length > 0) {\n const artifactsLines = displayArtifacts(artifacts, {\n showSize: true,\n showTime: true,\n showDescription: true,\n maxItems: 10,\n title: '',\n });\n sections.push({\n header: 'Artifacts',\n items: artifactsLines,\n });\n }\n\n ctx.ui.sideBox({\n title: 'Release Plan',\n sections,\n status: 'success',\n });\n }\n\n return { exitCode: 0, plan };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/cli/commands/plan.ts"],"names":[],"mappings":"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","file":"plan.js","sourcesContent":["export { findRepoRoot } from '@kb-labs/sdk';\nexport { resolveScopePath } from './resolve-scope';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n","/**\n * Release plan command\n */\n\nimport {\n defineCommand,\n type CLIInput,\n type CommandResult,\n type PluginContextV3,\n useLoader,\n displayArtifacts,\n type ArtifactInfo,\n useConfig,\n} from '@kb-labs/sdk';\nimport { planRelease, type VersionBump, type ReleaseConfig } from '@kb-labs/release-manager-core';\nimport { findRepoRoot, scopeToDir } from '../../shared/utils';\n\ninterface PlanFlags {\n scope?: string;\n flow?: string;\n bump?: 'patch' | 'minor' | 'major' | 'auto';\n strict?: boolean;\n json?: boolean;\n}\n\ntype ReleasePlanResult = CommandResult & {\n plan?: {\n strategy: string;\n registry: string;\n packages: Array<{\n name: string;\n currentVersion?: string;\n nextVersion?: string;\n }>;\n };\n};\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nfunction formatVersionInfo(pkg: { currentVersion?: string; nextVersion?: string }): string {\n if (pkg.currentVersion && pkg.nextVersion) { return `${pkg.currentVersion} → ${pkg.nextVersion}`; }\n return pkg.nextVersion || 'new';\n}\n\nfunction buildPlanSections(\n plan: { strategy: string; registry: string; packages: Array<{ name: string; currentVersion?: string; nextVersion?: string }> },\n artifacts: ArtifactInfo[],\n symbols: { success: string },\n): Array<{ header?: string; items: string[] }> {\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n sections.push({\n header: 'Summary',\n items: [\n `Strategy: ${plan.strategy}`,\n `Registry: ${plan.registry}`,\n `Packages: ${plan.packages.length}`,\n ],\n });\n\n if (plan.packages.length > 0) {\n sections.push({\n header: 'Packages to release',\n items: plan.packages.map(pkg => `${symbols.success} ${pkg.name}: ${formatVersionInfo(pkg)}`),\n });\n } else {\n sections.push({ items: ['No packages to release'] });\n }\n\n if (artifacts.length > 0) {\n sections.push({\n header: 'Artifacts',\n items: displayArtifacts(artifacts, { showSize: true, showTime: true, showDescription: true, maxItems: 10, title: '' }),\n });\n }\n\n return sections;\n}\n\n// ── command ────────────────────────────────────────────────────────────────\n\nexport default defineCommand({\n id: 'release:plan',\n description: 'Analyze changes and prepare release plan',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<PlanFlags>): Promise<ReleasePlanResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const configLoader = useLoader('Loading release configuration...');\n configLoader.start();\n\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = {\n ...fileConfig,\n ...(flags.bump && { bump: flags.bump }),\n ...(flags.strict !== undefined && { strict: flags.strict }),\n };\n configLoader.succeed('Configuration loaded');\n\n const planLoader = useLoader('Discovering packages and planning release...');\n planLoader.start();\n\n const plan = await planRelease({\n cwd: repoRoot,\n config,\n scope: flags.scope,\n flow: flags.flow,\n bumpOverride: flags.bump as VersionBump | undefined,\n });\n\n if (plan.packages.length === 0) {\n planLoader.fail(`No packages found matching scope: ${flags.scope || 'all'}`);\n } else {\n planLoader.succeed(`Found ${plan.packages.length} package(s) to release`);\n }\n\n const scopeDir = scopeToDir(flags.scope ?? 'root');\n const planDir = ctx.runtime.fs.join(repoRoot, '.kb', 'release', 'plans', scopeDir, 'current');\n const planPath = ctx.runtime.fs.join(planDir, 'plan.json');\n const artifacts: ArtifactInfo[] = [];\n\n if (!flags.json) {\n await ctx.runtime.fs.mkdir(planDir, { recursive: true });\n await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: 'utf-8' });\n const stats = await ctx.runtime.fs.stat(planPath);\n artifacts.push({\n name: 'Release Plan',\n path: planPath,\n size: stats.size,\n modified: new Date(stats.mtime),\n description: 'Detailed release plan (JSON)',\n });\n }\n\n ctx.platform?.logger?.info?.('Release plan completed', {\n packagesCount: plan.packages.length,\n strategy: plan.strategy,\n registry: plan.registry,\n });\n\n const firstPkg = plan.packages[0];\n console.log('::kb-output::' + JSON.stringify({\n version: firstPkg?.nextVersion ?? '',\n packages: plan.packages.length,\n bump: firstPkg?.bump ?? 'auto',\n planPath,\n }));\n\n if (flags.json) {\n ctx.ui?.json?.(plan);\n } else {\n ctx.ui.sideBox({\n title: 'Release Plan',\n sections: buildPlanSections(plan, artifacts, ctx.ui.symbols),\n status: 'success',\n });\n }\n\n return { exitCode: 0, plan };\n },\n },\n});\n"]}