@kb-labs/release-manager-cli 2.116.14 → 2.118.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.
@@ -62,7 +62,19 @@ var build_default = defineCommand({
62
62
  const startedAt = Date.now();
63
63
  const execResult = await ctx.api.shell.exec("pnpm", ["run", buildScript], {
64
64
  cwd: repoRoot,
65
- timeout: 20 * 60 * 1e3
65
+ timeout: 60 * 60 * 1e3,
66
+ // Studio (Module Federation) rspack configs gate dts type
67
+ // generation on NODE_ENV !== 'production' (see
68
+ // createStudioRemoteConfig in studio/plugin-tools) — a dev-only
69
+ // convenience so the Studio host can hot-pick-up types, of no
70
+ // value to a release build that only needs compiled JS. Its
71
+ // background TS worker is a reproducible source of indefinite
72
+ // native-threadpool hangs under concurrent rspack invocations
73
+ // (observed: multiple `rspack build --config
74
+ // rspack.studio.config.mjs` processes stuck in __psynch_cvwait
75
+ // for hours). Release builds never need dts — skip the whole
76
+ // risky code path instead of chasing the underlying race.
77
+ env: { NODE_ENV: "production" }
66
78
  });
67
79
  return [{
68
80
  name: `pnpm run ${buildScript}`,
@@ -72,6 +84,7 @@ var build_default = defineCommand({
72
84
  }];
73
85
  })() : await buildPackages(plan.packages, {
74
86
  logger: ctx.platform?.logger,
87
+ shell: ctx.api.shell,
75
88
  onProgress: (name, result) => {
76
89
  ctx.platform?.logger?.info?.(`Built ${name}`, { ok: result.success, ms: result.durationMs });
77
90
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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","file":"build.js","sourcesContent":["/**\n * Release build command — build packages in plan using safe build strategy.\n * Atomic step: reads plan, builds, 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 buildPackages,\n mergeConfigWithFlow,\n type ReleaseConfig,\n type BuildResult,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface BuildFlags {\n scope?: string;\n flow?: string;\n json?: boolean;\n}\n\ntype ReleaseBuildResult = CommandResult<unknown>;\n\nfunction buildSections(\n results: BuildResult[],\n symbols: { success: string; error: 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: 'Built',\n items: passed.map(r => `${symbols.success} ${r.name}${r.durationMs ? ` (${r.durationMs}ms)` : ''}`),\n });\n }\n\n if (failed.length > 0) {\n sections.push({\n header: 'Failed',\n items: failed.flatMap(r => {\n const lines = [`${symbols.error} ${r.name}`];\n if (r.error) { lines.push(` ${r.error.slice(0, 200)}`); }\n return lines;\n }),\n });\n }\n\n return sections;\n}\n\nexport default defineCommand({\n id: 'release:build',\n description: 'Build packages from release plan using safe build strategy',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<BuildFlags>): Promise<ReleaseBuildResult> {\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, flow: flags.flow });\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, failed: [], results: [], message: msg }); }\n else { ctx.ui?.write?.(msg); }\n console.log('::kb-output::' + JSON.stringify({ ok: true, failed: [] }));\n return { ok: true, result: { ok: true, failed: [], results: [] } };\n }\n\n const effectiveConfig = flags.flow ? mergeConfigWithFlow(config, flags.flow) : config;\n const buildScript = effectiveConfig.build?.script;\n\n const buildLoader = useLoader(\n buildScript\n ? `Running \"pnpm run ${buildScript}\"...`\n : `Building ${plan.packages.length} package(s)...`,\n );\n buildLoader.start();\n\n const results: BuildResult[] = buildScript\n ? await (async () => {\n const startedAt = Date.now();\n const execResult = await ctx.api.shell.exec('pnpm', ['run', buildScript], {\n cwd: repoRoot,\n timeout: 20 * 60 * 1000,\n });\n return [{\n name: `pnpm run ${buildScript}`,\n success: execResult.ok,\n durationMs: Date.now() - startedAt,\n error: execResult.ok ? undefined : (execResult.stderr || execResult.stdout).trim().split('\\n').slice(-30).join('\\n'),\n }];\n })()\n : await buildPackages(plan.packages, {\n logger: ctx.platform?.logger,\n onProgress: (name, result) => {\n ctx.platform?.logger?.info?.(`Built ${name}`, { ok: result.success, ms: result.durationMs });\n },\n });\n\n const ok = results.every(r => r.success);\n const failed = results.filter(r => !r.success).map(r => r.name);\n\n if (ok) {\n buildLoader.succeed(`Built ${results.length} package(s)`);\n } else {\n buildLoader.fail(`${failed.length} package(s) failed to build`);\n }\n\n console.log('::kb-output::' + JSON.stringify({ ok, failed }));\n\n if (flags.json) {\n ctx.ui?.json?.({ ok, failed, results });\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Build Results',\n sections: buildSections(results, ctx.ui.symbols),\n status: ok ? 'success' : 'error',\n });\n\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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","file":"build.js","sourcesContent":["/**\n * Release build command — build packages in plan using safe build strategy.\n * Atomic step: reads plan, builds, 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 buildPackages,\n mergeConfigWithFlow,\n type ReleaseConfig,\n type BuildResult,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface BuildFlags {\n scope?: string;\n flow?: string;\n json?: boolean;\n}\n\ntype ReleaseBuildResult = CommandResult<unknown>;\n\nfunction buildSections(\n results: BuildResult[],\n symbols: { success: string; error: 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: 'Built',\n items: passed.map(r => `${symbols.success} ${r.name}${r.durationMs ? ` (${r.durationMs}ms)` : ''}`),\n });\n }\n\n if (failed.length > 0) {\n sections.push({\n header: 'Failed',\n items: failed.flatMap(r => {\n const lines = [`${symbols.error} ${r.name}`];\n if (r.error) { lines.push(` ${r.error.slice(0, 200)}`); }\n return lines;\n }),\n });\n }\n\n return sections;\n}\n\nexport default defineCommand({\n id: 'release:build',\n description: 'Build packages from release plan using safe build strategy',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<BuildFlags>): Promise<ReleaseBuildResult> {\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, flow: flags.flow });\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, failed: [], results: [], message: msg }); }\n else { ctx.ui?.write?.(msg); }\n console.log('::kb-output::' + JSON.stringify({ ok: true, failed: [] }));\n return { ok: true, result: { ok: true, failed: [], results: [] } };\n }\n\n const effectiveConfig = flags.flow ? mergeConfigWithFlow(config, flags.flow) : config;\n const buildScript = effectiveConfig.build?.script;\n\n const buildLoader = useLoader(\n buildScript\n ? `Running \"pnpm run ${buildScript}\"...`\n : `Building ${plan.packages.length} package(s)...`,\n );\n buildLoader.start();\n\n const results: BuildResult[] = buildScript\n ? await (async () => {\n const startedAt = Date.now();\n const execResult = await ctx.api.shell.exec('pnpm', ['run', buildScript], {\n cwd: repoRoot,\n timeout: 60 * 60 * 1000,\n // Studio (Module Federation) rspack configs gate dts type\n // generation on NODE_ENV !== 'production' (see\n // createStudioRemoteConfig in studio/plugin-tools) — a dev-only\n // convenience so the Studio host can hot-pick-up types, of no\n // value to a release build that only needs compiled JS. Its\n // background TS worker is a reproducible source of indefinite\n // native-threadpool hangs under concurrent rspack invocations\n // (observed: multiple `rspack build --config\n // rspack.studio.config.mjs` processes stuck in __psynch_cvwait\n // for hours). Release builds never need dts — skip the whole\n // risky code path instead of chasing the underlying race.\n env: { NODE_ENV: 'production' },\n });\n return [{\n name: `pnpm run ${buildScript}`,\n success: execResult.ok,\n durationMs: Date.now() - startedAt,\n error: execResult.ok ? undefined : (execResult.stderr || execResult.stdout).trim().split('\\n').slice(-30).join('\\n'),\n }];\n })()\n : await buildPackages(plan.packages, {\n logger: ctx.platform?.logger,\n shell: ctx.api.shell,\n onProgress: (name, result) => {\n ctx.platform?.logger?.info?.(`Built ${name}`, { ok: result.success, ms: result.durationMs });\n },\n });\n\n const ok = results.every(r => r.success);\n const failed = results.filter(r => !r.success).map(r => r.name);\n\n if (ok) {\n buildLoader.succeed(`Built ${results.length} package(s)`);\n } else {\n buildLoader.fail(`${failed.length} package(s) failed to build`);\n }\n\n console.log('::kb-output::' + JSON.stringify({ ok, failed }));\n\n if (flags.json) {\n ctx.ui?.json?.({ ok, failed, results });\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Build Results',\n sections: buildSections(results, ctx.ui.symbols),\n status: ok ? 'success' : 'error',\n });\n\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n },\n },\n});\n"]}
@@ -41,7 +41,7 @@ var checks_default = defineCommand({
41
41
  const repoRoot = await findRepoRoot(cwd);
42
42
  const fileConfig = await useConfig();
43
43
  const config = fileConfig ?? {};
44
- const checks = config.checks ?? [];
44
+ const checks = flags.flow ? config.flows?.[flags.flow]?.checks ?? config.checks ?? [] : config.checks ?? [];
45
45
  if (checks.length === 0) {
46
46
  const msg = "No checks configured in release config";
47
47
  if (flags.json) {
@@ -64,9 +64,10 @@ var checks_default = defineCommand({
64
64
  repoRoot,
65
65
  packagePaths,
66
66
  scopePath,
67
- logger: ctx.platform?.logger
67
+ logger: ctx.platform?.logger,
68
+ shell: ctx.api.shell
68
69
  });
69
- const ok = results.every((r) => r.ok);
70
+ const ok = results.every((r) => r.ok || r.optional);
70
71
  const failed = results.filter((r) => !r.ok).map((r) => r.id);
71
72
  if (ok) {
72
73
  checksLoader.succeed(`All ${results.length} check(s) passed`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/checks.ts"],"names":[],"mappings":"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","file":"checks.js","sourcesContent":["/**\n * Release checks command — run pre-release checks from config.\n * Atomic step: reads plan, runs 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 runReleaseChecks,\n resolveScopePath,\n type ReleaseConfig,\n type CheckResult,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface ChecksFlags {\n scope?: string;\n flow?: string;\n json?: boolean;\n}\n\ntype ReleaseChecksResult = CommandResult<unknown>;\n\nfunction buildChecksSections(\n results: CheckResult[],\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.ok);\n const failed = results.filter(r => !r.ok);\n\n if (passed.length > 0) {\n sections.push({\n header: 'Passed',\n items: passed.map(r => `${symbols.success} ${r.id}${r.timingMs ? ` (${r.timingMs}ms)` : ''}`),\n });\n }\n\n if (failed.length > 0) {\n sections.push({\n header: 'Failed',\n items: failed.flatMap(r => {\n const lines = [`${symbols.error} ${r.id}`];\n if (r.details?.stderr) { lines.push(` ${r.details.stderr.slice(0, 120)}`); }\n if (r.hint) { lines.push(` Hint: ${r.hint}`); }\n return lines;\n }),\n });\n }\n\n return sections;\n}\n\nexport default defineCommand({\n id: 'release:checks',\n description: 'Run pre-release checks from release config',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<ChecksFlags>): Promise<ReleaseChecksResult> {\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 const checks = config.checks ?? [];\n\n if (checks.length === 0) {\n const msg = 'No checks configured in release config';\n if (flags.json) {\n ctx.ui?.json?.({ ok: true, failed: [], results: [], message: msg });\n } else {\n ctx.ui?.write?.(msg);\n }\n console.log('::kb-output::' + JSON.stringify({ ok: true, failed: [] }));\n return { ok: true, result: { ok: true, failed: [], results: [] } };\n }\n\n const planLoader = useLoader('Discovering packages...');\n planLoader.start();\n const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope, flow: flags.flow });\n planLoader.succeed(`Found ${plan.packages.length} package(s)`);\n\n const scopePath = await resolveScopePath(repoRoot, flags.scope ?? 'root');\n const packagePaths = plan.packages.map(p => p.path);\n\n const checksLoader = useLoader(`Running ${checks.length} check(s)...`);\n checksLoader.start();\n\n const results = await runReleaseChecks(checks, {\n repoRoot,\n packagePaths,\n scopePath,\n logger: ctx.platform?.logger,\n });\n\n const ok = results.every(r => r.ok);\n const failed = results.filter(r => !r.ok).map(r => r.id);\n\n if (ok) {\n checksLoader.succeed(`All ${results.length} check(s) passed`);\n } else {\n checksLoader.fail(`${failed.length} check(s) failed`);\n }\n\n console.log('::kb-output::' + JSON.stringify({ ok, failed }));\n\n if (flags.json) {\n ctx.ui?.json?.({ ok, failed, results });\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Pre-release Checks',\n sections: buildChecksSections(results, ctx.ui.symbols),\n status: ok ? 'success' : 'error',\n });\n\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/checks.ts"],"names":[],"mappings":"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","file":"checks.js","sourcesContent":["/**\n * Release checks command — run pre-release checks from config.\n * Atomic step: reads plan, runs 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 runReleaseChecks,\n resolveScopePath,\n type ReleaseConfig,\n type CheckResult,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface ChecksFlags {\n scope?: string;\n flow?: string;\n json?: boolean;\n}\n\ntype ReleaseChecksResult = CommandResult<unknown>;\n\nfunction buildChecksSections(\n results: CheckResult[],\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.ok);\n const failed = results.filter(r => !r.ok);\n\n if (passed.length > 0) {\n sections.push({\n header: 'Passed',\n items: passed.map(r => `${symbols.success} ${r.id}${r.timingMs ? ` (${r.timingMs}ms)` : ''}`),\n });\n }\n\n if (failed.length > 0) {\n sections.push({\n header: 'Failed',\n items: failed.flatMap(r => {\n const lines = [`${symbols.error} ${r.id}`];\n if (r.details?.stderr) { lines.push(` ${r.details.stderr.slice(0, 120)}`); }\n if (r.hint) { lines.push(` Hint: ${r.hint}`); }\n return lines;\n }),\n });\n }\n\n return sections;\n}\n\nexport default defineCommand({\n id: 'release:checks',\n description: 'Run pre-release checks from release config',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<ChecksFlags>): Promise<ReleaseChecksResult> {\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 // A flow owns its release checks. Falling back to the global checks is\n // important for callers without --flow, but using the global list when\n // a flow was explicitly requested runs unrelated checks (for example\n // the platform flow would also run the root typecheck/test suite).\n const checks = flags.flow\n ? (config.flows?.[flags.flow]?.checks ?? config.checks ?? [])\n : (config.checks ?? []);\n\n if (checks.length === 0) {\n const msg = 'No checks configured in release config';\n if (flags.json) {\n ctx.ui?.json?.({ ok: true, failed: [], results: [], message: msg });\n } else {\n ctx.ui?.write?.(msg);\n }\n console.log('::kb-output::' + JSON.stringify({ ok: true, failed: [] }));\n return { ok: true, result: { ok: true, failed: [], results: [] } };\n }\n\n const planLoader = useLoader('Discovering packages...');\n planLoader.start();\n const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope, flow: flags.flow });\n planLoader.succeed(`Found ${plan.packages.length} package(s)`);\n\n const scopePath = await resolveScopePath(repoRoot, flags.scope ?? 'root');\n const packagePaths = plan.packages.map(p => p.path);\n\n const checksLoader = useLoader(`Running ${checks.length} check(s)...`);\n checksLoader.start();\n\n const results = await runReleaseChecks(checks, {\n repoRoot,\n packagePaths,\n scopePath,\n logger: ctx.platform?.logger,\n shell: ctx.api.shell,\n });\n\n // A failed optional check is reported (still listed in `failed`) but must not fail the run.\n const ok = results.every(r => r.ok || r.optional);\n const failed = results.filter(r => !r.ok).map(r => r.id);\n\n if (ok) {\n checksLoader.succeed(`All ${results.length} check(s) passed`);\n } else {\n checksLoader.fail(`${failed.length} check(s) failed`);\n }\n\n console.log('::kb-output::' + JSON.stringify({ ok, failed }));\n\n if (flags.json) {\n ctx.ui?.json?.({ ok, failed, results });\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Pre-release Checks',\n sections: buildChecksSections(results, ctx.ui.symbols),\n status: ok ? 'success' : 'error',\n });\n\n return ok ? { ok: true, result: { ok, failed, results } } : { ok: false, error: 'Command failed', result: { ok, failed, results } };\n },\n },\n});\n"]}
@@ -1,7 +1,68 @@
1
1
  import { defineCommand, findRepoRoot, useConfig, useLoader } from '@kb-labs/sdk';
2
- import { planRelease, resolveScopePath, commitAndTagRelease } from '@kb-labs/release-manager-core';
2
+ import { resolveScopePath, commitAndTagRelease, planRelease } from '@kb-labs/release-manager-core';
3
+ import { join } from 'path';
4
+ import { readFile } from 'fs/promises';
3
5
 
4
6
  // src/cli/commands/git.ts
7
+ function scopeToDir(scope) {
8
+ return scope.replace(/^@/, "").replace(/\//g, "-").replace(/:/g, "-").replace(/\*/g, "");
9
+ }
10
+ function releasePlanPath(repoRoot, scope) {
11
+ return join(repoRoot, ".kb", "release", "plans", scopeToDir(scope ?? "root"), "current", "plan.json");
12
+ }
13
+ async function readDiskVersion(packagePath) {
14
+ try {
15
+ const raw = await readFile(join(packagePath, "package.json"), "utf-8");
16
+ return JSON.parse(raw).version;
17
+ } catch {
18
+ return void 0;
19
+ }
20
+ }
21
+ async function validateAgainstDisk(plan, stage) {
22
+ const expectedField = "nextVersion";
23
+ for (const pkg of plan.packages) {
24
+ const onDisk = await readDiskVersion(pkg.path);
25
+ if (onDisk === void 0) {
26
+ return `${pkg.name}: package.json not readable at ${pkg.path}`;
27
+ }
28
+ const expected = pkg[expectedField];
29
+ if (onDisk !== expected) {
30
+ return `${pkg.name}: expected ${expectedField} ${expected} on disk, found ${onDisk}`;
31
+ }
32
+ }
33
+ return void 0;
34
+ }
35
+ async function resolvePlan(options) {
36
+ const { repoRoot, config, scope, flow, bumpOverride, channel} = options;
37
+ const computeFresh = async (reason) => ({
38
+ plan: await planRelease({ cwd: repoRoot, config, scope, flow, bumpOverride, channel }),
39
+ source: "computed",
40
+ ...reason ? { reason } : {}
41
+ });
42
+ let persisted;
43
+ try {
44
+ persisted = JSON.parse(await readFile(releasePlanPath(repoRoot, scope), "utf-8"));
45
+ } catch {
46
+ return computeFresh();
47
+ }
48
+ if (!Array.isArray(persisted.packages) || persisted.packages.length === 0) {
49
+ return computeFresh("persisted plan has no packages");
50
+ }
51
+ if ((persisted.flow ?? void 0) !== (flow ?? void 0)) {
52
+ return computeFresh(`persisted plan is for flow "${persisted.flow ?? "<none>"}", requested "${flow ?? "<none>"}"`);
53
+ }
54
+ if ((persisted.scope ?? void 0) !== (scope ?? void 0)) {
55
+ return computeFresh(`persisted plan is for scope "${persisted.scope ?? "<none>"}", requested "${scope ?? "<none>"}"`);
56
+ }
57
+ if (channel !== void 0 && persisted.channel !== channel) {
58
+ return computeFresh(`persisted plan is for channel "${persisted.channel}", requested "${channel}"`);
59
+ }
60
+ const mismatch = await validateAgainstDisk(persisted);
61
+ if (mismatch) {
62
+ return computeFresh(`persisted plan does not match working tree (${mismatch})`);
63
+ }
64
+ return { plan: persisted, source: "artifact" };
65
+ }
5
66
 
6
67
  // src/cli/commands/git.ts
7
68
  function buildGitSections(result, dryRun, symbols) {
@@ -58,14 +119,16 @@ var git_default = defineCommand({
58
119
  };
59
120
  const planLoader = useLoader("Loading release plan...");
60
121
  planLoader.start();
61
- const plan = await planRelease({
62
- cwd: repoRoot,
122
+ const { plan, source, reason } = await resolvePlan({
123
+ repoRoot,
63
124
  config,
64
125
  scope: flags.scope,
65
126
  flow: flags.flow,
66
- bumpOverride: flags.bump
67
- });
68
- planLoader.succeed(`Loaded plan: ${plan.packages.length} package(s)`);
127
+ bumpOverride: flags.bump});
128
+ ctx.platform?.logger?.debug?.("Release plan resolved", { source, reason });
129
+ planLoader.succeed(
130
+ `${source === "artifact" ? "Loaded plan" : "Recomputed plan"}: ${plan.packages.length} package(s)`
131
+ );
69
132
  if (plan.packages.length === 0) {
70
133
  const msg = `No packages found${flags.scope ? ` matching scope: ${flags.scope}` : ""}`;
71
134
  if (flags.json) {
@@ -84,6 +147,11 @@ var git_default = defineCommand({
84
147
  plan,
85
148
  dryRun: false,
86
149
  noVerify,
150
+ // Without repoRoot the consolidated root changelog is never staged
151
+ // (see the `root === repoRoot` branch in publisher.ts) — it stays
152
+ // dirty in the working tree after every release.
153
+ repoRoot,
154
+ changelogOutputPath: config.changelog?.outputPath,
87
155
  flowName: flags.flow,
88
156
  tagPattern: flags.flow ? config.flows?.[flags.flow]?.tagPattern : void 0
89
157
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/git.ts"],"names":[],"mappings":"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","file":"git.js","sourcesContent":["/**\n * Release git command — commit, tag, and push release changes.\n * Atomic step: reads plan, runs git ops, 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 commitAndTagRelease,\n resolveScopePath,\n type ReleaseConfig,\n type VersionBump,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface GitFlags {\n scope?: string;\n flow?: string;\n bump?: 'patch' | 'minor' | 'major' | 'auto';\n 'dry-run'?: boolean;\n 'no-verify'?: boolean;\n json?: boolean;\n}\n\ntype ReleaseGitResult = CommandResult<unknown>;\n\nfunction buildGitSections(\n result: { committed: boolean; tagged: string[]; pushed: boolean },\n dryRun: boolean,\n symbols: { success: string; warning: string },\n): Array<{ header?: string; items: string[] }> {\n if (dryRun) {\n return [{ items: [`${symbols.warning} Dry-run: no git operations performed`] }];\n }\n\n return [\n {\n header: 'Git Operations',\n items: [\n `${result.committed ? symbols.success : symbols.warning} Commit: ${result.committed ? 'created' : 'skipped'}`,\n `${result.tagged.length > 0 ? symbols.success : symbols.warning} Tags: ${result.tagged.length > 0 ? result.tagged.join(', ') : 'none'}`,\n `${result.pushed ? symbols.success : symbols.warning} Push: ${result.pushed ? 'done' : 'skipped'}`,\n ],\n },\n ];\n}\n\nexport default defineCommand({\n id: 'release:git',\n description: 'Commit, tag, and push release changes',\n\n handler: {\n async intent(ctx: PluginContextV3, input: CLIInput<GitFlags>) {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = { ...fileConfig, ...(flags.bump && { bump: flags.bump }) };\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 return {\n summary: `Commit, tag, and push release for ${plan.packages.length} package(s)`,\n operations: [\n { type: 'create' as const, resource: 'git-commit', details: { packages: plan.packages.length } },\n ...plan.packages.map(p => ({\n type: 'create' as const,\n resource: 'git-tag',\n details: { tag: `${p.name}@${p.nextVersion ?? 'unknown'}` },\n })),\n { type: 'create' as const, resource: 'git-push', details: { scope: flags.scope ?? 'root' } },\n ],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<GitFlags>): Promise<ReleaseGitResult> {\n const { flags } = input;\n const noVerify = flags['no-verify'] ?? false;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = {\n ...fileConfig,\n ...(flags.bump && { bump: flags.bump }),\n };\n\n const planLoader = useLoader('Loading release plan...');\n planLoader.start();\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 planLoader.succeed(`Loaded plan: ${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?.({ committed: false, tagged: [], pushed: false, message: msg }); }\n else { ctx.ui?.write?.(msg); }\n console.log('::kb-output::' + JSON.stringify({ committed: false, tagged: [], pushed: false }));\n return { ok: true, result: { committed: false, tagged: [], pushed: false } };\n }\n\n const scopePath = await resolveScopePath(repoRoot, flags.scope ?? 'root');\n\n const gitLoader = useLoader('Committing, tagging, pushing...');\n gitLoader.start();\n\n const result = await commitAndTagRelease({\n cwd: scopePath,\n plan,\n dryRun: false,\n noVerify,\n flowName: flags.flow,\n tagPattern: flags.flow ? config.flows?.[flags.flow]?.tagPattern : undefined,\n });\n\n if (result.pushed) {\n gitLoader.succeed(`Committed, tagged (${result.tagged.length}), pushed`);\n } else {\n gitLoader.succeed(`Committed, tagged (${result.tagged.length})`);\n }\n\n console.log('::kb-output::' + JSON.stringify({\n committed: result.committed,\n tagged: result.tagged,\n pushed: result.pushed,\n }));\n\n if (flags.json) {\n ctx.ui?.json?.(result);\n return { ok: true, result };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Git Operations',\n sections: buildGitSections(result, false, ctx.ui.symbols),\n status: 'success',\n });\n\n return { ok: true, result };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/shared/resolve-plan.ts","../../../src/cli/commands/git.ts"],"names":["planRelease"],"mappings":"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","file":"git.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 * Plan resolution shared by the atomic release steps that must act on the\n * SAME plan (`release:version` → `release:git`).\n *\n * Why this exists: each step used to call planRelease() independently and\n * hope the results matched. They don't have to — planning is a function of\n * disk state, and the step in between mutates exactly that state. A plan\n * re-derived after `release:version` sees the bumped versions as the new\n * baseline and bumps again, so the tag/commit message end up one version\n * ahead of the package.json files actually being committed.\n *\n * The plan written by `release:plan` is the single source of truth for a\n * pipeline run. It is only reused when it provably describes the current\n * state of the working tree, so a stale artifact (plan.json is committed to\n * the repo, so one is always present) can never be adopted silently.\n */\n\nimport { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport {\n planRelease,\n type ReleasePlan,\n type ReleaseConfig,\n type VersionBump,\n type ReleaseChannel,\n} from '@kb-labs/release-manager-core';\nimport { scopeToDir } from './utils';\n\n/**\n * Which side of the version bump the caller sits on — determines which field\n * of the plan the on-disk package.json versions are expected to match.\n */\nexport type PlanStage =\n /** `release:version`: bump not applied yet, disk should still be at currentVersion. */\n | 'pre-bump'\n /** `release:git`: bump already applied, disk should be at nextVersion. */\n | 'post-bump';\n\nexport interface ResolvePlanOptions {\n repoRoot: string;\n config: ReleaseConfig;\n scope?: string;\n flow?: string;\n bumpOverride?: VersionBump;\n channel?: ReleaseChannel;\n stage: PlanStage;\n}\n\nexport interface ResolvedPlan {\n plan: ReleasePlan;\n /** 'artifact' — reused the plan from `release:plan`; 'computed' — planned fresh. */\n source: 'artifact' | 'computed';\n /** Why the artifact was rejected, when source is 'computed' and one existed. */\n reason?: string;\n}\n\nexport function releasePlanPath(repoRoot: string, scope?: string): string {\n return join(repoRoot, '.kb', 'release', 'plans', scopeToDir(scope ?? 'root'), 'current', 'plan.json');\n}\n\nasync function readDiskVersion(packagePath: string): Promise<string | undefined> {\n try {\n const raw = await readFile(join(packagePath, 'package.json'), 'utf-8');\n return (JSON.parse(raw) as { version?: string }).version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Reject the persisted plan unless every package it covers is on disk at the\n * version this stage expects. That single check subsumes staleness, partial\n * runs, and out-of-band edits: any of them show up as a version mismatch.\n */\nasync function validateAgainstDisk(plan: ReleasePlan, stage: PlanStage): Promise<string | undefined> {\n const expectedField = stage === 'pre-bump' ? 'currentVersion' : 'nextVersion';\n\n for (const pkg of plan.packages) {\n const onDisk = await readDiskVersion(pkg.path);\n if (onDisk === undefined) {\n return `${pkg.name}: package.json not readable at ${pkg.path}`;\n }\n const expected = pkg[expectedField];\n if (onDisk !== expected) {\n return `${pkg.name}: expected ${expectedField} ${expected} on disk, found ${onDisk}`;\n }\n }\n\n return undefined;\n}\n\n/**\n * Load the plan produced by `release:plan` when it matches this run and the\n * working tree; otherwise plan fresh.\n */\nexport async function resolvePlan(options: ResolvePlanOptions): Promise<ResolvedPlan> {\n const { repoRoot, config, scope, flow, bumpOverride, channel, stage } = options;\n\n const computeFresh = async (reason?: string): Promise<ResolvedPlan> => ({\n plan: await planRelease({ cwd: repoRoot, config, scope, flow, bumpOverride, channel }),\n source: 'computed',\n ...(reason ? { reason } : {}),\n });\n\n let persisted: ReleasePlan;\n try {\n persisted = JSON.parse(await readFile(releasePlanPath(repoRoot, scope), 'utf-8')) as ReleasePlan;\n } catch {\n return computeFresh();\n }\n\n if (!Array.isArray(persisted.packages) || persisted.packages.length === 0) {\n return computeFresh('persisted plan has no packages');\n }\n\n // All flows share one scope-derived artifact path, so an unrelated flow's\n // plan can legitimately be sitting there. Never adopt it.\n if ((persisted.flow ?? undefined) !== (flow ?? undefined)) {\n return computeFresh(`persisted plan is for flow \"${persisted.flow ?? '<none>'}\", requested \"${flow ?? '<none>'}\"`);\n }\n if ((persisted.scope ?? undefined) !== (scope ?? undefined)) {\n return computeFresh(`persisted plan is for scope \"${persisted.scope ?? '<none>'}\", requested \"${scope ?? '<none>'}\"`);\n }\n if (channel !== undefined && persisted.channel !== channel) {\n return computeFresh(`persisted plan is for channel \"${persisted.channel}\", requested \"${channel}\"`);\n }\n\n const mismatch = await validateAgainstDisk(persisted, stage);\n if (mismatch) {\n return computeFresh(`persisted plan does not match working tree (${mismatch})`);\n }\n\n return { plan: persisted, source: 'artifact' };\n}\n","/**\n * Release git command — commit, tag, and push release changes.\n * Atomic step: reads plan, runs git ops, 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 commitAndTagRelease,\n resolveScopePath,\n type ReleaseConfig,\n type VersionBump,\n} from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\nimport { resolvePlan } from '../../shared/resolve-plan';\n\ninterface GitFlags {\n scope?: string;\n flow?: string;\n bump?: 'patch' | 'minor' | 'major' | 'auto';\n 'dry-run'?: boolean;\n 'no-verify'?: boolean;\n json?: boolean;\n}\n\ntype ReleaseGitResult = CommandResult<unknown>;\n\nfunction buildGitSections(\n result: { committed: boolean; tagged: string[]; pushed: boolean },\n dryRun: boolean,\n symbols: { success: string; warning: string },\n): Array<{ header?: string; items: string[] }> {\n if (dryRun) {\n return [{ items: [`${symbols.warning} Dry-run: no git operations performed`] }];\n }\n\n return [\n {\n header: 'Git Operations',\n items: [\n `${result.committed ? symbols.success : symbols.warning} Commit: ${result.committed ? 'created' : 'skipped'}`,\n `${result.tagged.length > 0 ? symbols.success : symbols.warning} Tags: ${result.tagged.length > 0 ? result.tagged.join(', ') : 'none'}`,\n `${result.pushed ? symbols.success : symbols.warning} Push: ${result.pushed ? 'done' : 'skipped'}`,\n ],\n },\n ];\n}\n\nexport default defineCommand({\n id: 'release:git',\n description: 'Commit, tag, and push release changes',\n\n handler: {\n async intent(ctx: PluginContextV3, input: CLIInput<GitFlags>) {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = { ...fileConfig, ...(flags.bump && { bump: flags.bump }) };\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 return {\n summary: `Commit, tag, and push release for ${plan.packages.length} package(s)`,\n operations: [\n { type: 'create' as const, resource: 'git-commit', details: { packages: plan.packages.length } },\n ...plan.packages.map(p => ({\n type: 'create' as const,\n resource: 'git-tag',\n details: { tag: `${p.name}@${p.nextVersion ?? 'unknown'}` },\n })),\n { type: 'create' as const, resource: 'git-push', details: { scope: flags.scope ?? 'root' } },\n ],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<GitFlags>): Promise<ReleaseGitResult> {\n const { flags } = input;\n const noVerify = flags['no-verify'] ?? false;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = {\n ...fileConfig,\n ...(flags.bump && { bump: flags.bump }),\n };\n\n const planLoader = useLoader('Loading release plan...');\n planLoader.start();\n // Must be the same plan `release:version` acted on — re-deriving it here\n // sees the versions that step just wrote as the new baseline and bumps a\n // second time, so the tag/commit message land one version ahead of the\n // package.json files being committed.\n const { plan, source, reason } = await resolvePlan({\n repoRoot,\n config,\n scope: flags.scope,\n flow: flags.flow,\n bumpOverride: flags.bump as VersionBump | undefined,\n stage: 'post-bump',\n });\n ctx.platform?.logger?.debug?.('Release plan resolved', { source, reason });\n planLoader.succeed(\n `${source === 'artifact' ? 'Loaded plan' : 'Recomputed plan'}: ${plan.packages.length} package(s)`,\n );\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?.({ committed: false, tagged: [], pushed: false, message: msg }); }\n else { ctx.ui?.write?.(msg); }\n console.log('::kb-output::' + JSON.stringify({ committed: false, tagged: [], pushed: false }));\n return { ok: true, result: { committed: false, tagged: [], pushed: false } };\n }\n\n const scopePath = await resolveScopePath(repoRoot, flags.scope ?? 'root');\n\n const gitLoader = useLoader('Committing, tagging, pushing...');\n gitLoader.start();\n\n const result = await commitAndTagRelease({\n cwd: scopePath,\n plan,\n dryRun: false,\n noVerify,\n // Without repoRoot the consolidated root changelog is never staged\n // (see the `root === repoRoot` branch in publisher.ts) — it stays\n // dirty in the working tree after every release.\n repoRoot,\n changelogOutputPath: config.changelog?.outputPath,\n flowName: flags.flow,\n tagPattern: flags.flow ? config.flows?.[flags.flow]?.tagPattern : undefined,\n });\n\n if (result.pushed) {\n gitLoader.succeed(`Committed, tagged (${result.tagged.length}), pushed`);\n } else {\n gitLoader.succeed(`Committed, tagged (${result.tagged.length})`);\n }\n\n console.log('::kb-output::' + JSON.stringify({\n committed: result.committed,\n tagged: result.tagged,\n pushed: result.pushed,\n }));\n\n if (flags.json) {\n ctx.ui?.json?.(result);\n return { ok: true, result };\n }\n\n ctx.ui?.sideBox?.({\n title: 'Git Operations',\n sections: buildGitSections(result, false, ctx.ui.symbols),\n status: 'success',\n });\n\n return { ok: true, result };\n },\n },\n});\n"]}
@@ -76,9 +76,9 @@ var plan_default = defineCommand({
76
76
  const planDir = ctx.runtime.fs.join(repoRoot, ".kb", "release", "plans", scopeDir, "current");
77
77
  const planPath = ctx.runtime.fs.join(planDir, "plan.json");
78
78
  const artifacts = [];
79
+ await ctx.runtime.fs.mkdir(planDir, { recursive: true });
80
+ await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: "utf-8" });
79
81
  if (!flags.json) {
80
- await ctx.runtime.fs.mkdir(planDir, { recursive: true });
81
- await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: "utf-8" });
82
82
  const stats = await ctx.runtime.fs.stat(planPath);
83
83
  artifacts.push({
84
84
  name: "Release Plan",
@@ -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":["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, type ReleaseChannel } 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 channel?: ReleaseChannel;\n json?: boolean;\n}\n\ntype ReleasePlanResult = CommandResult<unknown>;\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 ...(flags.channel && { channel: flags.channel }),\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 channel: config.channel,\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 { ok: true, result: { 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, type ReleaseChannel } 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 channel?: ReleaseChannel;\n json?: boolean;\n}\n\ntype ReleasePlanResult = CommandResult<unknown>;\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 ...(flags.channel && { channel: flags.channel }),\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 channel: config.channel,\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 // Always persist: later steps (`release:version`, `release:git`) consume\n // this artifact as the single source of truth for the run, so it must\n // exist regardless of how this invocation chose to render itself.\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 if (!flags.json) {\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 { ok: true, result: { plan } };\n },\n },\n});\n"]}
@@ -961,6 +961,7 @@ var run_default = defineCommand({
961
961
  checks: resolveChecks(flags, config),
962
962
  publisher,
963
963
  changelog,
964
+ shell: ctx.api.shell,
964
965
  logger: ctx.platform?.logger,
965
966
  onProgress: (_stage, message) => {
966
967
  const elapsed = ((Date.now() - pipelineStart) / 1e3).toFixed(1);