@kb-labs/release-manager-cli 0.5.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 (133) hide show
  1. package/README.md +211 -0
  2. package/dist/cli/commands/changelog.d.ts +17 -0
  3. package/dist/cli/commands/changelog.js +156 -0
  4. package/dist/cli/commands/changelog.js.map +1 -0
  5. package/dist/cli/commands/plan.d.ts +12 -0
  6. package/dist/cli/commands/plan.js +117 -0
  7. package/dist/cli/commands/plan.js.map +1 -0
  8. package/dist/cli/commands/publish.d.ts +15 -0
  9. package/dist/cli/commands/publish.js +486 -0
  10. package/dist/cli/commands/publish.js.map +1 -0
  11. package/dist/cli/commands/report.d.ts +9 -0
  12. package/dist/cli/commands/report.js +77 -0
  13. package/dist/cli/commands/report.js.map +1 -0
  14. package/dist/cli/commands/rollback.d.ts +9 -0
  15. package/dist/cli/commands/rollback.js +42 -0
  16. package/dist/cli/commands/rollback.js.map +1 -0
  17. package/dist/cli/commands/run.d.ts +16 -0
  18. package/dist/cli/commands/run.js +539 -0
  19. package/dist/cli/commands/run.js.map +1 -0
  20. package/dist/cli/commands/verify.d.ts +14 -0
  21. package/dist/cli/commands/verify.js +106 -0
  22. package/dist/cli/commands/verify.js.map +1 -0
  23. package/dist/contracts/release.schema.d.ts +503 -0
  24. package/dist/contracts/release.schema.js +45 -0
  25. package/dist/contracts/release.schema.js.map +1 -0
  26. package/dist/index.d.ts +76 -0
  27. package/dist/index.js +689 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/manifest.d.ts +292 -0
  30. package/dist/manifest.js +604 -0
  31. package/dist/manifest.js.map +1 -0
  32. package/dist/rest/handlers/build-handler.d.ts +20 -0
  33. package/dist/rest/handlers/build-handler.js +68 -0
  34. package/dist/rest/handlers/build-handler.js.map +1 -0
  35. package/dist/rest/handlers/changelog-generate-handler.d.ts +20 -0
  36. package/dist/rest/handlers/changelog-generate-handler.js +169 -0
  37. package/dist/rest/handlers/changelog-generate-handler.js.map +1 -0
  38. package/dist/rest/handlers/changelog-handler.d.ts +16 -0
  39. package/dist/rest/handlers/changelog-handler.js +50 -0
  40. package/dist/rest/handlers/changelog-handler.js.map +1 -0
  41. package/dist/rest/handlers/changelog-save-handler.d.ts +13 -0
  42. package/dist/rest/handlers/changelog-save-handler.js +42 -0
  43. package/dist/rest/handlers/changelog-save-handler.js.map +1 -0
  44. package/dist/rest/handlers/checklist-handler.d.ts +39 -0
  45. package/dist/rest/handlers/checklist-handler.js +155 -0
  46. package/dist/rest/handlers/checklist-handler.js.map +1 -0
  47. package/dist/rest/handlers/generate-handler.d.ts +35 -0
  48. package/dist/rest/handlers/generate-handler.js +206 -0
  49. package/dist/rest/handlers/generate-handler.js.map +1 -0
  50. package/dist/rest/handlers/get-checks-handler.d.ts +15 -0
  51. package/dist/rest/handlers/get-checks-handler.js +22 -0
  52. package/dist/rest/handlers/get-checks-handler.js.map +1 -0
  53. package/dist/rest/handlers/git-timeline-handler.d.ts +26 -0
  54. package/dist/rest/handlers/git-timeline-handler.js +209 -0
  55. package/dist/rest/handlers/git-timeline-handler.js.map +1 -0
  56. package/dist/rest/handlers/history-changelog-handler.d.ts +14 -0
  57. package/dist/rest/handlers/history-changelog-handler.js +34 -0
  58. package/dist/rest/handlers/history-changelog-handler.js.map +1 -0
  59. package/dist/rest/handlers/history-handler.d.ts +20 -0
  60. package/dist/rest/handlers/history-handler.js +75 -0
  61. package/dist/rest/handlers/history-handler.js.map +1 -0
  62. package/dist/rest/handlers/history-plan-handler.d.ts +30 -0
  63. package/dist/rest/handlers/history-plan-handler.js +34 -0
  64. package/dist/rest/handlers/history-plan-handler.js.map +1 -0
  65. package/dist/rest/handlers/history-report-handler.d.ts +64 -0
  66. package/dist/rest/handlers/history-report-handler.js +34 -0
  67. package/dist/rest/handlers/history-report-handler.js.map +1 -0
  68. package/dist/rest/handlers/plan-handler.d.ts +29 -0
  69. package/dist/rest/handlers/plan-handler.js +75 -0
  70. package/dist/rest/handlers/plan-handler.js.map +1 -0
  71. package/dist/rest/handlers/preview-handler.d.ts +26 -0
  72. package/dist/rest/handlers/preview-handler.js +127 -0
  73. package/dist/rest/handlers/preview-handler.js.map +1 -0
  74. package/dist/rest/handlers/report-handler.d.ts +65 -0
  75. package/dist/rest/handlers/report-handler.js +48 -0
  76. package/dist/rest/handlers/report-handler.js.map +1 -0
  77. package/dist/rest/handlers/reset-handler.d.ts +12 -0
  78. package/dist/rest/handlers/reset-handler.js +38 -0
  79. package/dist/rest/handlers/reset-handler.js.map +1 -0
  80. package/dist/rest/handlers/run-checks-handler.d.ts +20 -0
  81. package/dist/rest/handlers/run-checks-handler.js +58 -0
  82. package/dist/rest/handlers/run-checks-handler.js.map +1 -0
  83. package/dist/rest/handlers/run-handler.d.ts +68 -0
  84. package/dist/rest/handlers/run-handler.js +274 -0
  85. package/dist/rest/handlers/run-handler.js.map +1 -0
  86. package/dist/rest/handlers/scopes-handler.d.ts +20 -0
  87. package/dist/rest/handlers/scopes-handler.js +63 -0
  88. package/dist/rest/handlers/scopes-handler.js.map +1 -0
  89. package/dist/rest/handlers/status-handler.d.ts +24 -0
  90. package/dist/rest/handlers/status-handler.js +120 -0
  91. package/dist/rest/handlers/status-handler.js.map +1 -0
  92. package/dist/setup/handler.d.ts +19 -0
  93. package/dist/setup/handler.js +103 -0
  94. package/dist/setup/handler.js.map +1 -0
  95. package/dist/widgets/220.js +446 -0
  96. package/dist/widgets/220.js.map +1 -0
  97. package/dist/widgets/331.js +2 -0
  98. package/dist/widgets/331.js.map +1 -0
  99. package/dist/widgets/403.js +2 -0
  100. package/dist/widgets/403.js.map +1 -0
  101. package/dist/widgets/406.js +35 -0
  102. package/dist/widgets/406.js.map +1 -0
  103. package/dist/widgets/455.js +2 -0
  104. package/dist/widgets/455.js.map +1 -0
  105. package/dist/widgets/482.js +2 -0
  106. package/dist/widgets/482.js.map +1 -0
  107. package/dist/widgets/485.js +2 -0
  108. package/dist/widgets/485.js.map +1 -0
  109. package/dist/widgets/527.js +2 -0
  110. package/dist/widgets/527.js.map +1 -0
  111. package/dist/widgets/628.js +2 -0
  112. package/dist/widgets/628.js.map +1 -0
  113. package/dist/widgets/694.js +2 -0
  114. package/dist/widgets/694.js.map +1 -0
  115. package/dist/widgets/712.js +2 -0
  116. package/dist/widgets/712.js.map +1 -0
  117. package/dist/widgets/866.js +2 -0
  118. package/dist/widgets/866.js.map +1 -0
  119. package/dist/widgets/915.js +39 -0
  120. package/dist/widgets/915.js.map +1 -0
  121. package/dist/widgets/957.js +10 -0
  122. package/dist/widgets/957.js.map +1 -0
  123. package/dist/widgets/983.js +2 -0
  124. package/dist/widgets/983.js.map +1 -0
  125. package/dist/widgets/@mf-types.d.ts +3 -0
  126. package/dist/widgets/@mf-types.zip +0 -0
  127. package/dist/widgets/__federation_expose_ReleasePage.js +2 -0
  128. package/dist/widgets/__federation_expose_ReleasePage.js.map +1 -0
  129. package/dist/widgets/mf-manifest.json +260 -0
  130. package/dist/widgets/mf-stats.json +302 -0
  131. package/dist/widgets/remoteEntry.js +7 -0
  132. package/dist/widgets/remoteEntry.js.map +1 -0
  133. package/package.json +81 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/report.ts"],"names":["join","readFile"],"mappings":"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","file":"report.js","sourcesContent":["/**\n * Release report command\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { defineCommand, type CLIInput, type CommandResult, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { ReleaseReport } from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface ReportFlags {\n json?: boolean;\n}\n\ntype ReleaseReportResult = CommandResult & {\n report?: ReleaseReport;\n};\n\nexport default defineCommand({\n id: 'release:report',\n description: 'Show last release report',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<ReportFlags>): Promise<ReleaseReportResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const reportPath = join(repoRoot, '.kb', 'release', 'report.json');\n\n try {\n const reportContent = await readFile(reportPath, 'utf-8');\n const report = JSON.parse(reportContent) as ReleaseReport;\n\n // Platform services with optional chaining\n ctx.platform?.logger?.info?.('Release report completed', {\n stage: report.stage,\n ok: report.result.ok,\n });\n\n if (flags.json) {\n ctx.ui?.json?.(report);\n } else {\n if (!ctx.ui) {\n throw new Error('UI not available');\n }\n\n const sections: Array<{ header?: string; items: string[] }> = [\n {\n header: 'Summary',\n items: [\n `Timestamp: ${report.ts}`,\n `Stage: ${report.stage}`,\n `Result: ${report.result.ok ? 'SUCCESS' : 'FAILED'}`,\n ],\n },\n ];\n\n if (report.result.errors && report.result.errors.length > 0) {\n const errorItems: string[] = [];\n for (const error of report.result.errors) {\n errorItems.push(error);\n }\n sections.push({\n header: 'Errors',\n items: errorItems,\n });\n }\n\n const status = report.result.ok ? 'success' : 'error';\n ctx.ui.sideBox({\n title: 'Release Report',\n sections,\n status,\n });\n }\n\n return { exitCode: report.result.ok ? 0 : 1, report };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // Platform services with optional chaining\n ctx.platform?.logger?.warn?.('No release report found');\n\n if (flags.json) {\n ctx.ui?.json?.({ exitCode: 3, meta: { error: 'No release report found' } });\n } else {\n ctx.ui?.error?.(new Error('No release report found. Run \"kb release run\" first.'));\n }\n // Return exit code 3 for misconfiguration\n return { exitCode: 3, meta: { error: 'No release report found' } };\n }\n throw error;\n }\n },\n },\n});\n"]}
@@ -0,0 +1,9 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ interface RollbackFlags {
5
+ json?: boolean;
6
+ }
7
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<RollbackFlags>, unknown>;
8
+
9
+ export { _default as default };
@@ -0,0 +1,42 @@
1
+ import { defineCommand, findRepoRoot } from '@kb-labs/sdk';
2
+ import { restoreSnapshot } from '@kb-labs/release-manager-core';
3
+ import 'path';
4
+ import 'fs/promises';
5
+ import 'globby';
6
+
7
+ // src/cli/commands/rollback.ts
8
+
9
+ // src/cli/commands/rollback.ts
10
+ var rollback_default = defineCommand({
11
+ id: "release:rollback",
12
+ description: "Rollback last release",
13
+ handler: {
14
+ async execute(ctx, input) {
15
+ const { flags } = input;
16
+ const cwd = ctx.cwd || process.cwd();
17
+ const repoRoot = await findRepoRoot(cwd);
18
+ await restoreSnapshot(repoRoot);
19
+ ctx.platform?.logger?.info?.("Release rollback completed");
20
+ if (flags.json) {
21
+ ctx.ui?.json?.({ exitCode: 4, message: "Rollback completed" });
22
+ } else {
23
+ ctx.ui.sideBox({
24
+ title: "Rollback",
25
+ sections: [
26
+ {
27
+ items: [
28
+ `${ctx.ui.symbols.success} ${ctx.ui.colors.success("Release state restored from backup snapshot")}`
29
+ ]
30
+ }
31
+ ],
32
+ status: "success"
33
+ });
34
+ }
35
+ return { exitCode: 4, message: "Rollback completed" };
36
+ }
37
+ }
38
+ });
39
+
40
+ export { rollback_default as default };
41
+ //# sourceMappingURL=rollback.js.map
42
+ //# sourceMappingURL=rollback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/rollback.ts"],"names":[],"mappings":";;;;;;;;;AAgBA,IAAO,mBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,kBAAA;AAAA,EACJ,WAAA,EAAa,uBAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAgE;AAClG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,GAAG,CAAA;AAEvC,MAAA,MAAM,gBAAgB,QAAQ,CAAA;AAE9B,MAAA,GAAA,CAAI,QAAA,EAAU,MAAA,EAAQ,IAAA,GAAO,4BAA4B,CAAA;AAEzD,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,IAAI,IAAA,GAAO,EAAE,UAAU,CAAA,EAAG,OAAA,EAAS,sBAAsB,CAAA;AAAA,MAC/D,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,GAAG,OAAA,CAAQ;AAAA,UACb,KAAA,EAAO,UAAA;AAAA,UACP,QAAA,EAAU;AAAA,YACR;AAAA,cACE,KAAA,EAAO;AAAA,gBACL,CAAA,EAAG,GAAA,CAAI,EAAA,CAAG,OAAA,CAAQ,OAAO,CAAA,CAAA,EAAI,GAAA,CAAI,EAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,6CAA6C,CAAC,CAAA;AAAA;AACnG;AACF,WACF;AAAA,UACA,MAAA,EAAQ;AAAA,SACT,CAAA;AAAA,MACH;AAGA,MAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,OAAA,EAAS,oBAAA,EAAqB;AAAA,IACtD;AAAA;AAEJ,CAAC","file":"rollback.js","sourcesContent":["/**\n * Release rollback command\n */\n\nimport { defineCommand, type CLIInput, type CommandResult, type PluginContextV3 } from '@kb-labs/sdk';\nimport { restoreSnapshot } from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\n\ninterface RollbackFlags {\n json?: boolean;\n}\n\ntype ReleaseRollbackResult = CommandResult & {\n message?: string;\n};\n\nexport default defineCommand({\n id: 'release:rollback',\n description: 'Rollback last release',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<RollbackFlags>): Promise<ReleaseRollbackResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n await restoreSnapshot(repoRoot);\n\n ctx.platform?.logger?.info?.('Release rollback completed');\n\n if (flags.json) {\n ctx.ui?.json?.({ exitCode: 4, message: 'Rollback completed' });\n } else {\n ctx.ui.sideBox({\n title: 'Rollback',\n sections: [\n {\n items: [\n `${ctx.ui.symbols.success} ${ctx.ui.colors.success('Release state restored from backup snapshot')}`,\n ],\n },\n ],\n status: 'success',\n });\n }\n\n // Return exit code 4 for rollback executed\n return { exitCode: 4, message: 'Rollback completed' };\n },\n },\n});\n"]}
@@ -0,0 +1,16 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ interface RunFlags {
5
+ scope?: string;
6
+ bump?: 'patch' | 'minor' | 'major' | 'auto';
7
+ strict?: boolean;
8
+ 'dry-run'?: boolean;
9
+ 'skip-checks'?: boolean;
10
+ 'skip-build'?: boolean;
11
+ 'skip-verify'?: boolean;
12
+ json?: boolean;
13
+ }
14
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<RunFlags>, unknown>;
15
+
16
+ export { _default as default };
@@ -0,0 +1,539 @@
1
+ import { defineCommand, findRepoRoot, useLoader, useConfig, useLLM, useLogger } from '@kb-labs/sdk';
2
+ import { resolveScopePath, runReleasePipeline } from '@kb-labs/release-manager-core';
3
+ import { join } from 'path';
4
+ import 'fs/promises';
5
+ import 'globby';
6
+ import { generateChangelog, generateSimpleChangelog } from '@kb-labs/release-manager-changelog';
7
+ import { spawn } from 'child_process';
8
+ import { readFileSync, readdirSync, writeFileSync } from 'fs';
9
+ import * as readline from 'readline/promises';
10
+
11
+ // src/cli/commands/run.ts
12
+ function createChangelogGenerator(config, llm) {
13
+ return {
14
+ async generate(plan, opts) {
15
+ const locale = config.changelog?.locale || "en";
16
+ const packages = plan.packages.map((pkg) => ({
17
+ name: pkg.name,
18
+ path: pkg.path,
19
+ currentVersion: pkg.currentVersion,
20
+ nextVersion: pkg.nextVersion,
21
+ bump: pkg.bump === "auto" ? "patch" : pkg.bump
22
+ }));
23
+ try {
24
+ const result = await generateChangelog({
25
+ repoRoot: opts.repoRoot,
26
+ gitCwd: opts.gitCwd,
27
+ packages,
28
+ range: { to: "HEAD" },
29
+ changelog: {
30
+ template: config.changelog?.template ?? void 0,
31
+ locale,
32
+ metadata: config.changelog?.metadata,
33
+ ignoreAuthors: config.changelog?.ignoreAuthors,
34
+ includeTypes: config.changelog?.includeTypes,
35
+ excludeTypes: config.changelog?.excludeTypes,
36
+ collapseMerges: config.changelog?.collapseMerges,
37
+ collapseReverts: config.changelog?.collapseReverts,
38
+ preferMergeSummary: config.changelog?.preferMergeSummary
39
+ },
40
+ git: {
41
+ autoUnshallow: config.git?.autoUnshallow,
42
+ requireSignedTags: config.git?.requireSignedTags,
43
+ baseUrl: config.git?.baseUrl ?? void 0
44
+ },
45
+ platform: llm ? { llm } : void 0
46
+ });
47
+ return result.markdown;
48
+ } catch {
49
+ return generateSimpleChangelog(packages, locale);
50
+ }
51
+ }
52
+ };
53
+ }
54
+ function resolveToken(token) {
55
+ return token ?? process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
56
+ }
57
+ function publishSinglePackage(options) {
58
+ const { packagePath, token, otp, dryRun, tag, access, registry } = options;
59
+ return new Promise((resolve, reject) => {
60
+ const args = ["publish"];
61
+ if (dryRun) {
62
+ args.push("--dry-run");
63
+ }
64
+ if (tag) {
65
+ args.push(`--tag=${tag}`);
66
+ }
67
+ if (access) {
68
+ args.push(`--access=${access}`);
69
+ }
70
+ if (registry) {
71
+ args.push(`--registry=${registry}`);
72
+ }
73
+ if (otp) {
74
+ args.push(`--otp=${otp}`);
75
+ }
76
+ const env = { ...process.env };
77
+ if (token) {
78
+ env["NODE_AUTH_TOKEN"] = token;
79
+ }
80
+ const child = spawn("npm", args, {
81
+ cwd: packagePath,
82
+ stdio: ["ignore", "pipe", "pipe"],
83
+ shell: true,
84
+ env
85
+ });
86
+ let stdout = "";
87
+ let stderr = "";
88
+ child.stdout?.on("data", (data) => {
89
+ stdout += data.toString();
90
+ });
91
+ child.stderr?.on("data", (data) => {
92
+ stderr += data.toString();
93
+ });
94
+ child.on("close", (code) => {
95
+ if (code === 0) {
96
+ resolve();
97
+ } else {
98
+ reject(new Error(stderr || stdout || `npm publish exited with code ${code}`));
99
+ }
100
+ });
101
+ child.on("error", (err) => {
102
+ reject(err);
103
+ });
104
+ });
105
+ }
106
+ async function publishPackagesProgrammatic(options) {
107
+ const { packages, dryRun, otp, tag, access, registry } = options;
108
+ const logger = useLogger();
109
+ const token = resolveToken(options.token);
110
+ if (!token && !dryRun) {
111
+ const error = "No npm token found. Set NPM_TOKEN (or NODE_AUTH_TOKEN) in environment.";
112
+ logger.error(error);
113
+ return {
114
+ results: [],
115
+ published: [],
116
+ failed: packages.map((p) => `${p.name}@${p.version}`),
117
+ skipped: [],
118
+ errors: [error]
119
+ };
120
+ }
121
+ const results = [];
122
+ const versionMap = new Map(packages.map((p) => [p.name, p.version]));
123
+ for (const pkg of packages) {
124
+ logger.info(`Publishing ${pkg.name}@${pkg.version}`, { path: pkg.path, dryRun });
125
+ const pkgJsonPath = join(pkg.path, "package.json");
126
+ const originalPkgJson = readFileSync(pkgJsonPath, "utf-8");
127
+ let restored = false;
128
+ try {
129
+ const pkgJson = JSON.parse(originalPkgJson);
130
+ let modified = false;
131
+ for (const section of ["dependencies", "peerDependencies"]) {
132
+ const deps = pkgJson[section];
133
+ if (!deps) continue;
134
+ for (const [depName, depValue] of Object.entries(deps)) {
135
+ if (typeof depValue !== "string") continue;
136
+ const val = depValue;
137
+ if (val.startsWith("link:")) {
138
+ const planVersion = versionMap.get(depName);
139
+ if (planVersion) {
140
+ deps[depName] = `^${planVersion}`;
141
+ modified = true;
142
+ } else {
143
+ try {
144
+ const linkPath = val.replace("link:", "");
145
+ const linkedPkg = JSON.parse(readFileSync(join(pkg.path, linkPath, "package.json"), "utf-8"));
146
+ deps[depName] = `^${linkedPkg.version}`;
147
+ modified = true;
148
+ } catch {
149
+ deps[depName] = "*";
150
+ modified = true;
151
+ }
152
+ }
153
+ } else if (val.startsWith("workspace:")) {
154
+ const planVersion = versionMap.get(depName);
155
+ if (planVersion) {
156
+ deps[depName] = val === "workspace:*" ? `^${planVersion}` : val.replace("workspace:", "");
157
+ modified = true;
158
+ } else {
159
+ try {
160
+ const repoRoot = join(pkg.path, "..");
161
+ const candidates = readdirSync(repoRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => join(repoRoot, d.name, "package.json"));
162
+ for (const candidate of candidates) {
163
+ try {
164
+ const cPkg = JSON.parse(readFileSync(candidate, "utf-8"));
165
+ if (cPkg.name === depName) {
166
+ deps[depName] = `^${cPkg.version}`;
167
+ modified = true;
168
+ break;
169
+ }
170
+ } catch {
171
+ }
172
+ }
173
+ } catch {
174
+ deps[depName] = "*";
175
+ modified = true;
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ if (modified) {
182
+ writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
183
+ logger.info(`Replaced link: deps for ${pkg.name}`);
184
+ }
185
+ await publishSinglePackage({
186
+ packagePath: pkg.path,
187
+ token,
188
+ otp,
189
+ dryRun,
190
+ tag,
191
+ access: access ?? "public",
192
+ registry
193
+ });
194
+ results.push({ name: pkg.name, version: pkg.version, success: true });
195
+ logger.info(`Published ${pkg.name}@${pkg.version}`);
196
+ } catch (error) {
197
+ const message = error instanceof Error ? error.message : String(error);
198
+ logger.error(`Failed to publish ${pkg.name}@${pkg.version}`, void 0, { error: message });
199
+ results.push({
200
+ name: pkg.name,
201
+ version: pkg.version,
202
+ success: false,
203
+ error: message
204
+ });
205
+ } finally {
206
+ if (!restored) {
207
+ writeFileSync(pkgJsonPath, originalPkgJson);
208
+ restored = true;
209
+ }
210
+ }
211
+ }
212
+ const published = results.filter((r) => r.success).map((r) => `${r.name}@${r.version}`);
213
+ const failed = results.filter((r) => !r.success).map((r) => `${r.name}@${r.version}`);
214
+ const errors = results.filter((r) => !r.success && r.error).map((r) => `${r.name}: ${r.error}`);
215
+ return {
216
+ results,
217
+ published,
218
+ failed,
219
+ skipped: dryRun ? packages.map((p) => `${p.name}@${p.version} (dry-run)`) : [],
220
+ errors
221
+ };
222
+ }
223
+ async function publishPackagesWithOTP(options) {
224
+ const { packages, dryRun, tag, access, ui, logger } = options;
225
+ let otp = options.otp;
226
+ const results = [];
227
+ const versionMap = new Map(packages.map((p) => [p.name, p.version]));
228
+ for (const pkg of packages) {
229
+ logger?.info("Publishing package", { name: pkg.name, version: pkg.version });
230
+ const pkgJsonPath = join(pkg.path, "package.json");
231
+ const originalPkgJson = readFileSync(pkgJsonPath, "utf-8");
232
+ let restored = false;
233
+ try {
234
+ const pkgJson = JSON.parse(originalPkgJson);
235
+ let modified = false;
236
+ for (const section of ["dependencies", "peerDependencies"]) {
237
+ const deps = pkgJson[section];
238
+ if (!deps) continue;
239
+ for (const [depName, depValue] of Object.entries(deps)) {
240
+ if (typeof depValue !== "string") continue;
241
+ const val = depValue;
242
+ if (val.startsWith("link:")) {
243
+ const planVersion = versionMap.get(depName);
244
+ if (planVersion) {
245
+ deps[depName] = `^${planVersion}`;
246
+ modified = true;
247
+ } else {
248
+ try {
249
+ const linkPath = val.replace("link:", "");
250
+ const linkedPkg = JSON.parse(readFileSync(join(pkg.path, linkPath, "package.json"), "utf-8"));
251
+ deps[depName] = `^${linkedPkg.version}`;
252
+ modified = true;
253
+ } catch {
254
+ deps[depName] = "*";
255
+ modified = true;
256
+ }
257
+ }
258
+ } else if (val.startsWith("workspace:")) {
259
+ const planVersion = versionMap.get(depName);
260
+ if (planVersion) {
261
+ deps[depName] = val === "workspace:*" ? `^${planVersion}` : val.replace("workspace:", "");
262
+ modified = true;
263
+ } else {
264
+ try {
265
+ const repoRoot = join(pkg.path, "..");
266
+ const candidates = readdirSync(repoRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => join(repoRoot, d.name, "package.json"));
267
+ for (const candidate of candidates) {
268
+ try {
269
+ const cPkg = JSON.parse(readFileSync(candidate, "utf-8"));
270
+ if (cPkg.name === depName) {
271
+ deps[depName] = `^${cPkg.version}`;
272
+ modified = true;
273
+ break;
274
+ }
275
+ } catch {
276
+ }
277
+ }
278
+ } catch {
279
+ deps[depName] = "*";
280
+ modified = true;
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ if (modified) {
287
+ writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
288
+ logger?.info(`Replaced link: deps for ${pkg.name}`);
289
+ }
290
+ const loader = useLoader(`Publishing ${pkg.name}@${pkg.version}...`);
291
+ loader.start();
292
+ let attempts = 0;
293
+ const maxAttempts = 3;
294
+ let published2 = false;
295
+ while (!published2 && attempts < maxAttempts) {
296
+ attempts++;
297
+ try {
298
+ await publishSinglePackage2({
299
+ packagePath: pkg.path,
300
+ otp,
301
+ dryRun,
302
+ tag,
303
+ access
304
+ });
305
+ published2 = true;
306
+ results.push({ name: pkg.name, version: pkg.version, success: true });
307
+ const successMsg = dryRun ? `Dry-run succeeded for ${pkg.name}@${pkg.version}` : `Published ${pkg.name}@${pkg.version}`;
308
+ loader.succeed(successMsg);
309
+ logger?.info("Package published successfully", {
310
+ name: pkg.name,
311
+ version: pkg.version,
312
+ dryRun
313
+ });
314
+ } catch (error) {
315
+ const errorMessage = error.message || String(error);
316
+ if (errorMessage.includes("EOTP") || errorMessage.includes("one-time password")) {
317
+ if (attempts < maxAttempts) {
318
+ loader.succeed(`\u{1F510} 2FA required for ${pkg.name}`);
319
+ logger?.info("OTP required for publishing", {
320
+ name: pkg.name,
321
+ attempt: attempts
322
+ });
323
+ const rl = readline.createInterface({
324
+ input: process.stdin,
325
+ output: process.stdout
326
+ });
327
+ try {
328
+ otp = await rl.question(" Enter OTP code: ");
329
+ rl.close();
330
+ if (!otp || otp.trim().length !== 6) {
331
+ ui.write?.(" \u26A0\uFE0F Invalid OTP code (must be 6 digits)\n");
332
+ logger?.warn("Invalid OTP code provided", { length: otp?.trim().length });
333
+ otp = void 0;
334
+ continue;
335
+ }
336
+ loader.update({ text: `Publishing ${pkg.name}@${pkg.version} with OTP...` });
337
+ loader.start();
338
+ logger?.debug("Retrying with OTP");
339
+ } catch (e) {
340
+ rl.close();
341
+ throw e;
342
+ }
343
+ } else {
344
+ loader.fail("Max OTP attempts reached");
345
+ logger?.error("Max OTP attempts reached", {
346
+ name: pkg.name,
347
+ attempts: maxAttempts
348
+ });
349
+ results.push({
350
+ name: pkg.name,
351
+ version: pkg.version,
352
+ success: false,
353
+ error: "Max OTP attempts reached"
354
+ });
355
+ break;
356
+ }
357
+ } else {
358
+ loader.fail(`Failed: ${errorMessage}`);
359
+ logger?.error("Package publish failed", {
360
+ name: pkg.name,
361
+ version: pkg.version,
362
+ error: errorMessage
363
+ });
364
+ results.push({
365
+ name: pkg.name,
366
+ version: pkg.version,
367
+ success: false,
368
+ error: errorMessage
369
+ });
370
+ break;
371
+ }
372
+ }
373
+ }
374
+ } finally {
375
+ if (!restored) {
376
+ writeFileSync(pkgJsonPath, originalPkgJson);
377
+ restored = true;
378
+ }
379
+ }
380
+ }
381
+ const published = results.filter((r) => r.success).map((r) => `${r.name}@${r.version}`);
382
+ const failed = results.filter((r) => !r.success).map((r) => `${r.name}@${r.version}`);
383
+ const errors = results.filter((r) => !r.success && r.error).map((r) => `${r.name}: ${r.error}`);
384
+ return {
385
+ results,
386
+ published,
387
+ failed,
388
+ skipped: dryRun ? packages.map((p) => `${p.name}@${p.version} (dry-run)`) : [],
389
+ errors
390
+ };
391
+ }
392
+ function publishSinglePackage2(options) {
393
+ const { packagePath, otp, dryRun, tag, access } = options;
394
+ return new Promise((resolve, reject) => {
395
+ const args = ["publish"];
396
+ if (dryRun) {
397
+ args.push("--dry-run");
398
+ }
399
+ if (otp) {
400
+ args.push(`--otp=${otp}`);
401
+ }
402
+ if (tag) {
403
+ args.push(`--tag=${tag}`);
404
+ }
405
+ if (access) {
406
+ args.push(`--access=${access}`);
407
+ }
408
+ const child = spawn("npm", args, {
409
+ cwd: packagePath,
410
+ stdio: ["inherit", "pipe", "pipe"],
411
+ shell: true
412
+ });
413
+ let stdout = "";
414
+ let stderr = "";
415
+ child.stdout?.on("data", (data) => {
416
+ stdout += data.toString();
417
+ });
418
+ child.stderr?.on("data", (data) => {
419
+ stderr += data.toString();
420
+ });
421
+ child.on("close", (code) => {
422
+ if (code === 0) {
423
+ resolve();
424
+ } else {
425
+ const errorOutput = stderr || stdout;
426
+ reject(new Error(errorOutput));
427
+ }
428
+ });
429
+ child.on("error", (err) => {
430
+ reject(err);
431
+ });
432
+ });
433
+ }
434
+
435
+ // src/cli/commands/run.ts
436
+ var run_default = defineCommand({
437
+ id: "release:run",
438
+ description: "Execute release process (plan, check, publish)",
439
+ handler: {
440
+ async execute(ctx, input) {
441
+ const { flags } = input;
442
+ const cwd = ctx.cwd || process.cwd();
443
+ const repoRoot = await findRepoRoot(cwd);
444
+ const dryRun = flags["dry-run"] === true;
445
+ const configLoader = useLoader("Loading configuration...");
446
+ configLoader.start();
447
+ const fileConfig = await useConfig();
448
+ const config = {
449
+ ...fileConfig,
450
+ ...flags.bump && { bump: flags.bump },
451
+ ...flags.strict !== void 0 && { strict: flags.strict }
452
+ };
453
+ configLoader.succeed("Configuration loaded");
454
+ const llm = useLLM();
455
+ const changelog = createChangelogGenerator(config, llm ?? void 0);
456
+ const token = process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
457
+ const publisher = {
458
+ async publish(packages, opts) {
459
+ if (token) {
460
+ return publishPackagesProgrammatic({ packages, dryRun: opts.dryRun });
461
+ }
462
+ return publishPackagesWithOTP({
463
+ packages,
464
+ dryRun: opts.dryRun,
465
+ access: opts.access ?? "public",
466
+ ui: ctx.ui,
467
+ logger: ctx.platform?.logger
468
+ });
469
+ }
470
+ };
471
+ const pipelineLoader = useLoader("Running release pipeline...");
472
+ pipelineLoader.start();
473
+ const scopeCwd = await resolveScopePath(repoRoot, flags.scope || "root");
474
+ const result = await runReleasePipeline({
475
+ cwd,
476
+ repoRoot,
477
+ scopeCwd,
478
+ scope: flags.scope,
479
+ config,
480
+ dryRun,
481
+ skipChecks: flags["skip-checks"],
482
+ skipBuild: flags["skip-build"],
483
+ skipVerify: flags["skip-verify"],
484
+ checks: (flags.scope ? config.scopes?.[flags.scope]?.checks : void 0) ?? config.checks ?? [],
485
+ publisher,
486
+ changelog,
487
+ logger: ctx.platform?.logger,
488
+ onProgress: (_stage, message) => pipelineLoader.update({ text: message })
489
+ });
490
+ pipelineLoader.succeed(result.success ? "Release completed" : "Release failed");
491
+ if (flags.json) {
492
+ ctx.ui?.json?.(result.report);
493
+ } else {
494
+ const report = result.report;
495
+ const sections = [];
496
+ if (report.result.published?.length) {
497
+ sections.push({
498
+ header: "Published",
499
+ items: report.result.published.map((p) => `${ctx.ui.symbols.success} ${p}`)
500
+ });
501
+ }
502
+ if (report.result.skipped?.length) {
503
+ sections.push({
504
+ header: "Skipped (dry-run)",
505
+ items: report.result.skipped.map((p) => `${ctx.ui.symbols.info} ${p}`)
506
+ });
507
+ }
508
+ if (report.result.errors?.length) {
509
+ sections.push({
510
+ header: "Errors",
511
+ items: report.result.errors.map((e) => `${ctx.ui.symbols.error} ${e}`)
512
+ });
513
+ }
514
+ if (report.result.git) {
515
+ const g = report.result.git;
516
+ sections.push({
517
+ header: "Git",
518
+ items: [
519
+ `Committed: ${g.committed}`,
520
+ `Tags: ${g.tagged?.join(", ") || "none"}`,
521
+ `Pushed: ${g.pushed}`
522
+ ]
523
+ });
524
+ }
525
+ ctx.ui.sideBox({
526
+ title: "Release",
527
+ sections,
528
+ status: result.success ? "success" : "error",
529
+ timing: report.result.timingMs
530
+ });
531
+ }
532
+ return { exitCode: result.success ? 0 : 1, report: result.report };
533
+ }
534
+ }
535
+ });
536
+
537
+ export { run_default as default };
538
+ //# sourceMappingURL=run.js.map
539
+ //# sourceMappingURL=run.js.map