@kb-labs/release-manager-cli 2.93.0 → 2.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/cli/commands/build.js +1 -1
  2. package/dist/cli/commands/build.js.map +1 -1
  3. package/dist/cli/commands/changelog.js +1 -1
  4. package/dist/cli/commands/changelog.js.map +1 -1
  5. package/dist/cli/commands/checks.js +1 -1
  6. package/dist/cli/commands/checks.js.map +1 -1
  7. package/dist/cli/commands/git.js +31 -12
  8. package/dist/cli/commands/git.js.map +1 -1
  9. package/dist/cli/commands/pack.js +1 -1
  10. package/dist/cli/commands/pack.js.map +1 -1
  11. package/dist/cli/commands/plan.js +1 -1
  12. package/dist/cli/commands/plan.js.map +1 -1
  13. package/dist/cli/commands/publish.js +1 -1
  14. package/dist/cli/commands/publish.js.map +1 -1
  15. package/dist/cli/commands/report.js +5 -2
  16. package/dist/cli/commands/report.js.map +1 -1
  17. package/dist/cli/commands/rollback.js +9 -1
  18. package/dist/cli/commands/rollback.js.map +1 -1
  19. package/dist/cli/commands/run.js +5 -5
  20. package/dist/cli/commands/run.js.map +1 -1
  21. package/dist/cli/commands/verify.js +1 -1
  22. package/dist/cli/commands/verify.js.map +1 -1
  23. package/dist/cli/commands/version.js +22 -28
  24. package/dist/cli/commands/version.js.map +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +43 -61
  27. package/dist/index.js.map +1 -1
  28. package/dist/manifest.d.ts +62 -27
  29. package/dist/manifest.js +43 -61
  30. package/dist/manifest.js.map +1 -1
  31. package/dist/rest/handlers/build-handler.js +34 -30
  32. package/dist/rest/handlers/build-handler.js.map +1 -1
  33. package/dist/rest/handlers/changelog-generate-handler.js +98 -64
  34. package/dist/rest/handlers/changelog-generate-handler.js.map +1 -1
  35. package/dist/rest/handlers/changelog-handler.js +28 -24
  36. package/dist/rest/handlers/changelog-handler.js.map +1 -1
  37. package/dist/rest/handlers/changelog-save-handler.js +2 -2
  38. package/dist/rest/handlers/changelog-save-handler.js.map +1 -1
  39. package/dist/rest/handlers/checklist-handler.js +49 -45
  40. package/dist/rest/handlers/checklist-handler.js.map +1 -1
  41. package/dist/rest/handlers/generate-handler.js +96 -92
  42. package/dist/rest/handlers/generate-handler.js.map +1 -1
  43. package/dist/rest/handlers/get-checks-handler.js +16 -12
  44. package/dist/rest/handlers/get-checks-handler.js.map +1 -1
  45. package/dist/rest/handlers/git-timeline-handler.js +63 -59
  46. package/dist/rest/handlers/git-timeline-handler.js.map +1 -1
  47. package/dist/rest/handlers/history-changelog-handler.js +2 -2
  48. package/dist/rest/handlers/history-changelog-handler.js.map +1 -1
  49. package/dist/rest/handlers/history-handler.js +45 -41
  50. package/dist/rest/handlers/history-handler.js.map +1 -1
  51. package/dist/rest/handlers/history-plan-handler.js +2 -2
  52. package/dist/rest/handlers/history-plan-handler.js.map +1 -1
  53. package/dist/rest/handlers/history-report-handler.js +2 -2
  54. package/dist/rest/handlers/history-report-handler.js.map +1 -1
  55. package/dist/rest/handlers/plan-handler.js +57 -53
  56. package/dist/rest/handlers/plan-handler.js.map +1 -1
  57. package/dist/rest/handlers/preview-handler.js +90 -86
  58. package/dist/rest/handlers/preview-handler.js.map +1 -1
  59. package/dist/rest/handlers/report-handler.js +36 -32
  60. package/dist/rest/handlers/report-handler.js.map +1 -1
  61. package/dist/rest/handlers/reset-handler.js +22 -18
  62. package/dist/rest/handlers/reset-handler.js.map +1 -1
  63. package/dist/rest/handlers/run-checks-handler.js +43 -39
  64. package/dist/rest/handlers/run-checks-handler.js.map +1 -1
  65. package/dist/rest/handlers/run-handler.js +53 -49
  66. package/dist/rest/handlers/run-handler.js.map +1 -1
  67. package/dist/rest/handlers/scopes-handler.js +40 -36
  68. package/dist/rest/handlers/scopes-handler.js.map +1 -1
  69. package/dist/rest/handlers/status-handler.js +49 -45
  70. package/dist/rest/handlers/status-handler.js.map +1 -1
  71. package/dist/widgets/117.js +24 -1
  72. package/dist/widgets/{919.js → 215.js} +1 -1
  73. package/dist/widgets/370.js +1 -1
  74. package/dist/widgets/{805.js → 46.js} +92 -92
  75. package/dist/widgets/50.js +1 -1
  76. package/dist/widgets/62.js +96 -0
  77. package/dist/widgets/648.js +1 -0
  78. package/dist/widgets/669.js +1 -1
  79. package/dist/widgets/775.js +1 -1
  80. package/dist/widgets/78.js +1 -0
  81. package/dist/widgets/968.js +2 -2
  82. package/dist/widgets/__federation_expose_ReleasePage.js +1 -1
  83. package/dist/widgets/mf-manifest.json +31 -31
  84. package/dist/widgets/mf-stats.json +39 -39
  85. package/dist/widgets/remoteEntry.js +2 -2
  86. package/package.json +9 -8
  87. package/dist/widgets/418.js +0 -38
  88. package/dist/widgets/451.js +0 -1
  89. package/dist/widgets/694.js +0 -1
@@ -1,4 +1,4 @@
1
- import { defineHandler, findRepoRoot } from '@kb-labs/sdk';
1
+ import { defineHandler, findRepoRoot, rethrowForRest } from '@kb-labs/sdk';
2
2
  import { buildPackages } from '@kb-labs/release-manager-core';
3
3
  import { readFile, writeFile, mkdir } from 'fs/promises';
4
4
  import { existsSync } from 'fs';
@@ -31,37 +31,41 @@ async function copyChangelogToPackages(repoRoot, packages, results, changelogCon
31
31
  }
32
32
  var build_handler_default = defineHandler({
33
33
  async execute(ctx, input) {
34
- const scope = input.body?.scope || "root";
35
- const cwd = ctx.cwd ?? process.cwd();
36
- const repoRoot = await findRepoRoot(cwd);
37
- const startTime = Date.now();
38
- const scopeDir = scopeToDir(scope);
39
- const planPath = join(repoRoot, ".kb/release/plans", scopeDir, "current", "plan.json");
40
- let plan;
41
34
  try {
42
- plan = JSON.parse(await readFile(planPath, "utf-8"));
43
- } catch {
44
- return { scope, success: false, packages: [], builtCount: 0, totalCount: 0, totalDurationMs: Date.now() - startTime };
45
- }
46
- const results = await buildPackages(plan.packages, { logger: ctx.platform?.logger });
47
- const changelogPath = join(repoRoot, ".kb/release/plans", scopeDir, "current", "changelog.md");
48
- let changelogContent;
49
- try {
50
- changelogContent = await readFile(changelogPath, "utf-8");
51
- } catch {
52
- }
53
- if (changelogContent) {
54
- await copyChangelogToPackages(repoRoot, plan.packages, results, changelogContent);
35
+ const scope = input.body?.scope || "root";
36
+ const cwd = ctx.cwd ?? process.cwd();
37
+ const repoRoot = await findRepoRoot(cwd);
38
+ const startTime = Date.now();
39
+ const scopeDir = scopeToDir(scope);
40
+ const planPath = join(repoRoot, ".kb/release/plans", scopeDir, "current", "plan.json");
41
+ let plan;
42
+ try {
43
+ plan = JSON.parse(await readFile(planPath, "utf-8"));
44
+ } catch {
45
+ return { scope, success: false, packages: [], builtCount: 0, totalCount: 0, totalDurationMs: Date.now() - startTime };
46
+ }
47
+ const results = await buildPackages(plan.packages, { logger: ctx.platform?.logger });
48
+ const changelogPath = join(repoRoot, ".kb/release/plans", scopeDir, "current", "changelog.md");
49
+ let changelogContent;
50
+ try {
51
+ changelogContent = await readFile(changelogPath, "utf-8");
52
+ } catch {
53
+ }
54
+ if (changelogContent) {
55
+ await copyChangelogToPackages(repoRoot, plan.packages, results, changelogContent);
56
+ }
57
+ const builtCount = results.filter((r) => r.success).length;
58
+ return {
59
+ scope,
60
+ success: results.every((r) => r.success),
61
+ packages: results.map((r) => ({ name: r.name, success: r.success, error: r.error, durationMs: r.durationMs })),
62
+ builtCount,
63
+ totalCount: plan.packages.length,
64
+ totalDurationMs: Date.now() - startTime
65
+ };
66
+ } catch (err) {
67
+ rethrowForRest(err);
55
68
  }
56
- const builtCount = results.filter((r) => r.success).length;
57
- return {
58
- scope,
59
- success: results.every((r) => r.success),
60
- packages: results.map((r) => ({ name: r.name, success: r.success, error: r.error, durationMs: r.durationMs })),
61
- builtCount,
62
- totalCount: plan.packages.length,
63
- totalDurationMs: Date.now() - startTime
64
- };
65
69
  }
66
70
  });
67
71
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/build-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;ACEA,eAAe,uBAAA,CACb,QAAA,EACA,QAAA,EACA,OAAA,EACA,gBAAA,EACe;AACf,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,IAAI,CAAC,EAAE,OAAA,EAAS;AACd,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAM,QAAA,CAAS,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,EAAE,IAAI,CAAA;AAChD,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA;AAC7E,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,IAAA,CAAK,OAAA,EAAS,cAAc,CAAA,EAAG,kBAAkB,OAAO,CAAA;AACxE,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AACpC,MAAA,IAAI,CAAC,UAAA,CAAW,OAAO,CAAA,EAAG;AACxB,QAAA,MAAM,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,MAC1C;AACA,MAAA,MAAM,UAAU,IAAA,CAAK,OAAA,EAAS,cAAc,CAAA,EAAG,kBAAkB,OAAO,CAAA;AAAA,IAC1E,CAAA,CAAA,MAAQ;AAAA,IAAa;AAAA,EACvB;AACF;AAEA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAiE;AAClF,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,IAAS,MAAA;AACnC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,IAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AACvC,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAG3B,IAAA,MAAM,QAAA,GAAW,WAAW,KAAK,CAAA;AACjC,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA,EAAU,mBAAA,EAAqB,QAAA,EAAU,WAAW,WAAW,CAAA;AAErF,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAO,KAAK,KAAA,CAAM,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,IACrD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,UAAU,EAAC,EAAG,UAAA,EAAY,CAAA,EAAG,YAAY,CAAA,EAAG,eAAA,EAAiB,IAAA,CAAK,GAAA,KAAQ,SAAA,EAAU;AAAA,IACtH;AAGA,IAAA,MAAM,OAAA,GAAU,MAAM,aAAA,CAAc,IAAA,CAAK,QAAA,EAAyC,EAAE,MAAA,EAAQ,GAAA,CAAI,QAAA,EAAU,MAAA,EAAQ,CAAA;AAGlH,IAAA,MAAM,gBAAgB,IAAA,CAAK,QAAA,EAAU,mBAAA,EAAqB,QAAA,EAAU,WAAW,cAAc,CAAA;AAC7F,IAAA,IAAI,gBAAA;AACJ,IAAA,IAAI;AAAE,MAAA,gBAAA,GAAmB,MAAM,QAAA,CAAS,aAAA,EAAe,OAAO,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAa;AAEtF,IAAA,IAAI,gBAAA,EAAkB;AACpB,MAAA,MAAM,uBAAA,CAAwB,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,SAAS,gBAAgB,CAAA;AAAA,IAClF;AAEA,IAAA,MAAM,aAAa,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,MAAA;AAClD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAA,KAAK,EAAE,OAAO,CAAA;AAAA,MACrC,UAAU,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,MAAM,CAAA,CAAE,IAAA,EAAM,OAAA,EAAS,CAAA,CAAE,SAAS,KAAA,EAAO,CAAA,CAAE,OAAO,UAAA,EAAY,CAAA,CAAE,YAAW,CAAE,CAAA;AAAA,MAC3G,UAAA;AAAA,MACA,UAAA,EAAY,KAAK,QAAA,CAAS,MAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,KAChC;AAAA,EACF;AACF,CAAC","file":"build-handler.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 * Build handler — thin adapter over core buildPackages().\n */\n\nimport { defineHandler, findRepoRoot, type RestInput } from '@kb-labs/sdk';\nimport type { BuildRequest, BuildResponse } from '@kb-labs/release-manager-contracts';\nimport { buildPackages, type PackageVersion } from '@kb-labs/release-manager-core';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { scopeToDir } from '../../shared/utils';\nimport { join } from 'node:path';\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nasync function copyChangelogToPackages(\n repoRoot: string,\n packages: Array<{ name: string; path: string }>,\n results: Array<{ name: string; success: boolean }>,\n changelogContent: string,\n): Promise<void> {\n for (const r of results) {\n if (!r.success) {\n break;\n }\n const pkg = packages.find(p => p.name === r.name);\n if (!pkg) {\n continue;\n }\n const pkgPath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n await writeFile(join(pkgPath, 'CHANGELOG.md'), changelogContent, 'utf-8');\n const distDir = join(pkgPath, 'dist');\n if (!existsSync(distDir)) {\n await mkdir(distDir, { recursive: true });\n }\n await writeFile(join(distDir, 'CHANGELOG.md'), changelogContent, 'utf-8');\n } catch { /* skip */ }\n }\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, BuildRequest>): Promise<BuildResponse> {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const startTime = Date.now();\n\n // Read plan\n const scopeDir = scopeToDir(scope);\n const planPath = join(repoRoot, '.kb/release/plans', scopeDir, 'current', 'plan.json');\n\n let plan: { packages: Array<{ name: string; path: string; currentVersion: string; nextVersion: string; bump: unknown }> };\n try {\n plan = JSON.parse(await readFile(planPath, 'utf-8'));\n } catch {\n return { scope, success: false, packages: [], builtCount: 0, totalCount: 0, totalDurationMs: Date.now() - startTime };\n }\n\n // Build via core\n const results = await buildPackages(plan.packages as unknown as PackageVersion[], { logger: ctx.platform?.logger });\n\n // Copy changelog if exists\n const changelogPath = join(repoRoot, '.kb/release/plans', scopeDir, 'current', 'changelog.md');\n let changelogContent: string | undefined;\n try { changelogContent = await readFile(changelogPath, 'utf-8'); } catch { /* skip */ }\n\n if (changelogContent) {\n await copyChangelogToPackages(repoRoot, plan.packages, results, changelogContent);\n }\n\n const builtCount = results.filter(r => r.success).length;\n return {\n scope,\n success: results.every(r => r.success),\n packages: results.map(r => ({ name: r.name, success: r.success, error: r.error, durationMs: r.durationMs })),\n builtCount,\n totalCount: plan.packages.length,\n totalDurationMs: Date.now() - startTime,\n };\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/build-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"build-handler.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 * Build handler — thin adapter over core buildPackages().\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { BuildRequest, BuildResponse } from '@kb-labs/release-manager-contracts';\nimport { buildPackages, type PackageVersion } from '@kb-labs/release-manager-core';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { scopeToDir } from '../../shared/utils';\nimport { join } from 'node:path';\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nasync function copyChangelogToPackages(\n repoRoot: string,\n packages: Array<{ name: string; path: string }>,\n results: Array<{ name: string; success: boolean }>,\n changelogContent: string,\n): Promise<void> {\n for (const r of results) {\n if (!r.success) {\n break;\n }\n const pkg = packages.find(p => p.name === r.name);\n if (!pkg) {\n continue;\n }\n const pkgPath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n await writeFile(join(pkgPath, 'CHANGELOG.md'), changelogContent, 'utf-8');\n const distDir = join(pkgPath, 'dist');\n if (!existsSync(distDir)) {\n await mkdir(distDir, { recursive: true });\n }\n await writeFile(join(distDir, 'CHANGELOG.md'), changelogContent, 'utf-8');\n } catch { /* skip */ }\n }\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, BuildRequest>): Promise<BuildResponse> {\n try {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const startTime = Date.now();\n\n // Read plan\n const scopeDir = scopeToDir(scope);\n const planPath = join(repoRoot, '.kb/release/plans', scopeDir, 'current', 'plan.json');\n\n let plan: { packages: Array<{ name: string; path: string; currentVersion: string; nextVersion: string; bump: unknown }> };\n try {\n plan = JSON.parse(await readFile(planPath, 'utf-8'));\n } catch {\n return { scope, success: false, packages: [], builtCount: 0, totalCount: 0, totalDurationMs: Date.now() - startTime };\n }\n\n // Build via core\n const results = await buildPackages(plan.packages as unknown as PackageVersion[], { logger: ctx.platform?.logger });\n\n // Copy changelog if exists\n const changelogPath = join(repoRoot, '.kb/release/plans', scopeDir, 'current', 'changelog.md');\n let changelogContent: string | undefined;\n try { changelogContent = await readFile(changelogPath, 'utf-8'); } catch { /* skip */ }\n\n if (changelogContent) {\n await copyChangelogToPackages(repoRoot, plan.packages, results, changelogContent);\n }\n\n const builtCount = results.filter(r => r.success).length;\n return {\n scope,\n success: results.every(r => r.success),\n packages: results.map(r => ({ name: r.name, success: r.success, error: r.error, durationMs: r.durationMs })),\n builtCount,\n totalCount: plan.packages.length,\n totalDurationMs: Date.now() - startTime,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { defineHandler, findRepoRoot } from '@kb-labs/sdk';
1
+ import { defineHandler, findRepoRoot, rethrowForRest } from '@kb-labs/sdk';
2
2
  import { generateSimpleChangelog, generateChangelog } from '@kb-labs/release-manager-changelog';
3
3
  import { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';
4
4
 
@@ -6,15 +6,45 @@ import { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';
6
6
 
7
7
  // src/infra/analytics/events.ts
8
8
  var ANALYTICS_PREFIX = {
9
- CHANGELOG: "release.changelog"};
9
+ PLAN: "release.plan",
10
+ RUN: "release.run",
11
+ ROLLBACK: "release.rollback",
12
+ REPORT: "release.report",
13
+ CHANGELOG: "release.changelog",
14
+ PREVIEW: "release.preview",
15
+ VERIFY: "release.verify",
16
+ PUBLISH: "release.publish"
17
+ };
10
18
  var ANALYTICS_SUFFIX = {
11
19
  STARTED: "started",
12
20
  FINISHED: "finished"
13
21
  };
14
22
  var ANALYTICS_EVENTS = {
23
+ // Plan events
24
+ PLAN_STARTED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.STARTED}`,
25
+ PLAN_FINISHED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.FINISHED}`,
26
+ // Run events
27
+ RUN_STARTED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.STARTED}`,
28
+ RUN_FINISHED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.FINISHED}`,
29
+ // Rollback events
30
+ ROLLBACK_STARTED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.STARTED}`,
31
+ ROLLBACK_FINISHED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.FINISHED}`,
32
+ // Report events
33
+ REPORT_STARTED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.STARTED}`,
34
+ REPORT_FINISHED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.FINISHED}`,
15
35
  // Changelog events
16
36
  CHANGELOG_STARTED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.STARTED}`,
17
- CHANGELOG_FINISHED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.FINISHED}`};
37
+ CHANGELOG_FINISHED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.FINISHED}`,
38
+ // Preview events
39
+ PREVIEW_STARTED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.STARTED}`,
40
+ PREVIEW_FINISHED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.FINISHED}`,
41
+ // Verify events
42
+ VERIFY_STARTED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.STARTED}`,
43
+ VERIFY_FINISHED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.FINISHED}`,
44
+ // Publish events
45
+ PUBLISH_STARTED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.STARTED}`,
46
+ PUBLISH_FINISHED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.FINISHED}`
47
+ };
18
48
  var ANALYTICS_ACTOR = {
19
49
  type: "agent",
20
50
  id: "release-cli"
@@ -84,70 +114,74 @@ async function resolveGitCwd(packages, repoRoot) {
84
114
  }
85
115
  var changelog_generate_handler_default = defineHandler({
86
116
  async execute(ctx, input) {
87
- const scope = input.body?.scope || "root";
88
- const cwd = ctx.cwd ?? process.cwd();
89
- const repoRoot = await findRepoRoot(cwd);
90
- const startTime = Date.now();
91
- ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_STARTED, { scope, actor: ANALYTICS_ACTOR });
92
- const scopeDirName = scopeToDir(scope);
93
- const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;
94
- let plan;
95
117
  try {
96
- const planContent = await ctx.runtime.fs.readFile(planPath, "utf-8");
97
- plan = JSON.parse(planContent);
98
- } catch (err) {
99
- ctx.platform?.logger?.error?.(
100
- "Failed to read release plan",
101
- err instanceof Error ? err : void 0,
102
- { scope, planPath }
118
+ const scope = input.body?.scope || "root";
119
+ const cwd = ctx.cwd ?? process.cwd();
120
+ const repoRoot = await findRepoRoot(cwd);
121
+ const startTime = Date.now();
122
+ ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_STARTED, { scope, actor: ANALYTICS_ACTOR });
123
+ const scopeDirName = scopeToDir(scope);
124
+ const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;
125
+ let plan;
126
+ try {
127
+ const planContent = await ctx.runtime.fs.readFile(planPath, "utf-8");
128
+ plan = JSON.parse(planContent);
129
+ } catch (err) {
130
+ ctx.platform?.logger?.error?.(
131
+ "Failed to read release plan",
132
+ err instanceof Error ? err : void 0,
133
+ { scope, planPath }
134
+ );
135
+ throw new Error(`Release plan not found for scope "${scope}". Generate plan first.`);
136
+ }
137
+ const packages = plan.packages.map((pkg) => ({
138
+ name: pkg.name,
139
+ path: pkg.path,
140
+ currentVersion: pkg.currentVersion,
141
+ nextVersion: pkg.nextVersion,
142
+ bump: pkg.bump === "auto" ? "patch" : pkg.bump
143
+ }));
144
+ const gitCwd = await resolveGitCwd(packages, repoRoot);
145
+ const localeRaw = input.body?.locale;
146
+ const locale = localeRaw === "ru" ? "ru" : "en";
147
+ const { markdown, commitsCount, usedLLM } = await resolveMarkdown(
148
+ ctx,
149
+ packages,
150
+ repoRoot,
151
+ gitCwd,
152
+ locale,
153
+ input.body?.useLLM ?? true,
154
+ scope
103
155
  );
104
- throw new Error(`Release plan not found for scope "${scope}". Generate plan first.`);
156
+ const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;
157
+ await ctx.runtime.fs.mkdir(scopeDir, { recursive: true });
158
+ const changelogPath = `${scopeDir}/changelog.md`;
159
+ await ctx.runtime.fs.writeFile(changelogPath, markdown, { encoding: "utf-8" });
160
+ const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;
161
+ await ctx.platform?.cache?.delete(cacheKey);
162
+ const duration = Date.now() - startTime;
163
+ const tokensUsed = 0;
164
+ ctx.platform?.logger?.info?.("Changelog generated", {
165
+ scope,
166
+ path: changelogPath,
167
+ packagesCount: packages.length,
168
+ commitsCount,
169
+ usedLLM,
170
+ durationMs: duration
171
+ });
172
+ ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_FINISHED, {
173
+ scope,
174
+ packagesCount: packages.length,
175
+ commitsCount,
176
+ durationMs: duration,
177
+ tokensUsed,
178
+ usedLLM,
179
+ actor: ANALYTICS_ACTOR
180
+ });
181
+ return { scope, markdown, changelogPath, tokensUsed, usedLLM, commitsCount };
182
+ } catch (err) {
183
+ rethrowForRest(err);
105
184
  }
106
- const packages = plan.packages.map((pkg) => ({
107
- name: pkg.name,
108
- path: pkg.path,
109
- currentVersion: pkg.currentVersion,
110
- nextVersion: pkg.nextVersion,
111
- bump: pkg.bump === "auto" ? "patch" : pkg.bump
112
- }));
113
- const gitCwd = await resolveGitCwd(packages, repoRoot);
114
- const localeRaw = input.body?.locale;
115
- const locale = localeRaw === "ru" ? "ru" : "en";
116
- const { markdown, commitsCount, usedLLM } = await resolveMarkdown(
117
- ctx,
118
- packages,
119
- repoRoot,
120
- gitCwd,
121
- locale,
122
- input.body?.useLLM ?? true,
123
- scope
124
- );
125
- const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;
126
- await ctx.runtime.fs.mkdir(scopeDir, { recursive: true });
127
- const changelogPath = `${scopeDir}/changelog.md`;
128
- await ctx.runtime.fs.writeFile(changelogPath, markdown, { encoding: "utf-8" });
129
- const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;
130
- await ctx.platform?.cache?.delete(cacheKey);
131
- const duration = Date.now() - startTime;
132
- const tokensUsed = 0;
133
- ctx.platform?.logger?.info?.("Changelog generated", {
134
- scope,
135
- path: changelogPath,
136
- packagesCount: packages.length,
137
- commitsCount,
138
- usedLLM,
139
- durationMs: duration
140
- });
141
- ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_FINISHED, {
142
- scope,
143
- packagesCount: packages.length,
144
- commitsCount,
145
- durationMs: duration,
146
- tokensUsed,
147
- usedLLM,
148
- actor: ANALYTICS_ACTOR
149
- });
150
- return { scope, markdown, changelogPath, tokensUsed, usedLLM, commitsCount };
151
185
  }
152
186
  });
153
187
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/infra/analytics/events.ts","../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-generate-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"changelog-generate-handler.js","sourcesContent":["/**\n * Analytics event types for Release CLI\n * Centralized constants to prevent typos and enable type safety\n */\n\n/**\n * Event type prefixes by command\n */\nexport const ANALYTICS_PREFIX = {\n PLAN: 'release.plan',\n RUN: 'release.run',\n ROLLBACK: 'release.rollback',\n REPORT: 'release.report',\n CHANGELOG: 'release.changelog',\n PREVIEW: 'release.preview',\n VERIFY: 'release.verify',\n PUBLISH: 'release.publish',\n} as const;\n\n/**\n * Event lifecycle suffixes\n */\nexport const ANALYTICS_SUFFIX = {\n STARTED: 'started',\n FINISHED: 'finished',\n} as const;\n\n/**\n * Release analytics event types\n */\nexport const ANALYTICS_EVENTS = {\n // Plan events\n PLAN_STARTED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.STARTED}`,\n PLAN_FINISHED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Run events\n RUN_STARTED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.STARTED}`,\n RUN_FINISHED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Rollback events\n ROLLBACK_STARTED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.STARTED}`,\n ROLLBACK_FINISHED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Report events\n REPORT_STARTED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.STARTED}`,\n REPORT_FINISHED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Changelog events\n CHANGELOG_STARTED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.STARTED}`,\n CHANGELOG_FINISHED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Preview events\n PREVIEW_STARTED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.STARTED}`,\n PREVIEW_FINISHED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Verify events\n VERIFY_STARTED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.STARTED}`,\n VERIFY_FINISHED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Publish events\n PUBLISH_STARTED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.STARTED}`,\n PUBLISH_FINISHED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.FINISHED}`,\n} as const;\n\n/**\n * Type helper for analytics event types\n */\nexport type AnalyticsEventType = typeof ANALYTICS_EVENTS[keyof typeof ANALYTICS_EVENTS];\n\n/**\n * Actor configuration for Release analytics\n */\nexport const ANALYTICS_ACTOR = {\n type: 'agent' as const,\n id: 'release-cli',\n} as const;\n\n","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 * Changelog generate handler - Generate changelog using LLM\n *\n * Writes: .kb/release/plans/{scope}/current/changelog.md\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport type {\n GenerateChangelogRequest,\n GenerateChangelogResponse,\n ReleasePlan,\n} from '@kb-labs/release-manager-contracts';\nimport {\n generateChangelog,\n generateSimpleChangelog,\n type ChangelogPackageInfo,\n} from '@kb-labs/release-manager-changelog';\nimport { ANALYTICS_EVENTS, ANALYTICS_ACTOR } from '../../infra/analytics/events';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { scopeToDir } from '../../shared/utils';\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\ninterface GenerateResult {\n markdown: string;\n commitsCount: number;\n usedLLM: boolean;\n}\n\nasync function generateWithLLM(\n ctx: PluginContextV3,\n packages: ChangelogPackageInfo[],\n repoRoot: string,\n gitCwd: string,\n locale: 'en' | 'ru',\n scope: string,\n): Promise<GenerateResult> {\n try {\n ctx.platform?.logger?.info?.('Starting LLM changelog generation', {\n scope,\n packagesCount: packages.length,\n template: 'corporate-ai',\n });\n const result = await generateChangelog({\n repoRoot,\n gitCwd,\n packages,\n range: { from: undefined, to: 'HEAD' },\n changelog: { template: 'corporate-ai', locale },\n platform: {\n llm: ctx.platform.llm,\n logger: ctx.platform.logger,\n analytics: ctx.platform.analytics,\n },\n });\n ctx.platform?.logger?.info?.('LLM changelog generated', {\n scope,\n markdownLength: result.markdown.length,\n linesCount: result.markdown.split('\\n').length,\n commitsCount: result.changes.length,\n });\n return { markdown: result.markdown, commitsCount: result.changes.length, usedLLM: true };\n } catch (err) {\n ctx.platform?.logger?.error?.(\n 'Changelog generation failed, using simple fallback',\n err instanceof Error ? err : undefined,\n { scope, packagesCount: packages.length },\n );\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n}\n\nasync function resolveMarkdown(\n ctx: PluginContextV3,\n packages: ChangelogPackageInfo[],\n repoRoot: string,\n gitCwd: string,\n locale: 'en' | 'ru',\n useLLMFlag: boolean,\n scope: string,\n): Promise<GenerateResult> {\n if (!useLLMFlag) {\n ctx.platform?.logger?.info?.('Using simple changelog (LLM disabled by user)', { scope });\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n const hasLLM = !!ctx.platform?.llm;\n ctx.platform?.logger?.info?.('Changelog generation mode', { scope, useLLM: useLLMFlag, hasLLMPlatform: hasLLM });\n if (!hasLLM) {\n ctx.platform?.logger?.warn?.('LLM service not available, falling back to simple changelog', { scope });\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n return generateWithLLM(ctx, packages, repoRoot, gitCwd, locale, scope);\n}\n\nasync function resolveGitCwd(packages: ChangelogPackageInfo[], repoRoot: string): Promise<string> {\n if (!packages.length || !packages[0]) { return repoRoot; }\n try {\n return await findRepoRoot(packages[0].path);\n } catch {\n return packages[0].path;\n }\n}\n\n// ── handler ────────────────────────────────────────────────────────────────\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, GenerateChangelogRequest>): Promise<GenerateChangelogResponse> {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const startTime = Date.now();\n\n ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_STARTED, { scope, actor: ANALYTICS_ACTOR });\n\n const scopeDirName = scopeToDir(scope);\n const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;\n let plan: ReleasePlan;\n try {\n const planContent = await ctx.runtime.fs.readFile(planPath, 'utf-8');\n plan = JSON.parse(planContent);\n } catch (err) {\n ctx.platform?.logger?.error?.(\n 'Failed to read release plan',\n err instanceof Error ? err : undefined,\n { scope, planPath },\n );\n throw new Error(`Release plan not found for scope \"${scope}\". Generate plan first.`);\n }\n\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\n const gitCwd = await resolveGitCwd(packages, repoRoot);\n\n const localeRaw = input.body?.locale;\n const locale: 'en' | 'ru' = localeRaw === 'ru' ? 'ru' : 'en';\n\n const { markdown, commitsCount, usedLLM } = await resolveMarkdown(\n ctx,\n packages,\n repoRoot,\n gitCwd,\n locale,\n input.body?.useLLM ?? true,\n scope,\n );\n\n const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;\n await ctx.runtime.fs.mkdir(scopeDir, { recursive: true });\n\n const changelogPath = `${scopeDir}/changelog.md`;\n await ctx.runtime.fs.writeFile(changelogPath, markdown, { encoding: 'utf-8' });\n\n const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;\n await ctx.platform?.cache?.delete(cacheKey);\n\n const duration = Date.now() - startTime;\n const tokensUsed = 0;\n\n ctx.platform?.logger?.info?.('Changelog generated', {\n scope, path: changelogPath, packagesCount: packages.length,\n commitsCount, usedLLM, durationMs: duration,\n });\n\n ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_FINISHED, {\n scope, packagesCount: packages.length, commitsCount,\n durationMs: duration, tokensUsed, usedLLM, actor: ANALYTICS_ACTOR,\n });\n\n return { scope, markdown, changelogPath, tokensUsed, usedLLM, commitsCount };\n }\n});\n"]}
1
+ {"version":3,"sources":["../../../src/infra/analytics/events.ts","../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-generate-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"changelog-generate-handler.js","sourcesContent":["/**\n * Analytics event types for Release CLI\n * Centralized constants to prevent typos and enable type safety\n */\n\n/**\n * Event type prefixes by command\n */\nexport const ANALYTICS_PREFIX = {\n PLAN: 'release.plan',\n RUN: 'release.run',\n ROLLBACK: 'release.rollback',\n REPORT: 'release.report',\n CHANGELOG: 'release.changelog',\n PREVIEW: 'release.preview',\n VERIFY: 'release.verify',\n PUBLISH: 'release.publish',\n} as const;\n\n/**\n * Event lifecycle suffixes\n */\nexport const ANALYTICS_SUFFIX = {\n STARTED: 'started',\n FINISHED: 'finished',\n} as const;\n\n/**\n * Release analytics event types\n */\nexport const ANALYTICS_EVENTS = {\n // Plan events\n PLAN_STARTED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.STARTED}`,\n PLAN_FINISHED: `${ANALYTICS_PREFIX.PLAN}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Run events\n RUN_STARTED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.STARTED}`,\n RUN_FINISHED: `${ANALYTICS_PREFIX.RUN}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Rollback events\n ROLLBACK_STARTED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.STARTED}`,\n ROLLBACK_FINISHED: `${ANALYTICS_PREFIX.ROLLBACK}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Report events\n REPORT_STARTED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.STARTED}`,\n REPORT_FINISHED: `${ANALYTICS_PREFIX.REPORT}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Changelog events\n CHANGELOG_STARTED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.STARTED}`,\n CHANGELOG_FINISHED: `${ANALYTICS_PREFIX.CHANGELOG}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Preview events\n PREVIEW_STARTED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.STARTED}`,\n PREVIEW_FINISHED: `${ANALYTICS_PREFIX.PREVIEW}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Verify events\n VERIFY_STARTED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.STARTED}`,\n VERIFY_FINISHED: `${ANALYTICS_PREFIX.VERIFY}.${ANALYTICS_SUFFIX.FINISHED}`,\n\n // Publish events\n PUBLISH_STARTED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.STARTED}`,\n PUBLISH_FINISHED: `${ANALYTICS_PREFIX.PUBLISH}.${ANALYTICS_SUFFIX.FINISHED}`,\n} as const;\n\n/**\n * Type helper for analytics event types\n */\nexport type AnalyticsEventType = typeof ANALYTICS_EVENTS[keyof typeof ANALYTICS_EVENTS];\n\n/**\n * Actor configuration for Release analytics\n */\nexport const ANALYTICS_ACTOR = {\n type: 'agent' as const,\n id: 'release-cli',\n} as const;\n\n","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 * Changelog generate handler - Generate changelog using LLM\n *\n * Writes: .kb/release/plans/{scope}/current/changelog.md\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, type PluginContextV3, rethrowForRest } from '@kb-labs/sdk';\nimport type {\n GenerateChangelogRequest,\n GenerateChangelogResponse,\n ReleasePlan,\n} from '@kb-labs/release-manager-contracts';\nimport {\n generateChangelog,\n generateSimpleChangelog,\n type ChangelogPackageInfo,\n} from '@kb-labs/release-manager-changelog';\nimport { ANALYTICS_EVENTS, ANALYTICS_ACTOR } from '../../infra/analytics/events';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { scopeToDir } from '../../shared/utils';\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\ninterface GenerateResult {\n markdown: string;\n commitsCount: number;\n usedLLM: boolean;\n}\n\nasync function generateWithLLM(\n ctx: PluginContextV3,\n packages: ChangelogPackageInfo[],\n repoRoot: string,\n gitCwd: string,\n locale: 'en' | 'ru',\n scope: string,\n): Promise<GenerateResult> {\n try {\n ctx.platform?.logger?.info?.('Starting LLM changelog generation', {\n scope,\n packagesCount: packages.length,\n template: 'corporate-ai',\n });\n const result = await generateChangelog({\n repoRoot,\n gitCwd,\n packages,\n range: { from: undefined, to: 'HEAD' },\n changelog: { template: 'corporate-ai', locale },\n platform: {\n llm: ctx.platform.llm,\n logger: ctx.platform.logger,\n analytics: ctx.platform.analytics,\n },\n });\n ctx.platform?.logger?.info?.('LLM changelog generated', {\n scope,\n markdownLength: result.markdown.length,\n linesCount: result.markdown.split('\\n').length,\n commitsCount: result.changes.length,\n });\n return { markdown: result.markdown, commitsCount: result.changes.length, usedLLM: true };\n } catch (err) {\n ctx.platform?.logger?.error?.(\n 'Changelog generation failed, using simple fallback',\n err instanceof Error ? err : undefined,\n { scope, packagesCount: packages.length },\n );\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n}\n\nasync function resolveMarkdown(\n ctx: PluginContextV3,\n packages: ChangelogPackageInfo[],\n repoRoot: string,\n gitCwd: string,\n locale: 'en' | 'ru',\n useLLMFlag: boolean,\n scope: string,\n): Promise<GenerateResult> {\n if (!useLLMFlag) {\n ctx.platform?.logger?.info?.('Using simple changelog (LLM disabled by user)', { scope });\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n const hasLLM = !!ctx.platform?.llm;\n ctx.platform?.logger?.info?.('Changelog generation mode', { scope, useLLM: useLLMFlag, hasLLMPlatform: hasLLM });\n if (!hasLLM) {\n ctx.platform?.logger?.warn?.('LLM service not available, falling back to simple changelog', { scope });\n return { markdown: generateSimpleChangelog(packages, 'en'), commitsCount: 0, usedLLM: false };\n }\n return generateWithLLM(ctx, packages, repoRoot, gitCwd, locale, scope);\n}\n\nasync function resolveGitCwd(packages: ChangelogPackageInfo[], repoRoot: string): Promise<string> {\n if (!packages.length || !packages[0]) { return repoRoot; }\n try {\n return await findRepoRoot(packages[0].path);\n } catch {\n return packages[0].path;\n }\n}\n\n// ── handler ────────────────────────────────────────────────────────────────\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, GenerateChangelogRequest>): Promise<GenerateChangelogResponse> {\n try {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const startTime = Date.now();\n\n ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_STARTED, { scope, actor: ANALYTICS_ACTOR });\n\n const scopeDirName = scopeToDir(scope);\n const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;\n let plan: ReleasePlan;\n try {\n const planContent = await ctx.runtime.fs.readFile(planPath, 'utf-8');\n plan = JSON.parse(planContent);\n } catch (err) {\n ctx.platform?.logger?.error?.(\n 'Failed to read release plan',\n err instanceof Error ? err : undefined,\n { scope, planPath },\n );\n throw new Error(`Release plan not found for scope \"${scope}\". Generate plan first.`);\n }\n\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\n const gitCwd = await resolveGitCwd(packages, repoRoot);\n\n const localeRaw = input.body?.locale;\n const locale: 'en' | 'ru' = localeRaw === 'ru' ? 'ru' : 'en';\n\n const { markdown, commitsCount, usedLLM } = await resolveMarkdown(\n ctx,\n packages,\n repoRoot,\n gitCwd,\n locale,\n input.body?.useLLM ?? true,\n scope,\n );\n\n const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;\n await ctx.runtime.fs.mkdir(scopeDir, { recursive: true });\n\n const changelogPath = `${scopeDir}/changelog.md`;\n await ctx.runtime.fs.writeFile(changelogPath, markdown, { encoding: 'utf-8' });\n\n const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;\n await ctx.platform?.cache?.delete(cacheKey);\n\n const duration = Date.now() - startTime;\n const tokensUsed = 0;\n\n ctx.platform?.logger?.info?.('Changelog generated', {\n scope, path: changelogPath, packagesCount: packages.length,\n commitsCount, usedLLM, durationMs: duration,\n });\n\n ctx.platform?.analytics?.track?.(ANALYTICS_EVENTS.CHANGELOG_FINISHED, {\n scope, packagesCount: packages.length, commitsCount,\n durationMs: duration, tokensUsed, usedLLM, actor: ANALYTICS_ACTOR,\n });\n\n return { scope, markdown, changelogPath, tokensUsed, usedLLM, commitsCount };\n } catch (err) {\n rethrowForRest(err);\n }\n }\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { defineHandler, findRepoRoot } from '@kb-labs/sdk';
1
+ import { defineHandler, findRepoRoot, rethrowForRest } from '@kb-labs/sdk';
2
2
  import { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';
3
3
 
4
4
  // src/rest/handlers/changelog-handler.ts
@@ -10,35 +10,39 @@ function scopeToDir(scope) {
10
10
  var CACHE_TTL_MS = 15e3;
11
11
  var changelog_handler_default = defineHandler({
12
12
  async execute(ctx, input) {
13
- const scope = input.query?.scope || "root";
14
- const cwd = ctx.cwd ?? process.cwd();
15
- const repoRoot = await findRepoRoot(cwd);
16
- const scopeDirName = scopeToDir(scope);
17
- const changelogPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/changelog.md`;
18
- const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;
19
- const cached = await ctx.platform?.cache?.get(cacheKey);
20
- if (cached !== void 0 && cached !== null) {
13
+ try {
14
+ const scope = input.query?.scope || "root";
15
+ const cwd = ctx.cwd ?? process.cwd();
16
+ const repoRoot = await findRepoRoot(cwd);
17
+ const scopeDirName = scopeToDir(scope);
18
+ const changelogPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/changelog.md`;
19
+ const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;
20
+ const cached = await ctx.platform?.cache?.get(cacheKey);
21
+ if (cached !== void 0 && cached !== null) {
22
+ return {
23
+ scope,
24
+ markdown: cached,
25
+ from: input.query?.from,
26
+ to: input.query?.to
27
+ };
28
+ }
29
+ let markdown;
30
+ try {
31
+ markdown = await ctx.runtime.fs.readFile(changelogPath, "utf-8");
32
+ if (markdown !== void 0) {
33
+ await ctx.platform?.cache?.set(cacheKey, markdown, CACHE_TTL_MS);
34
+ }
35
+ } catch {
36
+ }
21
37
  return {
22
38
  scope,
23
- markdown: cached,
39
+ markdown,
24
40
  from: input.query?.from,
25
41
  to: input.query?.to
26
42
  };
43
+ } catch (err) {
44
+ rethrowForRest(err);
27
45
  }
28
- let markdown;
29
- try {
30
- markdown = await ctx.runtime.fs.readFile(changelogPath, "utf-8");
31
- if (markdown !== void 0) {
32
- await ctx.platform?.cache?.set(cacheKey, markdown, CACHE_TTL_MS);
33
- }
34
- } catch {
35
- }
36
- return {
37
- scope,
38
- markdown,
39
- from: input.query?.from,
40
- to: input.query?.to
41
- };
42
46
  }
43
47
  });
44
48
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;;;ACAA,IAAM,YAAA,GAAe,IAAA;AAErB,IAAO,4BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA8D;AAC/E,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AACpC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,IAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AAEvC,IAAA,MAAM,YAAA,GAAe,WAAW,KAAK,CAAA;AACrC,IAAA,MAAM,aAAA,GAAgB,CAAA,EAAG,QAAQ,CAAA,mBAAA,EAAsB,YAAY,CAAA,qBAAA,CAAA;AACnE,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,oBAAoB,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA;AAG1D,IAAA,MAAM,SAAS,MAAM,GAAA,CAAI,QAAA,EAAU,KAAA,EAAO,IAAI,QAAQ,CAAA;AACtD,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,IAAA,EAAM;AAC3C,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,QAAA,EAAU,MAAA;AAAA,QACV,IAAA,EAAM,MAAM,KAAA,EAAO,IAAA;AAAA,QACnB,EAAA,EAAI,MAAM,KAAA,EAAO;AAAA,OACnB;AAAA,IACF;AAGA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,CAAG,QAAA,CAAS,eAAe,OAAO,CAAA;AAG/D,MAAA,IAAI,aAAa,KAAA,CAAA,EAAW;AAC1B,QAAA,MAAM,IAAI,QAAA,EAAU,KAAA,EAAO,GAAA,CAAI,QAAA,EAAU,UAAU,YAAY,CAAA;AAAA,MACjE;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,QAAA;AAAA,MACA,IAAA,EAAM,MAAM,KAAA,EAAO,IAAA;AAAA,MACnB,EAAA,EAAI,MAAM,KAAA,EAAO;AAAA,KACnB;AAAA,EACF;AACF,CAAC","file":"changelog-handler.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 * Changelog handler - Get changelog for a scope\n *\n * Reads: .kb/release/plans/{scope}/current/changelog.md\n * Cache: 15s TTL to avoid repeated file reads\n */\n\nimport { defineHandler, findRepoRoot, type RestInput } from '@kb-labs/sdk';\nimport type { ChangelogResponse, ChangelogInput } from '@kb-labs/release-manager-contracts';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { scopeToDir } from '../../shared/utils';\n\nconst CACHE_TTL_MS = 15000; // 15 seconds\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<ChangelogInput>): Promise<ChangelogResponse> {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDirName = scopeToDir(scope);\n const changelogPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/changelog.md`;\n const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;\n\n // Try cache first\n const cached = await ctx.platform?.cache?.get(cacheKey);\n if (cached !== undefined && cached !== null) {\n return {\n scope,\n markdown: cached as string,\n from: input.query?.from,\n to: input.query?.to,\n };\n }\n\n // Cache miss - read from file\n let markdown: string | undefined;\n try {\n markdown = await ctx.runtime.fs.readFile(changelogPath, 'utf-8');\n\n // Cache the result (only if file exists)\n if (markdown !== undefined) {\n await ctx.platform?.cache?.set(cacheKey, markdown, CACHE_TTL_MS);\n }\n } catch {\n // No changelog found - markdown will be undefined\n }\n\n return {\n scope,\n markdown,\n from: input.query?.from,\n to: input.query?.to,\n };\n }\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;;;ACAA,IAAM,YAAA,GAAe,IAAA;AAErB,IAAO,4BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA8D;AAC/E,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AACpC,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AAEvC,MAAA,MAAM,YAAA,GAAe,WAAW,KAAK,CAAA;AACrC,MAAA,MAAM,aAAA,GAAgB,CAAA,EAAG,QAAQ,CAAA,mBAAA,EAAsB,YAAY,CAAA,qBAAA,CAAA;AACnE,MAAA,MAAM,QAAA,GAAW,CAAA,EAAG,oBAAoB,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA;AAG1D,MAAA,MAAM,SAAS,MAAM,GAAA,CAAI,QAAA,EAAU,KAAA,EAAO,IAAI,QAAQ,CAAA;AACtD,MAAA,IAAI,MAAA,KAAW,KAAA,CAAA,IAAa,MAAA,KAAW,IAAA,EAAM;AAC3C,QAAA,OAAO;AAAA,UACL,KAAA;AAAA,UACA,QAAA,EAAU,MAAA;AAAA,UACV,IAAA,EAAM,MAAM,KAAA,EAAO,IAAA;AAAA,UACnB,EAAA,EAAI,MAAM,KAAA,EAAO;AAAA,SACnB;AAAA,MACF;AAGA,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI;AACF,QAAA,QAAA,GAAW,MAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,CAAG,QAAA,CAAS,eAAe,OAAO,CAAA;AAG/D,QAAA,IAAI,aAAa,KAAA,CAAA,EAAW;AAC1B,UAAA,MAAM,IAAI,QAAA,EAAU,KAAA,EAAO,GAAA,CAAI,QAAA,EAAU,UAAU,YAAY,CAAA;AAAA,QACjE;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA,EAAM,MAAM,KAAA,EAAO,IAAA;AAAA,QACnB,EAAA,EAAI,MAAM,KAAA,EAAO;AAAA,OACnB;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"changelog-handler.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 * Changelog handler - Get changelog for a scope\n *\n * Reads: .kb/release/plans/{scope}/current/changelog.md\n * Cache: 15s TTL to avoid repeated file reads\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { ChangelogResponse, ChangelogInput } from '@kb-labs/release-manager-contracts';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { scopeToDir } from '../../shared/utils';\n\nconst CACHE_TTL_MS = 15000; // 15 seconds\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<ChangelogInput>): Promise<ChangelogResponse> {\n try {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDirName = scopeToDir(scope);\n const changelogPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/changelog.md`;\n const cacheKey = `${RELEASE_CACHE_PREFIX}changelog:${scope}`;\n\n // Try cache first\n const cached = await ctx.platform?.cache?.get(cacheKey);\n if (cached !== undefined && cached !== null) {\n return {\n scope,\n markdown: cached as string,\n from: input.query?.from,\n to: input.query?.to,\n };\n }\n\n // Cache miss - read from file\n let markdown: string | undefined;\n try {\n markdown = await ctx.runtime.fs.readFile(changelogPath, 'utf-8');\n\n // Cache the result (only if file exists)\n if (markdown !== undefined) {\n await ctx.platform?.cache?.set(cacheKey, markdown, CACHE_TTL_MS);\n }\n } catch {\n // No changelog found - markdown will be undefined\n }\n\n return {\n scope,\n markdown,\n from: input.query?.from,\n to: input.query?.to,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n }\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { defineHandler, findRepoRoot } from '@kb-labs/sdk';
1
+ import { defineHandler, findRepoRoot, rethrowForRest } from '@kb-labs/sdk';
2
2
  import { mkdir } from 'fs/promises';
3
3
 
4
4
  // src/rest/handlers/changelog-save-handler.ts
@@ -30,7 +30,7 @@ var changelog_save_handler_default = defineHandler({
30
30
  error instanceof Error ? error : void 0,
31
31
  { scope }
32
32
  );
33
- throw new Error(`Failed to save changelog: ${error instanceof Error ? error.message : String(error)}`);
33
+ rethrowForRest(error);
34
34
  }
35
35
  }
36
36
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-save-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;;;ACEA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAiF;AAClG,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,IAAS,MAAA;AACnC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,IAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AAEvC,IAAA,MAAM,YAAA,GAAe,WAAW,KAAK,CAAA;AACrC,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,QAAQ,CAAA,mBAAA,EAAsB,YAAY,CAAA,QAAA,CAAA;AAC9D,IAAA,MAAM,aAAA,GAAgB,GAAG,QAAQ,CAAA,aAAA,CAAA;AAEjC,IAAA,IAAI;AAEF,MAAA,MAAM,KAAA,CAAM,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAGzC,MAAA,MAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,CAAG,SAAA,CAAU,aAAA,EAAe,KAAA,CAAM,IAAA,EAAM,QAAA,IAAY,EAAA,EAAI,EAAE,QAAA,EAAU,OAAA,EAAS,CAAA;AAE/F,MAAA,GAAA,CAAI,QAAA,EAAU,QAAQ,IAAA,GAAO,iBAAA,EAAmB,EAAE,KAAA,EAAO,IAAA,EAAM,eAAe,CAAA;AAE9E,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,KAAA;AAAA,QACA,IAAA,EAAM;AAAA,OACR;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,GAAA,CAAI,UAAU,MAAA,EAAQ,KAAA;AAAA,QACpB,0BAAA;AAAA,QACA,KAAA,YAAiB,QAAQ,KAAA,GAAQ,MAAA;AAAA,QACjC,EAAE,KAAA;AAAM,OACV;AAEA,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IACvG;AAAA,EACF;AACF,CAAC","file":"changelog-save-handler.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 * Changelog save handler - Save edited changelog for a scope\n *\n * Writes to: .kb/release/plans/{scope}/current/changelog.md\n */\n\nimport { defineHandler, findRepoRoot, type RestInput } from '@kb-labs/sdk';\nimport type {\n SaveChangelogRequest,\n SaveChangelogResponse,\n} from '@kb-labs/release-manager-contracts';\nimport { mkdir } from 'node:fs/promises';\nimport { scopeToDir } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, SaveChangelogRequest>): Promise<SaveChangelogResponse> {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDirName = scopeToDir(scope);\n const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;\n const changelogPath = `${scopeDir}/changelog.md`;\n\n try {\n // Ensure directory exists\n await mkdir(scopeDir, { recursive: true });\n\n // Write changelog\n await ctx.runtime.fs.writeFile(changelogPath, input.body?.markdown || '', { encoding: 'utf-8' });\n\n ctx.platform?.logger?.info?.('Changelog saved', { scope, path: changelogPath });\n\n return {\n success: true,\n scope,\n path: changelogPath,\n };\n } catch (error) {\n ctx.platform?.logger?.error?.(\n 'Failed to save changelog',\n error instanceof Error ? error : undefined,\n { scope }\n );\n\n throw new Error(`Failed to save changelog: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/changelog-save-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;;;ACEA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAiF;AAClG,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,IAAS,MAAA;AACnC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,IAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AAEvC,IAAA,MAAM,YAAA,GAAe,WAAW,KAAK,CAAA;AACrC,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,QAAQ,CAAA,mBAAA,EAAsB,YAAY,CAAA,QAAA,CAAA;AAC9D,IAAA,MAAM,aAAA,GAAgB,GAAG,QAAQ,CAAA,aAAA,CAAA;AAEjC,IAAA,IAAI;AAEF,MAAA,MAAM,KAAA,CAAM,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAGzC,MAAA,MAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,CAAG,SAAA,CAAU,aAAA,EAAe,KAAA,CAAM,IAAA,EAAM,QAAA,IAAY,EAAA,EAAI,EAAE,QAAA,EAAU,OAAA,EAAS,CAAA;AAE/F,MAAA,GAAA,CAAI,QAAA,EAAU,QAAQ,IAAA,GAAO,iBAAA,EAAmB,EAAE,KAAA,EAAO,IAAA,EAAM,eAAe,CAAA;AAE9E,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,KAAA;AAAA,QACA,IAAA,EAAM;AAAA,OACR;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,GAAA,CAAI,UAAU,MAAA,EAAQ,KAAA;AAAA,QACpB,0BAAA;AAAA,QACA,KAAA,YAAiB,QAAQ,KAAA,GAAQ,MAAA;AAAA,QACjC,EAAE,KAAA;AAAM,OACV;AAEA,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"changelog-save-handler.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 * Changelog save handler - Save edited changelog for a scope\n *\n * Writes to: .kb/release/plans/{scope}/current/changelog.md\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type {\n SaveChangelogRequest,\n SaveChangelogResponse,\n} from '@kb-labs/release-manager-contracts';\nimport { mkdir } from 'node:fs/promises';\nimport { scopeToDir } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, SaveChangelogRequest>): Promise<SaveChangelogResponse> {\n const scope = input.body?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDirName = scopeToDir(scope);\n const scopeDir = `${repoRoot}/.kb/release/plans/${scopeDirName}/current`;\n const changelogPath = `${scopeDir}/changelog.md`;\n\n try {\n // Ensure directory exists\n await mkdir(scopeDir, { recursive: true });\n\n // Write changelog\n await ctx.runtime.fs.writeFile(changelogPath, input.body?.markdown || '', { encoding: 'utf-8' });\n\n ctx.platform?.logger?.info?.('Changelog saved', { scope, path: changelogPath });\n\n return {\n success: true,\n scope,\n path: changelogPath,\n };\n } catch (error) {\n ctx.platform?.logger?.error?.(\n 'Failed to save changelog',\n error instanceof Error ? error : undefined,\n { scope }\n );\n\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { defineHandler, findRepoRoot, useEnv } from '@kb-labs/sdk';
1
+ import { defineHandler, findRepoRoot, useEnv, rethrowForRest } from '@kb-labs/sdk';
2
2
  import { readFile, access, readdir, stat } from 'fs/promises';
3
3
  import { join } from 'path';
4
4
 
@@ -117,50 +117,54 @@ async function checkPreviewStatus(plan, repoRoot, buildStatus) {
117
117
  }
118
118
  var checklist_handler_default = defineHandler({
119
119
  async execute(ctx, input) {
120
- const scope = input.query?.scope || "root";
121
- const cwd = ctx.cwd ?? process.cwd();
122
- const repoRoot = await findRepoRoot(cwd);
123
- const scopeDir = scopeToDir(scope);
124
- const basePath = join(repoRoot, ".kb/release/plans", scopeDir, "current");
125
- const { planStatus, planMessage, packagesCount, bump, plan } = await checkPlanStatus(basePath);
126
- const { changelogStatus, changelogMessage, commitsCount } = await checkChangelogStatus(basePath, planStatus);
127
- const { buildStatus, buildMessage, builtCount, totalCount } = await checkBuildStatus(plan, repoRoot);
128
- const { previewStatus, previewMessage, filesCount, totalSize } = await checkPreviewStatus(plan, repoRoot, buildStatus);
129
- const hasNpmToken = !!(useEnv("NPM_TOKEN") ?? useEnv("NODE_AUTH_TOKEN"));
130
- const npmStatus = hasNpmToken ? "ready" : "error";
131
- const npmMessage = hasNpmToken ? "npm token configured" : "Set NPM_TOKEN (granular access token) in environment";
132
- const canPublish = planStatus === "ready" && changelogStatus === "ready" && buildStatus === "ready" && previewStatus === "ready" && npmStatus === "ready";
133
- return {
134
- scope,
135
- plan: {
136
- status: planStatus,
137
- message: planMessage,
138
- packagesCount: packagesCount > 0 ? packagesCount : void 0,
139
- bump
140
- },
141
- changelog: {
142
- status: changelogStatus,
143
- message: changelogMessage,
144
- commitsCount
145
- },
146
- build: {
147
- status: buildStatus,
148
- message: buildMessage,
149
- builtCount: builtCount > 0 ? builtCount : void 0,
150
- totalCount: totalCount > 0 ? totalCount : void 0
151
- },
152
- preview: {
153
- status: previewStatus,
154
- message: previewMessage,
155
- filesCount,
156
- totalSize
157
- },
158
- npm: {
159
- status: npmStatus,
160
- message: npmMessage
161
- },
162
- canPublish
163
- };
120
+ try {
121
+ const scope = input.query?.scope || "root";
122
+ const cwd = ctx.cwd ?? process.cwd();
123
+ const repoRoot = await findRepoRoot(cwd);
124
+ const scopeDir = scopeToDir(scope);
125
+ const basePath = join(repoRoot, ".kb/release/plans", scopeDir, "current");
126
+ const { planStatus, planMessage, packagesCount, bump, plan } = await checkPlanStatus(basePath);
127
+ const { changelogStatus, changelogMessage, commitsCount } = await checkChangelogStatus(basePath, planStatus);
128
+ const { buildStatus, buildMessage, builtCount, totalCount } = await checkBuildStatus(plan, repoRoot);
129
+ const { previewStatus, previewMessage, filesCount, totalSize } = await checkPreviewStatus(plan, repoRoot, buildStatus);
130
+ const hasNpmToken = !!(useEnv("NPM_TOKEN") ?? useEnv("NODE_AUTH_TOKEN"));
131
+ const npmStatus = hasNpmToken ? "ready" : "error";
132
+ const npmMessage = hasNpmToken ? "npm token configured" : "Set NPM_TOKEN (granular access token) in environment";
133
+ const canPublish = planStatus === "ready" && changelogStatus === "ready" && buildStatus === "ready" && previewStatus === "ready" && npmStatus === "ready";
134
+ return {
135
+ scope,
136
+ plan: {
137
+ status: planStatus,
138
+ message: planMessage,
139
+ packagesCount: packagesCount > 0 ? packagesCount : void 0,
140
+ bump
141
+ },
142
+ changelog: {
143
+ status: changelogStatus,
144
+ message: changelogMessage,
145
+ commitsCount
146
+ },
147
+ build: {
148
+ status: buildStatus,
149
+ message: buildMessage,
150
+ builtCount: builtCount > 0 ? builtCount : void 0,
151
+ totalCount: totalCount > 0 ? totalCount : void 0
152
+ },
153
+ preview: {
154
+ status: previewStatus,
155
+ message: previewMessage,
156
+ filesCount,
157
+ totalSize
158
+ },
159
+ npm: {
160
+ status: npmStatus,
161
+ message: npmMessage
162
+ },
163
+ canPublish
164
+ };
165
+ } catch (err) {
166
+ rethrowForRest(err);
167
+ }
164
168
  }
165
169
  });
166
170