@kb-labs/release-manager-cli 2.77.0 → 2.79.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.
@@ -6,10 +6,142 @@ import { join } from 'path';
6
6
  import { generateChangelog, generateSimpleChangelog } from '@kb-labs/release-manager-changelog';
7
7
 
8
8
  // src/rest/handlers/run-handler.ts
9
+ function rewriteWorkspaceDeps(pkgPath, versionMap, packageManager) {
10
+ const pkgJsonPath = join(pkgPath, "package.json");
11
+ const original = readFileSync(pkgJsonPath, "utf-8");
12
+ const pkgJson = JSON.parse(original);
13
+ let modified = false;
14
+ for (const section of ["dependencies", "peerDependencies"]) {
15
+ const deps = pkgJson[section];
16
+ if (!deps) {
17
+ continue;
18
+ }
19
+ for (const depName of Object.keys(deps)) {
20
+ const val = deps[depName];
21
+ if (typeof val !== "string") {
22
+ continue;
23
+ }
24
+ if (val.startsWith("link:")) {
25
+ const pinned = versionMap.get(depName);
26
+ if (pinned) {
27
+ deps[depName] = `^${pinned}`;
28
+ } else {
29
+ try {
30
+ const linkPath = val.slice("link:".length);
31
+ const linked = JSON.parse(readFileSync(join(pkgPath, linkPath, "package.json"), "utf-8"));
32
+ deps[depName] = `^${linked.version ?? "*"}`;
33
+ } catch {
34
+ deps[depName] = "*";
35
+ }
36
+ }
37
+ modified = true;
38
+ } else if (val.startsWith("workspace:") && packageManager !== "pnpm") {
39
+ const pinned = versionMap.get(depName);
40
+ if (pinned) {
41
+ deps[depName] = val === "workspace:*" ? `^${pinned}` : val.replace("workspace:", "");
42
+ modified = true;
43
+ }
44
+ }
45
+ }
46
+ }
47
+ if (modified) {
48
+ writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
49
+ }
50
+ return () => writeFileSync(pkgJsonPath, original);
51
+ }
52
+ function topoSort(packages, packageManager) {
53
+ const nameSet = new Set(packages.map((p) => p.name));
54
+ const deps = /* @__PURE__ */ new Map();
55
+ for (const pkg of packages) {
56
+ const intra = /* @__PURE__ */ new Set();
57
+ try {
58
+ const pkgJson = JSON.parse(readFileSync(join(pkg.path, "package.json"), "utf-8"));
59
+ for (const section of ["dependencies", "peerDependencies"]) {
60
+ for (const depName of Object.keys(pkgJson[section] ?? {})) {
61
+ if (nameSet.has(depName)) {
62
+ intra.add(depName);
63
+ }
64
+ }
65
+ }
66
+ } catch {
67
+ }
68
+ deps.set(pkg.name, intra);
69
+ }
70
+ const inDegree = new Map(packages.map((p) => [p.name, 0]));
71
+ for (const [, d] of deps) {
72
+ for (const dep of d) {
73
+ inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
74
+ }
75
+ }
76
+ const dependants = /* @__PURE__ */ new Map();
77
+ for (const pkg of packages) {
78
+ for (const dep of deps.get(pkg.name) ?? []) {
79
+ if (!dependants.has(dep)) {
80
+ dependants.set(dep, /* @__PURE__ */ new Set());
81
+ }
82
+ dependants.get(dep).add(pkg.name);
83
+ }
84
+ }
85
+ const remaining = new Map(
86
+ packages.map((p) => [p.name, (deps.get(p.name) ?? /* @__PURE__ */ new Set()).size])
87
+ );
88
+ const byName = new Map(packages.map((p) => [p.name, p]));
89
+ const waves = [];
90
+ while (remaining.size > 0) {
91
+ const wave = [...remaining.entries()].filter(([, count]) => count === 0).map(([name]) => byName.get(name));
92
+ if (wave.length === 0) {
93
+ waves.push([...remaining.keys()].map((n) => byName.get(n)));
94
+ break;
95
+ }
96
+ waves.push(wave);
97
+ for (const pkg of wave) {
98
+ remaining.delete(pkg.name);
99
+ for (const dependant of dependants.get(pkg.name) ?? []) {
100
+ if (remaining.has(dependant)) {
101
+ remaining.set(dependant, (remaining.get(dependant) ?? 1) - 1);
102
+ }
103
+ }
104
+ }
105
+ }
106
+ return waves.filter((w) => w.length > 0);
107
+ }
108
+
109
+ // src/shared/publish-programmatic.ts
110
+ var MAX_RETRIES = 5;
111
+ var RETRY_BASE_DELAYS_MS = [1e4, 2e4, 4e4, 8e4, 16e4];
112
+ var RETRYABLE_PATTERNS = [
113
+ "E429",
114
+ "429 Too Many Requests",
115
+ "ECONNRESET",
116
+ "ETIMEDOUT",
117
+ "ECONNREFUSED",
118
+ "ENOTFOUND",
119
+ "EAI_AGAIN",
120
+ "socket hang up",
121
+ "network timeout",
122
+ "read ECONNRESET"
123
+ ];
124
+ var ALREADY_PUBLISHED_PATTERNS = [
125
+ "You cannot publish over the previously published versions",
126
+ "cannot publish over the previously published version",
127
+ "EPUBLISHCONFLICT"
128
+ // Some registries return 403 for conflicts
129
+ ];
130
+ function isRetryable(message) {
131
+ return RETRYABLE_PATTERNS.some((p) => message.includes(p));
132
+ }
133
+ function isAlreadyPublished(message) {
134
+ return ALREADY_PUBLISHED_PATTERNS.some((p) => message.includes(p));
135
+ }
136
+ function retryDelay(attempt) {
137
+ const base = RETRY_BASE_DELAYS_MS[Math.min(attempt, RETRY_BASE_DELAYS_MS.length - 1)];
138
+ const jitter = 0.8 + Math.random() * 0.4;
139
+ return Math.round(base * jitter);
140
+ }
9
141
  function resolveToken(token) {
10
142
  return token ?? useEnv("NPM_TOKEN") ?? useEnv("NODE_AUTH_TOKEN");
11
143
  }
12
- function publishSinglePackage(options) {
144
+ function spawnPublish(options) {
13
145
  const { packagePath, packageManager, token, otp, dryRun, tag, access, registry } = options;
14
146
  return new Promise((resolve, reject) => {
15
147
  const args = ["publish"];
@@ -45,6 +177,19 @@ function publishSinglePackage(options) {
45
177
  writeFileSync(npmrcPath, existing + authLine);
46
178
  }
47
179
  }
180
+ const restoreNpmrc = () => {
181
+ if (!token) {
182
+ return;
183
+ }
184
+ try {
185
+ if (npmrcBackup !== null) {
186
+ writeFileSync(npmrcPath, npmrcBackup);
187
+ } else if (existsSync(npmrcPath)) {
188
+ unlinkSync(npmrcPath);
189
+ }
190
+ } catch {
191
+ }
192
+ };
48
193
  const child = spawn(packageManager, args, {
49
194
  cwd: packagePath,
50
195
  stdio: ["ignore", "pipe", "pipe"],
@@ -53,24 +198,14 @@ function publishSinglePackage(options) {
53
198
  });
54
199
  let stdout = "";
55
200
  let stderr = "";
56
- child.stdout?.on("data", (data) => {
57
- stdout += data.toString();
201
+ child.stdout?.on("data", (d) => {
202
+ stdout += d.toString();
58
203
  });
59
- child.stderr?.on("data", (data) => {
60
- stderr += data.toString();
204
+ child.stderr?.on("data", (d) => {
205
+ stderr += d.toString();
61
206
  });
62
- const cleanupNpmrc = () => {
63
- if (!token) {
64
- return;
65
- }
66
- if (npmrcBackup !== null) {
67
- writeFileSync(npmrcPath, npmrcBackup);
68
- } else if (existsSync(npmrcPath)) {
69
- unlinkSync(npmrcPath);
70
- }
71
- };
72
207
  child.on("close", (code) => {
73
- cleanupNpmrc();
208
+ restoreNpmrc();
74
209
  if (code === 0) {
75
210
  resolve();
76
211
  } else {
@@ -78,12 +213,66 @@ function publishSinglePackage(options) {
78
213
  }
79
214
  });
80
215
  child.on("error", (err) => {
216
+ restoreNpmrc();
81
217
  reject(err);
82
218
  });
83
219
  });
84
220
  }
221
+ async function publishOne(pkg, opts, logger) {
222
+ const restore = rewriteWorkspaceDeps(pkg.path, opts.versionMap, opts.packageManager);
223
+ try {
224
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
225
+ try {
226
+ await spawnPublish({
227
+ packagePath: pkg.path,
228
+ packageManager: opts.packageManager,
229
+ token: opts.token,
230
+ otp: opts.otp,
231
+ dryRun: opts.dryRun,
232
+ tag: opts.tag,
233
+ access: opts.access,
234
+ registry: opts.registry
235
+ });
236
+ logger.info(`Published ${pkg.name}@${pkg.version}`);
237
+ return { name: pkg.name, version: pkg.version, success: true };
238
+ } catch (err) {
239
+ const message = err instanceof Error ? err.message : String(err);
240
+ if (isAlreadyPublished(message)) {
241
+ logger.info(`${pkg.name}@${pkg.version} already published \u2014 skipping`);
242
+ return { name: pkg.name, version: pkg.version, success: true, alreadyPublished: true };
243
+ }
244
+ if (isRetryable(message) && attempt < MAX_RETRIES) {
245
+ const delay = retryDelay(attempt);
246
+ logger.warn(
247
+ `Transient error for ${pkg.name}@${pkg.version} (attempt ${attempt + 1}/${MAX_RETRIES}), retrying in ${(delay / 1e3).toFixed(1)}s: ${message.split("\n")[0]}`
248
+ );
249
+ await new Promise((r) => setTimeout(r, delay));
250
+ continue;
251
+ }
252
+ logger.error(`Failed to publish ${pkg.name}@${pkg.version}`, void 0, { error: message });
253
+ return { name: pkg.name, version: pkg.version, success: false, error: message };
254
+ }
255
+ }
256
+ return {
257
+ name: pkg.name,
258
+ version: pkg.version,
259
+ success: false,
260
+ error: `Publish failed after ${MAX_RETRIES} retries (transient errors)`
261
+ };
262
+ } finally {
263
+ restore();
264
+ }
265
+ }
85
266
  async function publishPackagesProgrammatic(options) {
86
- const { packages, packageManager = "pnpm", dryRun, otp, tag, access, registry } = options;
267
+ const {
268
+ packages,
269
+ packageManager = "pnpm",
270
+ dryRun,
271
+ otp,
272
+ tag,
273
+ access,
274
+ registry
275
+ } = options;
87
276
  const logger = useLogger();
88
277
  const token = resolveToken(options.token);
89
278
  if (!token && !dryRun) {
@@ -92,107 +281,63 @@ async function publishPackagesProgrammatic(options) {
92
281
  return {
93
282
  results: [],
94
283
  published: [],
284
+ alreadyPublished: [],
95
285
  failed: packages.map((p) => `${p.name}@${p.version}`),
96
286
  skipped: [],
97
287
  errors: [error]
98
288
  };
99
289
  }
100
290
  const versionMap = new Map(packages.map((p) => [p.name, p.version]));
101
- const CONCURRENCY = Number(useEnv("KB_PUBLISH_CONCURRENCY") ?? 8);
102
- const MAX_429_RETRIES = 3;
103
- const RETRY_429_DELAYS = [15e3, 3e4, 6e4];
104
- const publishOne = async (pkg) => {
105
- logger.info(`Publishing ${pkg.name}@${pkg.version}`, { path: pkg.path, dryRun });
106
- const pkgJsonPath = join(pkg.path, "package.json");
107
- const originalPkgJson = readFileSync(pkgJsonPath, "utf-8");
108
- let restored = false;
109
- try {
110
- const pkgJson = JSON.parse(originalPkgJson);
111
- let modified = false;
112
- for (const section of ["dependencies", "peerDependencies"]) {
113
- const deps = pkgJson[section];
114
- if (!deps) {
115
- continue;
116
- }
117
- for (const [depName, depValue] of Object.entries(deps)) {
118
- if (typeof depValue !== "string") {
119
- continue;
120
- }
121
- const val = depValue;
122
- if (val.startsWith("link:")) {
123
- const planVersion = versionMap.get(depName);
124
- if (planVersion) {
125
- deps[depName] = `^${planVersion}`;
126
- modified = true;
127
- } else {
128
- try {
129
- const linkPath = val.replace("link:", "");
130
- const linkedPkg = JSON.parse(readFileSync(join(pkg.path, linkPath, "package.json"), "utf-8"));
131
- deps[depName] = `^${linkedPkg.version}`;
132
- modified = true;
133
- } catch {
134
- deps[depName] = "*";
135
- modified = true;
136
- }
137
- }
138
- } else if (val.startsWith("workspace:") && packageManager !== "pnpm") {
139
- const planVersion = versionMap.get(depName);
140
- if (planVersion) {
141
- deps[depName] = val === "workspace:*" ? `^${planVersion}` : val.replace("workspace:", "");
142
- modified = true;
143
- }
144
- }
145
- }
146
- }
147
- if (modified) {
148
- writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
149
- }
150
- for (let attempt = 0; attempt <= MAX_429_RETRIES; attempt++) {
151
- try {
152
- await publishSinglePackage({
153
- packagePath: pkg.path,
154
- packageManager,
155
- token,
156
- otp,
157
- dryRun,
158
- tag,
159
- access: access ?? "public",
160
- registry
161
- });
162
- logger.info(`Published ${pkg.name}@${pkg.version}`);
163
- return { name: pkg.name, version: pkg.version, success: true };
164
- } catch (error) {
165
- const message = error instanceof Error ? error.message : String(error);
166
- if ((message.includes("E429") || message.includes("429 Too Many Requests")) && attempt < MAX_429_RETRIES) {
167
- const delay = RETRY_429_DELAYS[attempt];
168
- logger.warn(`429 rate limit for ${pkg.name}, retrying in ${delay / 1e3}s`, { attempt: attempt + 1 });
169
- await new Promise((r) => setTimeout(r, delay));
170
- continue;
291
+ const CONCURRENCY = Number(useEnv("KB_PUBLISH_CONCURRENCY") ?? 4);
292
+ const waves = topoSort(packages);
293
+ logger.info(
294
+ `Publishing ${packages.length} package(s) in ${waves.length} topological wave(s) (concurrency=${CONCURRENCY}, dryRun=${dryRun ?? false})`
295
+ );
296
+ const allResults = [];
297
+ for (let waveIdx = 0; waveIdx < waves.length; waveIdx++) {
298
+ const wave = waves[waveIdx];
299
+ logger.info(`Wave ${waveIdx + 1}/${waves.length}: publishing ${wave.length} package(s)`);
300
+ for (let i = 0; i < wave.length; i += CONCURRENCY) {
301
+ const batch = wave.slice(i, i + CONCURRENCY);
302
+ const batchResults = await Promise.all(
303
+ batch.map(
304
+ (pkg) => publishOne(pkg, { packageManager, token, versionMap, dryRun, otp, tag, access, registry }, logger)
305
+ )
306
+ );
307
+ allResults.push(...batchResults);
308
+ }
309
+ const waveFailed = allResults.slice(-wave.length).filter((r) => !r.success);
310
+ if (waveFailed.length > 0) {
311
+ const remaining = waves.slice(waveIdx + 1).reduce((acc, w) => acc + w.length, 0);
312
+ if (remaining > 0) {
313
+ logger.warn(
314
+ `Wave ${waveIdx + 1} had ${waveFailed.length} failure(s) \u2014 skipping ${remaining} package(s) in later waves to avoid broken dependency chain`
315
+ );
316
+ for (const laterWave of waves.slice(waveIdx + 1)) {
317
+ for (const pkg of laterWave) {
318
+ allResults.push({
319
+ name: pkg.name,
320
+ version: pkg.version,
321
+ success: false,
322
+ error: "Skipped: dependency wave failed"
323
+ });
171
324
  }
172
- logger.error(`Failed to publish ${pkg.name}@${pkg.version}`, void 0, { error: message });
173
- return { name: pkg.name, version: pkg.version, success: false, error: message };
174
325
  }
175
326
  }
176
- return { name: pkg.name, version: pkg.version, success: false, error: "429 rate limit: max retries exceeded" };
177
- } finally {
178
- if (!restored) {
179
- writeFileSync(pkgJsonPath, originalPkgJson);
180
- restored = true;
181
- }
327
+ break;
182
328
  }
183
- };
184
- const results = [];
185
- for (let i = 0; i < packages.length; i += CONCURRENCY) {
186
- const batch = packages.slice(i, i + CONCURRENCY);
187
- const batchResults = await Promise.all(batch.map(publishOne));
188
- results.push(...batchResults);
189
329
  }
190
- const published = results.filter((r) => r.success).map((r) => `${r.name}@${r.version}`);
191
- const failed = results.filter((r) => !r.success).map((r) => `${r.name}@${r.version}`);
192
- const errors = results.filter((r) => !r.success && r.error).map((r) => `${r.name}: ${r.error}`);
330
+ const published = allResults.filter((r) => r.success && !r.alreadyPublished).map((r) => `${r.name}@${r.version}`);
331
+ const alreadyPublished = allResults.filter((r) => r.alreadyPublished).map((r) => `${r.name}@${r.version}`);
332
+ const failed = allResults.filter((r) => !r.success).map((r) => `${r.name}@${r.version}`);
333
+ const errors = allResults.filter((r) => !r.success && r.error).map((r) => `${r.name}: ${r.error}`);
334
+ if (alreadyPublished.length > 0) {
335
+ logger.info(`${alreadyPublished.length} package(s) already published \u2014 counted as success`);
336
+ }
193
337
  return {
194
- results,
338
+ results: allResults,
195
339
  published,
340
+ alreadyPublished,
196
341
  failed,
197
342
  skipped: dryRun ? packages.map((p) => `${p.name}@${p.version} (dry-run)`) : [],
198
343
  errors
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/publish-programmatic.ts","../../../src/shared/changelog-factory.ts","../../../src/rest/handlers/run-handler.ts"],"names":[],"mappings":"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","file":"run-handler.js","sourcesContent":["/**\n * Programmatic npm publishing for REST handlers (non-interactive context)\n *\n * Uses `npm publish` CLI via spawn with NODE_AUTH_TOKEN env variable.\n * This is the correct approach for granular access tokens (classic tokens\n * were revoked by npm in December 2025).\n *\n * Token resolution order:\n * 1. options.token (explicit override)\n * 2. NPM_TOKEN env variable\n * 3. NODE_AUTH_TOKEN env variable\n */\n\nimport { spawn } from 'node:child_process';\nimport { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { useLogger, useEnv } from '@kb-labs/sdk';\n\nexport interface PackageToPublish {\n name: string;\n version: string;\n path: string;\n}\n\nexport interface ProgrammaticPublishOptions {\n packages: PackageToPublish[];\n packageManager?: 'pnpm' | 'npm' | 'yarn';\n dryRun?: boolean;\n otp?: string;\n tag?: string;\n access?: 'public' | 'restricted';\n registry?: string;\n token?: string;\n}\n\nexport interface PublishResult {\n name: string;\n version: string;\n success: boolean;\n error?: string;\n}\n\nexport interface ProgrammaticPublishResult {\n results: PublishResult[];\n published: string[];\n failed: string[];\n skipped: string[];\n errors: string[];\n}\n\n/**\n * Resolve npm auth token from options or environment\n */\nfunction resolveToken(token?: string): string | undefined {\n return token ?? useEnv('NPM_TOKEN') ?? useEnv('NODE_AUTH_TOKEN');\n}\n\n/**\n * Publish a single package using npm CLI\n * Passes auth token via NODE_AUTH_TOKEN env (recommended for granular tokens)\n */\nfunction publishSinglePackage(options: {\n packagePath: string;\n packageManager: string;\n token: string | undefined;\n otp?: string;\n dryRun?: boolean;\n tag?: string;\n access?: string;\n registry?: string;\n}): Promise<void> {\n const { packagePath, packageManager, token, otp, dryRun, tag, access, registry } = options;\n\n return new Promise((resolve, reject) => {\n const args = ['publish'];\n\n // pnpm checks git cleanliness before publish, but our pipeline already bumps versions\n // (making the tree dirty) before calling publish — disable this check.\n if (packageManager === 'pnpm') {\n args.push('--no-git-checks');\n }\n\n if (dryRun) {\n args.push('--dry-run');\n }\n\n if (tag) {\n args.push(`--tag=${tag}`);\n }\n\n if (access) {\n args.push(`--access=${access}`);\n }\n\n if (registry) {\n args.push(`--registry=${registry}`);\n }\n\n if (otp) {\n args.push(`--otp=${otp}`);\n }\n\n const env: NodeJS.ProcessEnv = { ...process.env };\n if (token) {\n env['NODE_AUTH_TOKEN'] = token;\n }\n\n // Write a temporary .npmrc so npm picks up NODE_AUTH_TOKEN without\n // requiring it to be pre-configured in the global ~/.npmrc.\n const npmrcPath = join(packagePath, '.npmrc');\n const npmrcExisted = existsSync(npmrcPath);\n const npmrcBackup = npmrcExisted ? readFileSync(npmrcPath, 'utf-8') : null;\n const authLine = '//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\\n';\n if (token) {\n const existing = npmrcExisted ? readFileSync(npmrcPath, 'utf-8') : '';\n if (!existing.includes('_authToken')) {\n writeFileSync(npmrcPath, existing + authLine);\n }\n }\n\n const child = spawn(packageManager, args, {\n cwd: packagePath,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n env,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const cleanupNpmrc = () => {\n if (!token) { return; }\n if (npmrcBackup !== null) {\n writeFileSync(npmrcPath, npmrcBackup);\n } else if (existsSync(npmrcPath)) {\n unlinkSync(npmrcPath);\n }\n };\n\n child.on('close', (code: number | null) => {\n cleanupNpmrc();\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || stdout || `${packageManager} publish exited with code ${code}`));\n }\n });\n\n child.on('error', (err: Error) => {\n reject(err);\n });\n });\n}\n\n/**\n * Publish packages programmatically (non-interactive, for REST handlers)\n * Uses npm CLI with NODE_AUTH_TOKEN — works with granular access tokens.\n */\nexport async function publishPackagesProgrammatic(\n options: ProgrammaticPublishOptions\n): Promise<ProgrammaticPublishResult> {\n const { packages, packageManager = 'pnpm', dryRun, otp, tag, access, registry } = options;\n const logger = useLogger();\n\n const token = resolveToken(options.token);\n\n if (!token && !dryRun) {\n const error = 'No npm token found. Set NPM_TOKEN (or NODE_AUTH_TOKEN) in environment.';\n logger.error(error);\n return {\n results: [],\n published: [],\n failed: packages.map((p) => `${p.name}@${p.version}`),\n skipped: [],\n errors: [error],\n };\n }\n\n // Build version map from all packages in this release for link: → ^version replacement\n const versionMap = new Map(packages.map(p => [p.name, p.version]));\n\n const CONCURRENCY = Number(useEnv('KB_PUBLISH_CONCURRENCY') ?? 8);\n const MAX_429_RETRIES = 3;\n const RETRY_429_DELAYS = [15_000, 30_000, 60_000] as const;\n\n const publishOne = async (pkg: PackageToPublish): Promise<PublishResult> => {\n logger.info(`Publishing ${pkg.name}@${pkg.version}`, { path: pkg.path, dryRun });\n\n const pkgJsonPath = join(pkg.path, 'package.json');\n const originalPkgJson = readFileSync(pkgJsonPath, 'utf-8');\n let restored = false;\n\n try {\n const pkgJson = JSON.parse(originalPkgJson);\n let modified = false;\n\n for (const section of ['dependencies', 'peerDependencies'] as const) {\n const deps = pkgJson[section];\n if (!deps) {continue;}\n for (const [depName, depValue] of Object.entries(deps)) {\n if (typeof depValue !== 'string') {continue;}\n const val = depValue as string;\n\n if (val.startsWith('link:')) {\n const planVersion = versionMap.get(depName);\n if (planVersion) {\n deps[depName] = `^${planVersion}`;\n modified = true;\n } else {\n try {\n const linkPath = val.replace('link:', '');\n const linkedPkg = JSON.parse(readFileSync(join(pkg.path, linkPath, 'package.json'), 'utf-8'));\n deps[depName] = `^${linkedPkg.version}`;\n modified = true;\n } catch {\n deps[depName] = '*';\n modified = true;\n }\n }\n } else if (val.startsWith('workspace:') && packageManager !== 'pnpm') {\n const planVersion = versionMap.get(depName);\n if (planVersion) {\n deps[depName] = val === 'workspace:*' ? `^${planVersion}` : val.replace('workspace:', '');\n modified = true;\n }\n }\n }\n }\n\n if (modified) {\n writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\\n');\n }\n\n for (let attempt = 0; attempt <= MAX_429_RETRIES; attempt++) {\n try {\n await publishSinglePackage({\n packagePath: pkg.path,\n packageManager,\n token,\n otp,\n dryRun,\n tag,\n access: access ?? 'public',\n registry,\n });\n logger.info(`Published ${pkg.name}@${pkg.version}`);\n return { name: pkg.name, version: pkg.version, success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n if ((message.includes('E429') || message.includes('429 Too Many Requests')) && attempt < MAX_429_RETRIES) {\n const delay = RETRY_429_DELAYS[attempt]!;\n logger.warn(`429 rate limit for ${pkg.name}, retrying in ${delay / 1000}s`, { attempt: attempt + 1 });\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n logger.error(`Failed to publish ${pkg.name}@${pkg.version}`, undefined, { error: message });\n return { name: pkg.name, version: pkg.version, success: false, error: message };\n }\n }\n return { name: pkg.name, version: pkg.version, success: false, error: '429 rate limit: max retries exceeded' };\n } finally {\n if (!restored) {\n writeFileSync(pkgJsonPath, originalPkgJson);\n restored = true;\n }\n }\n };\n\n // Run publishes in parallel batches\n const results: PublishResult[] = [];\n for (let i = 0; i < packages.length; i += CONCURRENCY) {\n const batch = packages.slice(i, i + CONCURRENCY);\n const batchResults = await Promise.all(batch.map(publishOne));\n results.push(...batchResults);\n }\n\n const published = results.filter((r) => r.success).map((r) => `${r.name}@${r.version}`);\n const failed = results.filter((r) => !r.success).map((r) => `${r.name}@${r.version}`);\n const errors = results.filter((r) => !r.success && r.error).map((r) => `${r.name}: ${r.error}`);\n\n return {\n results,\n published,\n failed,\n skipped: dryRun ? packages.map((p) => `${p.name}@${p.version} (dry-run)`) : [],\n errors,\n };\n}\n","/**\n * Shared changelog generator factory.\n * Used by both CLI (run.ts) and REST (run-handler.ts) to avoid duplication.\n */\n\nimport {\n generateChangelog,\n generateSimpleChangelog,\n type ChangelogPackageInfo,\n} from '@kb-labs/release-manager-changelog';\nimport type { ReleaseConfig, ChangelogGenerator } from '@kb-labs/release-manager-core';\n\nexport function createChangelogGenerator(config: ReleaseConfig, llm?: any): ChangelogGenerator {\n return {\n async generate(plan, opts) {\n const locale = (config.changelog?.locale as 'en' | 'ru') || 'en';\n const packages: ChangelogPackageInfo[] = plan.packages.map(pkg => ({\n name: pkg.name,\n path: pkg.path,\n currentVersion: pkg.currentVersion,\n nextVersion: pkg.nextVersion,\n bump: pkg.bump === 'auto' ? 'patch' : pkg.bump,\n }));\n try {\n const result = await generateChangelog({\n repoRoot: opts.repoRoot,\n gitCwd: opts.gitCwd,\n packages,\n range: { to: 'HEAD' },\n changelog: {\n template: config.changelog?.template ?? undefined,\n locale,\n metadata: config.changelog?.metadata,\n ignoreAuthors: config.changelog?.ignoreAuthors,\n includeTypes: config.changelog?.includeTypes as string[],\n excludeTypes: config.changelog?.excludeTypes as string[],\n collapseMerges: config.changelog?.collapseMerges,\n collapseReverts: config.changelog?.collapseReverts,\n preferMergeSummary: config.changelog?.preferMergeSummary,\n groups: config.changelog?.groups,\n },\n git: {\n autoUnshallow: config.git?.autoUnshallow,\n requireSignedTags: config.git?.requireSignedTags,\n baseUrl: config.git?.baseUrl ?? undefined,\n },\n platform: llm ? { llm } : undefined,\n });\n return result.markdown;\n } catch {\n return generateSimpleChangelog(packages, locale);\n }\n },\n };\n}\n","/**\n * Run release handler — thin adapter over core runReleasePipeline().\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, useConfig, useLLM } from '@kb-labs/sdk';\nimport type {\n RunReleaseRequest,\n RunReleaseResponse,\n} from '@kb-labs/release-manager-contracts';\nimport {\n runReleasePipeline,\n resolveScopePath,\n type ReleaseConfig,\n type PublishablePackage,\n type PublishResult,\n} from '@kb-labs/release-manager-core';\nimport { publishPackagesProgrammatic } from '../../shared/publish-programmatic';\nimport { createChangelogGenerator } from '../../shared/changelog-factory';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, RunReleaseRequest>): Promise<RunReleaseResponse> {\n const scope = input.body?.scope || 'root';\n const flow = input.body?.flow;\n const dryRun = input.body?.dryRun ?? false;\n const skipChecks = input.body?.skipChecks ?? false;\n const otp = input.body?.otp;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const scopeCwd = await resolveScopePath(repoRoot, scope);\n\n const config = await useConfig<ReleaseConfig>() ?? {};\n\n // Changelog generator (with LLM if available)\n const llm = useLLM();\n const changelog = createChangelogGenerator(config, llm ?? undefined);\n\n // Programmatic publisher (token-based, no interactive OTP)\n const publisher = {\n async publish(packages: PublishablePackage[], opts: { dryRun?: boolean }): Promise<PublishResult> {\n return publishPackagesProgrammatic({\n packages,\n packageManager: config.workspace?.type ?? config.publish?.packageManager ?? 'pnpm',\n dryRun: opts.dryRun,\n otp,\n });\n },\n };\n\n const result = await runReleasePipeline({\n cwd,\n repoRoot,\n scopeCwd,\n scope,\n flow,\n config,\n dryRun,\n skipChecks,\n checks: (flow ? config.flows?.[flow]?.checks : undefined)\n ?? config.scopes?.[scope]?.checks\n ?? config.checks ?? [],\n publisher,\n changelog,\n logger: ctx.platform?.logger,\n });\n\n // Track analytics\n await ctx.platform?.analytics?.track?.(result.success ? 'release.completed' : 'release.failed', {\n scope,\n packagesCount: result.plan.packages.length,\n publishedCount: result.report.result.published?.length ?? 0,\n dryRun,\n durationMs: result.report.result.timingMs,\n });\n\n return {\n scope,\n report: result.report as any,\n success: result.success,\n errors: result.report.result.errors,\n };\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/dep-rewrite.ts","../../../src/shared/publish-programmatic.ts","../../../src/shared/changelog-factory.ts","../../../src/rest/handlers/run-handler.ts"],"names":["join","readFileSync","writeFileSync"],"mappings":"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","file":"run-handler.js","sourcesContent":["/**\n * Rewrite workspace:/link: dependency references to pinned npm versions.\n *\n * - pnpm handles `workspace:*` natively during `pnpm publish` — no rewrite needed.\n * - npm/yarn do NOT — we must replace with `^version` before publish.\n * - `link:` references are never valid on the npm registry — always rewrite.\n *\n * Returns a restore function that reverts package.json to original content.\n * Call it in a finally block to guarantee cleanup.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function rewriteWorkspaceDeps(\n pkgPath: string,\n versionMap: Map<string, string>,\n packageManager: string,\n): () => void {\n const pkgJsonPath = join(pkgPath, 'package.json');\n const original = readFileSync(pkgJsonPath, 'utf-8');\n const pkgJson = JSON.parse(original) as Record<string, unknown>;\n let modified = false;\n\n for (const section of ['dependencies', 'peerDependencies'] as const) {\n const deps = pkgJson[section] as Record<string, string> | undefined;\n if (!deps) { continue; }\n\n for (const depName of Object.keys(deps)) {\n const val = deps[depName];\n if (typeof val !== 'string') { continue; }\n\n if (val.startsWith('link:')) {\n // link: is always invalid on npm registry — replace with semver range\n const pinned = versionMap.get(depName);\n if (pinned) {\n deps[depName] = `^${pinned}`;\n } else {\n try {\n const linkPath = val.slice('link:'.length);\n const linked = JSON.parse(readFileSync(join(pkgPath, linkPath, 'package.json'), 'utf-8')) as { version?: string };\n deps[depName] = `^${linked.version ?? '*'}`;\n } catch {\n deps[depName] = '*';\n }\n }\n modified = true;\n } else if (val.startsWith('workspace:') && packageManager !== 'pnpm') {\n // pnpm publish rewrites workspace: natively; npm/yarn need manual replacement\n const pinned = versionMap.get(depName);\n if (pinned) {\n deps[depName] = val === 'workspace:*' ? `^${pinned}` : val.replace('workspace:', '');\n modified = true;\n }\n }\n }\n }\n\n if (modified) {\n writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\\n');\n }\n\n return () => writeFileSync(pkgJsonPath, original);\n}\n\n/**\n * Build a simple topological sort of packages for publish order.\n *\n * Packages are grouped into \"waves\": wave 0 has no intra-release deps,\n * wave 1 depends only on wave 0, etc. Within each wave publish order\n * is arbitrary (safe to parallelise).\n *\n * Cycles (should not exist in a well-formed monorepo) fall into a\n * \"remainder\" group appended at the end.\n */\nexport interface TopoPackage {\n name: string;\n path: string;\n version: string;\n}\n\nexport function topoSort(packages: TopoPackage[], packageManager: string): TopoPackage[][] {\n const nameSet = new Set(packages.map(p => p.name));\n\n // Build adjacency: pkg → set of deps that are also being released\n const deps = new Map<string, Set<string>>();\n for (const pkg of packages) {\n const intra = new Set<string>();\n try {\n const pkgJson = JSON.parse(readFileSync(join(pkg.path, 'package.json'), 'utf-8')) as {\n dependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n };\n for (const section of ['dependencies', 'peerDependencies'] as const) {\n for (const depName of Object.keys(pkgJson[section] ?? {})) {\n if (nameSet.has(depName)) { intra.add(depName); }\n }\n }\n } catch {\n // If we can't read package.json, treat as no deps\n }\n deps.set(pkg.name, intra);\n }\n\n // Kahn's algorithm\n const inDegree = new Map<string, number>(packages.map(p => [p.name, 0]));\n for (const [, d] of deps) {\n for (const dep of d) {\n inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);\n }\n }\n\n // Actually we want packages whose deps are resolved first.\n // Recompute: inDegree[pkg] = number of its dependencies (incoming edges from deps).\n // A package is \"ready\" when all its dependencies have been placed in earlier waves.\n const dependants = new Map<string, Set<string>>(); // dep → packages that depend on it\n for (const pkg of packages) {\n for (const dep of deps.get(pkg.name) ?? []) {\n if (!dependants.has(dep)) { dependants.set(dep, new Set()); }\n dependants.get(dep)!.add(pkg.name);\n }\n }\n\n const remaining = new Map<string, number>(\n packages.map(p => [p.name, (deps.get(p.name) ?? new Set()).size])\n );\n\n const byName = new Map(packages.map(p => [p.name, p]));\n const waves: TopoPackage[][] = [];\n\n while (remaining.size > 0) {\n const wave = [...remaining.entries()]\n .filter(([, count]) => count === 0)\n .map(([name]) => byName.get(name)!);\n\n if (wave.length === 0) {\n // Cycle detected — dump remainder as a final wave\n waves.push([...remaining.keys()].map(n => byName.get(n)!));\n break;\n }\n\n waves.push(wave);\n for (const pkg of wave) {\n remaining.delete(pkg.name);\n for (const dependant of dependants.get(pkg.name) ?? []) {\n if (remaining.has(dependant)) {\n remaining.set(dependant, (remaining.get(dependant) ?? 1) - 1);\n }\n }\n }\n }\n\n return waves.filter(w => w.length > 0);\n}\n","/**\n * Programmatic npm publishing for REST handlers (non-interactive context).\n *\n * Uses `npm publish` CLI via spawn with NODE_AUTH_TOKEN env variable.\n * This is the correct approach for granular access tokens (classic tokens\n * were revoked by npm in December 2025).\n *\n * Token resolution order:\n * 1. options.token (explicit override)\n * 2. NPM_TOKEN env variable\n * 3. NODE_AUTH_TOKEN env variable\n *\n * Reliability guarantees:\n * - Already-published versions are treated as success (idempotent re-runs).\n * - 429 rate-limit: exponential back-off with jitter, up to MAX_RETRIES attempts.\n * - Transient network errors (ECONNRESET, ETIMEDOUT, etc.) are also retried.\n * - Packages are published in topological order (deps before dependants).\n * - Default concurrency is 4 — enough throughput, low enough to avoid rate limits.\n */\n\nimport { spawn } from 'node:child_process';\nimport { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { useLogger, useEnv } from '@kb-labs/sdk';\nimport { rewriteWorkspaceDeps, topoSort } from './dep-rewrite';\n\nexport interface PackageToPublish {\n name: string;\n version: string;\n path: string;\n}\n\nexport interface ProgrammaticPublishOptions {\n packages: PackageToPublish[];\n packageManager?: 'pnpm' | 'npm' | 'yarn';\n dryRun?: boolean;\n otp?: string;\n tag?: string;\n access?: 'public' | 'restricted';\n registry?: string;\n token?: string;\n}\n\nexport interface PublishResult {\n name: string;\n version: string;\n success: boolean;\n /** Package was already published at this version — counted as success. */\n alreadyPublished?: boolean;\n error?: string;\n}\n\nexport interface ProgrammaticPublishResult {\n results: PublishResult[];\n published: string[];\n /** Versions that were already on npm (counted as success). */\n alreadyPublished: string[];\n failed: string[];\n skipped: string[];\n errors: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Retry configuration\n// ---------------------------------------------------------------------------\n\nconst MAX_RETRIES = 5;\n\n// Exponential base delays (ms). Actual delay = base * jitter(0.8–1.2).\nconst RETRY_BASE_DELAYS_MS = [10_000, 20_000, 40_000, 80_000, 160_000] as const;\n\n/** Retryable error patterns — all transient, not indicative of a bad package. */\nconst RETRYABLE_PATTERNS = [\n 'E429',\n '429 Too Many Requests',\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'ECONNREFUSED',\n 'ENOTFOUND',\n 'EAI_AGAIN',\n 'socket hang up',\n 'network timeout',\n 'read ECONNRESET',\n];\n\n/** \"Already published\" — treat as success so re-runs are idempotent. */\nconst ALREADY_PUBLISHED_PATTERNS = [\n 'You cannot publish over the previously published versions',\n 'cannot publish over the previously published version',\n 'EPUBLISHCONFLICT',\n // Some registries return 403 for conflicts\n];\n\nfunction isRetryable(message: string): boolean {\n return RETRYABLE_PATTERNS.some(p => message.includes(p));\n}\n\nfunction isAlreadyPublished(message: string): boolean {\n return ALREADY_PUBLISHED_PATTERNS.some(p => message.includes(p));\n}\n\n/** Exponential back-off with ±20% jitter. */\nfunction retryDelay(attempt: number): number {\n const base = RETRY_BASE_DELAYS_MS[Math.min(attempt, RETRY_BASE_DELAYS_MS.length - 1)]!;\n const jitter = 0.8 + Math.random() * 0.4; // 0.8 – 1.2\n return Math.round(base * jitter);\n}\n\n// ---------------------------------------------------------------------------\n// Token resolution\n// ---------------------------------------------------------------------------\n\nfunction resolveToken(token?: string): string | undefined {\n return token ?? useEnv('NPM_TOKEN') ?? useEnv('NODE_AUTH_TOKEN');\n}\n\n// ---------------------------------------------------------------------------\n// Low-level spawn\n// ---------------------------------------------------------------------------\n\n/**\n * Spawn `packageManager publish` for a single package.\n * Writes a temporary .npmrc for NODE_AUTH_TOKEN auth, cleans it up on exit.\n */\nfunction spawnPublish(options: {\n packagePath: string;\n packageManager: string;\n token: string | undefined;\n otp?: string;\n dryRun?: boolean;\n tag?: string;\n access?: string;\n registry?: string;\n}): Promise<void> {\n const { packagePath, packageManager, token, otp, dryRun, tag, access, registry } = options;\n\n return new Promise((resolve, reject) => {\n const args = ['publish'];\n\n if (packageManager === 'pnpm') {\n // pnpm checks git cleanliness; we version-bump before publish which makes\n // the tree dirty — bypass that check.\n args.push('--no-git-checks');\n }\n if (dryRun) { args.push('--dry-run'); }\n if (tag) { args.push(`--tag=${tag}`); }\n if (access) { args.push(`--access=${access}`); }\n if (registry) { args.push(`--registry=${registry}`); }\n if (otp) { args.push(`--otp=${otp}`); }\n\n const env: NodeJS.ProcessEnv = { ...process.env };\n if (token) { env['NODE_AUTH_TOKEN'] = token; }\n\n // Write a per-package .npmrc so npm picks up NODE_AUTH_TOKEN.\n const npmrcPath = join(packagePath, '.npmrc');\n const npmrcExisted = existsSync(npmrcPath);\n const npmrcBackup = npmrcExisted ? readFileSync(npmrcPath, 'utf-8') : null;\n const authLine = '//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\\n';\n\n if (token) {\n const existing = npmrcExisted ? readFileSync(npmrcPath, 'utf-8') : '';\n if (!existing.includes('_authToken')) {\n writeFileSync(npmrcPath, existing + authLine);\n }\n }\n\n const restoreNpmrc = () => {\n if (!token) { return; }\n try {\n if (npmrcBackup !== null) {\n writeFileSync(npmrcPath, npmrcBackup);\n } else if (existsSync(npmrcPath)) {\n unlinkSync(npmrcPath);\n }\n } catch { /* best-effort */ }\n };\n\n const child = spawn(packageManager, args, {\n cwd: packagePath,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n env,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (d: Buffer) => { stdout += d.toString(); });\n child.stderr?.on('data', (d: Buffer) => { stderr += d.toString(); });\n\n child.on('close', (code: number | null) => {\n restoreNpmrc();\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || stdout || `${packageManager} publish exited with code ${code}`));\n }\n });\n\n child.on('error', (err: Error) => {\n restoreNpmrc();\n reject(err);\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Per-package publish with retry\n// ---------------------------------------------------------------------------\n\nasync function publishOne(\n pkg: PackageToPublish,\n opts: {\n packageManager: string;\n token: string | undefined;\n versionMap: Map<string, string>;\n dryRun?: boolean;\n otp?: string;\n tag?: string;\n access?: string;\n registry?: string;\n },\n logger: ReturnType<typeof useLogger>,\n): Promise<PublishResult> {\n const restore = rewriteWorkspaceDeps(pkg.path, opts.versionMap, opts.packageManager);\n\n try {\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n await spawnPublish({\n packagePath: pkg.path,\n packageManager: opts.packageManager,\n token: opts.token,\n otp: opts.otp,\n dryRun: opts.dryRun,\n tag: opts.tag,\n access: opts.access,\n registry: opts.registry,\n });\n\n logger.info(`Published ${pkg.name}@${pkg.version}`);\n return { name: pkg.name, version: pkg.version, success: true };\n\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n\n // Idempotency: already published at this version → success.\n if (isAlreadyPublished(message)) {\n logger.info(`${pkg.name}@${pkg.version} already published — skipping`);\n return { name: pkg.name, version: pkg.version, success: true, alreadyPublished: true };\n }\n\n // Retryable transient error (rate-limit, network blip).\n if (isRetryable(message) && attempt < MAX_RETRIES) {\n const delay = retryDelay(attempt);\n logger.warn(\n `Transient error for ${pkg.name}@${pkg.version} (attempt ${attempt + 1}/${MAX_RETRIES}), ` +\n `retrying in ${(delay / 1000).toFixed(1)}s: ${message.split('\\n')[0]}`,\n );\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n\n // Permanent failure.\n logger.error(`Failed to publish ${pkg.name}@${pkg.version}`, undefined, { error: message });\n return { name: pkg.name, version: pkg.version, success: false, error: message };\n }\n }\n\n // Exhausted retries.\n return {\n name: pkg.name,\n version: pkg.version,\n success: false,\n error: `Publish failed after ${MAX_RETRIES} retries (transient errors)`,\n };\n } finally {\n restore();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Publish packages programmatically (non-interactive, for REST handlers / CI).\n *\n * Packages are published in topological order (deps before dependants) to\n * avoid \"package not found\" errors when a dependent is installed right after\n * release. Within each topological wave, publishes run in parallel up to\n * CONCURRENCY.\n */\nexport async function publishPackagesProgrammatic(\n options: ProgrammaticPublishOptions,\n): Promise<ProgrammaticPublishResult> {\n const {\n packages,\n packageManager = 'pnpm',\n dryRun,\n otp,\n tag,\n access,\n registry,\n } = options;\n\n const logger = useLogger();\n const token = resolveToken(options.token);\n\n if (!token && !dryRun) {\n const error = 'No npm token found. Set NPM_TOKEN (or NODE_AUTH_TOKEN) in environment.';\n logger.error(error);\n return {\n results: [],\n published: [],\n alreadyPublished: [],\n failed: packages.map(p => `${p.name}@${p.version}`),\n skipped: [],\n errors: [error],\n };\n }\n\n // Version map for dep rewriting (workspace:/link: → ^version).\n const versionMap = new Map(packages.map(p => [p.name, p.version]));\n\n // Concurrency: default 4 — enough throughput, below npm's sustained rate limit.\n const CONCURRENCY = Number(useEnv('KB_PUBLISH_CONCURRENCY') ?? 4);\n\n // Sort packages into topological waves so deps are always published first.\n const waves = topoSort(packages, packageManager);\n\n logger.info(\n `Publishing ${packages.length} package(s) in ${waves.length} topological wave(s) ` +\n `(concurrency=${CONCURRENCY}, dryRun=${dryRun ?? false})`,\n );\n\n const allResults: PublishResult[] = [];\n\n for (let waveIdx = 0; waveIdx < waves.length; waveIdx++) {\n const wave = waves[waveIdx]!;\n logger.info(`Wave ${waveIdx + 1}/${waves.length}: publishing ${wave.length} package(s)`);\n\n // Publish wave in parallel batches.\n for (let i = 0; i < wave.length; i += CONCURRENCY) {\n const batch = wave.slice(i, i + CONCURRENCY);\n const batchResults = await Promise.all(\n batch.map(pkg =>\n publishOne(pkg, { packageManager, token, versionMap, dryRun, otp, tag, access, registry }, logger),\n ),\n );\n allResults.push(...batchResults);\n }\n\n // If any package in this wave genuinely failed (not alreadyPublished), stop\n // publishing the next wave — it may depend on the failed packages.\n const waveFailed = allResults.slice(-wave.length).filter(r => !r.success);\n if (waveFailed.length > 0) {\n const remaining = waves.slice(waveIdx + 1).reduce((acc, w) => acc + w.length, 0);\n if (remaining > 0) {\n logger.warn(\n `Wave ${waveIdx + 1} had ${waveFailed.length} failure(s) — ` +\n `skipping ${remaining} package(s) in later waves to avoid broken dependency chain`,\n );\n // Mark remaining packages as skipped-due-to-dependency-failure.\n for (const laterWave of waves.slice(waveIdx + 1)) {\n for (const pkg of laterWave) {\n allResults.push({\n name: pkg.name,\n version: pkg.version,\n success: false,\n error: 'Skipped: dependency wave failed',\n });\n }\n }\n }\n break;\n }\n }\n\n const published = allResults.filter(r => r.success && !r.alreadyPublished).map(r => `${r.name}@${r.version}`);\n const alreadyPublished = allResults.filter(r => r.alreadyPublished).map(r => `${r.name}@${r.version}`);\n const failed = allResults.filter(r => !r.success).map(r => `${r.name}@${r.version}`);\n const errors = allResults.filter(r => !r.success && r.error).map(r => `${r.name}: ${r.error}`);\n\n if (alreadyPublished.length > 0) {\n logger.info(`${alreadyPublished.length} package(s) already published — counted as success`);\n }\n\n return {\n results: allResults,\n published,\n alreadyPublished,\n failed,\n skipped: dryRun ? packages.map(p => `${p.name}@${p.version} (dry-run)`) : [],\n errors,\n };\n}\n","/**\n * Shared changelog generator factory.\n * Used by both CLI (run.ts) and REST (run-handler.ts) to avoid duplication.\n */\n\nimport {\n generateChangelog,\n generateSimpleChangelog,\n type ChangelogPackageInfo,\n} from '@kb-labs/release-manager-changelog';\nimport type { ReleaseConfig, ChangelogGenerator } from '@kb-labs/release-manager-core';\n\nexport function createChangelogGenerator(config: ReleaseConfig, llm?: any): ChangelogGenerator {\n return {\n async generate(plan, opts) {\n const locale = (config.changelog?.locale as 'en' | 'ru') || 'en';\n const packages: ChangelogPackageInfo[] = plan.packages.map(pkg => ({\n name: pkg.name,\n path: pkg.path,\n currentVersion: pkg.currentVersion,\n nextVersion: pkg.nextVersion,\n bump: pkg.bump === 'auto' ? 'patch' : pkg.bump,\n }));\n try {\n const result = await generateChangelog({\n repoRoot: opts.repoRoot,\n gitCwd: opts.gitCwd,\n packages,\n range: { to: 'HEAD' },\n changelog: {\n template: config.changelog?.template ?? undefined,\n locale,\n metadata: config.changelog?.metadata,\n ignoreAuthors: config.changelog?.ignoreAuthors,\n includeTypes: config.changelog?.includeTypes as string[],\n excludeTypes: config.changelog?.excludeTypes as string[],\n collapseMerges: config.changelog?.collapseMerges,\n collapseReverts: config.changelog?.collapseReverts,\n preferMergeSummary: config.changelog?.preferMergeSummary,\n groups: config.changelog?.groups,\n },\n git: {\n autoUnshallow: config.git?.autoUnshallow,\n requireSignedTags: config.git?.requireSignedTags,\n baseUrl: config.git?.baseUrl ?? undefined,\n },\n platform: llm ? { llm } : undefined,\n });\n return result.markdown;\n } catch {\n return generateSimpleChangelog(packages, locale);\n }\n },\n };\n}\n","/**\n * Run release handler — thin adapter over core runReleasePipeline().\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, useConfig, useLLM } from '@kb-labs/sdk';\nimport type {\n RunReleaseRequest,\n RunReleaseResponse,\n} from '@kb-labs/release-manager-contracts';\nimport {\n runReleasePipeline,\n resolveScopePath,\n type ReleaseConfig,\n type PublishablePackage,\n type PublishResult,\n} from '@kb-labs/release-manager-core';\nimport { publishPackagesProgrammatic } from '../../shared/publish-programmatic';\nimport { createChangelogGenerator } from '../../shared/changelog-factory';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, RunReleaseRequest>): Promise<RunReleaseResponse> {\n const scope = input.body?.scope || 'root';\n const flow = input.body?.flow;\n const dryRun = input.body?.dryRun ?? false;\n const skipChecks = input.body?.skipChecks ?? false;\n const otp = input.body?.otp;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const scopeCwd = await resolveScopePath(repoRoot, scope);\n\n const config = await useConfig<ReleaseConfig>() ?? {};\n\n // Changelog generator (with LLM if available)\n const llm = useLLM();\n const changelog = createChangelogGenerator(config, llm ?? undefined);\n\n // Programmatic publisher (token-based, no interactive OTP)\n const publisher = {\n async publish(packages: PublishablePackage[], opts: { dryRun?: boolean }): Promise<PublishResult> {\n return publishPackagesProgrammatic({\n packages,\n packageManager: config.workspace?.type ?? config.publish?.packageManager ?? 'pnpm',\n dryRun: opts.dryRun,\n otp,\n });\n },\n };\n\n const result = await runReleasePipeline({\n cwd,\n repoRoot,\n scopeCwd,\n scope,\n flow,\n config,\n dryRun,\n skipChecks,\n checks: (flow ? config.flows?.[flow]?.checks : undefined)\n ?? config.scopes?.[scope]?.checks\n ?? config.checks ?? [],\n publisher,\n changelog,\n logger: ctx.platform?.logger,\n });\n\n // Track analytics\n await ctx.platform?.analytics?.track?.(result.success ? 'release.completed' : 'release.failed', {\n scope,\n packagesCount: result.plan.packages.length,\n publishedCount: result.report.result.published?.length ?? 0,\n dryRun,\n durationMs: result.report.result.timingMs,\n });\n\n return {\n scope,\n report: result.report as any,\n success: result.success,\n errors: result.report.result.errors,\n };\n },\n});\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/release-manager-cli",
3
3
  "description": "KB Labs Release Manager - CLI commands for release management",
4
- "version": "2.77.0",
4
+ "version": "2.79.0",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Kirill Baranov",
@@ -26,12 +26,12 @@
26
26
  "globby": "^11.0.0",
27
27
  "npm-packlist": "^10.0.3",
28
28
  "zod": "^3.25.76",
29
- "@kb-labs/release-manager-changelog": "2.77.0",
30
- "@kb-labs/release-manager-core": "2.77.0",
31
- "@kb-labs/release-manager-contracts": "2.77.0",
32
- "@kb-labs/sdk": "2.21.2",
33
- "@kb-labs/studio-plugin-tools": "2.77.0",
34
- "@kb-labs/release-manager-checks": "2.77.0"
29
+ "@kb-labs/release-manager-checks": "2.79.0",
30
+ "@kb-labs/studio-plugin-tools": "2.79.0",
31
+ "@kb-labs/release-manager-core": "2.79.0",
32
+ "@kb-labs/release-manager-contracts": "2.79.0",
33
+ "@kb-labs/release-manager-changelog": "2.79.0",
34
+ "@kb-labs/sdk": "2.21.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@rspack/cli": "latest",
@@ -47,7 +47,7 @@
47
47
  "tsup": "^8.5.0",
48
48
  "typescript": "^5.6.3",
49
49
  "vitest": "^3.2.4",
50
- "@kb-labs/devkit": "2.77.0"
50
+ "@kb-labs/devkit": "2.79.0"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=20.0.0",