@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.
- package/README.md +211 -0
- package/dist/cli/commands/changelog.d.ts +17 -0
- package/dist/cli/commands/changelog.js +156 -0
- package/dist/cli/commands/changelog.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +12 -0
- package/dist/cli/commands/plan.js +117 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/publish.d.ts +15 -0
- package/dist/cli/commands/publish.js +486 -0
- package/dist/cli/commands/publish.js.map +1 -0
- package/dist/cli/commands/report.d.ts +9 -0
- package/dist/cli/commands/report.js +77 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/rollback.d.ts +9 -0
- package/dist/cli/commands/rollback.js +42 -0
- package/dist/cli/commands/rollback.js.map +1 -0
- package/dist/cli/commands/run.d.ts +16 -0
- package/dist/cli/commands/run.js +539 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +14 -0
- package/dist/cli/commands/verify.js +106 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/contracts/release.schema.d.ts +503 -0
- package/dist/contracts/release.schema.js +45 -0
- package/dist/contracts/release.schema.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +689 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +292 -0
- package/dist/manifest.js +604 -0
- package/dist/manifest.js.map +1 -0
- package/dist/rest/handlers/build-handler.d.ts +20 -0
- package/dist/rest/handlers/build-handler.js +68 -0
- package/dist/rest/handlers/build-handler.js.map +1 -0
- package/dist/rest/handlers/changelog-generate-handler.d.ts +20 -0
- package/dist/rest/handlers/changelog-generate-handler.js +169 -0
- package/dist/rest/handlers/changelog-generate-handler.js.map +1 -0
- package/dist/rest/handlers/changelog-handler.d.ts +16 -0
- package/dist/rest/handlers/changelog-handler.js +50 -0
- package/dist/rest/handlers/changelog-handler.js.map +1 -0
- package/dist/rest/handlers/changelog-save-handler.d.ts +13 -0
- package/dist/rest/handlers/changelog-save-handler.js +42 -0
- package/dist/rest/handlers/changelog-save-handler.js.map +1 -0
- package/dist/rest/handlers/checklist-handler.d.ts +39 -0
- package/dist/rest/handlers/checklist-handler.js +155 -0
- package/dist/rest/handlers/checklist-handler.js.map +1 -0
- package/dist/rest/handlers/generate-handler.d.ts +35 -0
- package/dist/rest/handlers/generate-handler.js +206 -0
- package/dist/rest/handlers/generate-handler.js.map +1 -0
- package/dist/rest/handlers/get-checks-handler.d.ts +15 -0
- package/dist/rest/handlers/get-checks-handler.js +22 -0
- package/dist/rest/handlers/get-checks-handler.js.map +1 -0
- package/dist/rest/handlers/git-timeline-handler.d.ts +26 -0
- package/dist/rest/handlers/git-timeline-handler.js +209 -0
- package/dist/rest/handlers/git-timeline-handler.js.map +1 -0
- package/dist/rest/handlers/history-changelog-handler.d.ts +14 -0
- package/dist/rest/handlers/history-changelog-handler.js +34 -0
- package/dist/rest/handlers/history-changelog-handler.js.map +1 -0
- package/dist/rest/handlers/history-handler.d.ts +20 -0
- package/dist/rest/handlers/history-handler.js +75 -0
- package/dist/rest/handlers/history-handler.js.map +1 -0
- package/dist/rest/handlers/history-plan-handler.d.ts +30 -0
- package/dist/rest/handlers/history-plan-handler.js +34 -0
- package/dist/rest/handlers/history-plan-handler.js.map +1 -0
- package/dist/rest/handlers/history-report-handler.d.ts +64 -0
- package/dist/rest/handlers/history-report-handler.js +34 -0
- package/dist/rest/handlers/history-report-handler.js.map +1 -0
- package/dist/rest/handlers/plan-handler.d.ts +29 -0
- package/dist/rest/handlers/plan-handler.js +75 -0
- package/dist/rest/handlers/plan-handler.js.map +1 -0
- package/dist/rest/handlers/preview-handler.d.ts +26 -0
- package/dist/rest/handlers/preview-handler.js +127 -0
- package/dist/rest/handlers/preview-handler.js.map +1 -0
- package/dist/rest/handlers/report-handler.d.ts +65 -0
- package/dist/rest/handlers/report-handler.js +48 -0
- package/dist/rest/handlers/report-handler.js.map +1 -0
- package/dist/rest/handlers/reset-handler.d.ts +12 -0
- package/dist/rest/handlers/reset-handler.js +38 -0
- package/dist/rest/handlers/reset-handler.js.map +1 -0
- package/dist/rest/handlers/run-checks-handler.d.ts +20 -0
- package/dist/rest/handlers/run-checks-handler.js +58 -0
- package/dist/rest/handlers/run-checks-handler.js.map +1 -0
- package/dist/rest/handlers/run-handler.d.ts +68 -0
- package/dist/rest/handlers/run-handler.js +274 -0
- package/dist/rest/handlers/run-handler.js.map +1 -0
- package/dist/rest/handlers/scopes-handler.d.ts +20 -0
- package/dist/rest/handlers/scopes-handler.js +63 -0
- package/dist/rest/handlers/scopes-handler.js.map +1 -0
- package/dist/rest/handlers/status-handler.d.ts +24 -0
- package/dist/rest/handlers/status-handler.js +120 -0
- package/dist/rest/handlers/status-handler.js.map +1 -0
- package/dist/setup/handler.d.ts +19 -0
- package/dist/setup/handler.js +103 -0
- package/dist/setup/handler.js.map +1 -0
- package/dist/widgets/220.js +446 -0
- package/dist/widgets/220.js.map +1 -0
- package/dist/widgets/331.js +2 -0
- package/dist/widgets/331.js.map +1 -0
- package/dist/widgets/403.js +2 -0
- package/dist/widgets/403.js.map +1 -0
- package/dist/widgets/406.js +35 -0
- package/dist/widgets/406.js.map +1 -0
- package/dist/widgets/455.js +2 -0
- package/dist/widgets/455.js.map +1 -0
- package/dist/widgets/482.js +2 -0
- package/dist/widgets/482.js.map +1 -0
- package/dist/widgets/485.js +2 -0
- package/dist/widgets/485.js.map +1 -0
- package/dist/widgets/527.js +2 -0
- package/dist/widgets/527.js.map +1 -0
- package/dist/widgets/628.js +2 -0
- package/dist/widgets/628.js.map +1 -0
- package/dist/widgets/694.js +2 -0
- package/dist/widgets/694.js.map +1 -0
- package/dist/widgets/712.js +2 -0
- package/dist/widgets/712.js.map +1 -0
- package/dist/widgets/866.js +2 -0
- package/dist/widgets/866.js.map +1 -0
- package/dist/widgets/915.js +39 -0
- package/dist/widgets/915.js.map +1 -0
- package/dist/widgets/957.js +10 -0
- package/dist/widgets/957.js.map +1 -0
- package/dist/widgets/983.js +2 -0
- package/dist/widgets/983.js.map +1 -0
- package/dist/widgets/@mf-types.d.ts +3 -0
- package/dist/widgets/@mf-types.zip +0 -0
- package/dist/widgets/__federation_expose_ReleasePage.js +2 -0
- package/dist/widgets/__federation_expose_ReleasePage.js.map +1 -0
- package/dist/widgets/mf-manifest.json +260 -0
- package/dist/widgets/mf-stats.json +302 -0
- package/dist/widgets/remoteEntry.js +7 -0
- package/dist/widgets/remoteEntry.js.map +1 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# @kb-labs/release-cli
|
|
2
|
+
|
|
3
|
+
KB Labs Release Manager - CLI commands for release management.
|
|
4
|
+
|
|
5
|
+
## Vision & Purpose
|
|
6
|
+
|
|
7
|
+
**@kb-labs/release-cli** provides CLI commands for KB Labs Release Manager. It includes commands for planning, running, verifying, previewing, reporting, rolling back releases, and generating changelogs.
|
|
8
|
+
|
|
9
|
+
### Core Goals
|
|
10
|
+
|
|
11
|
+
- **Plan Command**: Plan release with versioning
|
|
12
|
+
- **Run Command**: Run complete release process
|
|
13
|
+
- **Verify Command**: Verify release readiness
|
|
14
|
+
- **Preview Command**: Preview release plan
|
|
15
|
+
- **Report Command**: Generate release report
|
|
16
|
+
- **Rollback Command**: Rollback failed release
|
|
17
|
+
- **Changelog Command**: Generate changelog
|
|
18
|
+
|
|
19
|
+
## Package Status
|
|
20
|
+
|
|
21
|
+
- **Version**: 0.1.0
|
|
22
|
+
- **Stage**: Stable
|
|
23
|
+
- **Status**: Production Ready ✅
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
### High-Level Overview
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Release CLI
|
|
31
|
+
│
|
|
32
|
+
├──► CLI Commands
|
|
33
|
+
├──► Manifest Definition
|
|
34
|
+
├──► REST Handlers
|
|
35
|
+
└──► Analytics Integration
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Key Components
|
|
39
|
+
|
|
40
|
+
1. **Commands** (`commands/`): CLI command implementations
|
|
41
|
+
2. **Manifest** (`manifest.v2.ts`): Plugin manifest definition
|
|
42
|
+
3. **REST Handlers** (`rest/handlers/`): REST API handlers
|
|
43
|
+
4. **Analytics** (`analytics/`): Analytics event tracking
|
|
44
|
+
|
|
45
|
+
## ✨ Features
|
|
46
|
+
|
|
47
|
+
- **Plan command** for planning releases
|
|
48
|
+
- **Run command** for running releases
|
|
49
|
+
- **Verify command** for verifying release readiness
|
|
50
|
+
- **Preview command** for previewing release plans
|
|
51
|
+
- **Report command** for generating reports
|
|
52
|
+
- **Rollback command** for rolling back releases
|
|
53
|
+
- **Changelog command** for generating changelogs
|
|
54
|
+
- **REST handlers** for API integration
|
|
55
|
+
|
|
56
|
+
## 📦 API Reference
|
|
57
|
+
|
|
58
|
+
### Main Exports
|
|
59
|
+
|
|
60
|
+
#### Commands
|
|
61
|
+
|
|
62
|
+
- `plan`: Plan release command
|
|
63
|
+
- `run`: Run release command
|
|
64
|
+
- `verify`: Verify release command
|
|
65
|
+
- `preview`: Preview release command
|
|
66
|
+
- `report`: Report command
|
|
67
|
+
- `rollback`: Rollback command
|
|
68
|
+
- `changelog`: Changelog command
|
|
69
|
+
|
|
70
|
+
#### Manifest
|
|
71
|
+
|
|
72
|
+
- `manifest`: Plugin manifest V2
|
|
73
|
+
- `commands`: CLI commands manifest
|
|
74
|
+
|
|
75
|
+
## 🔧 Configuration
|
|
76
|
+
|
|
77
|
+
### Configuration Options
|
|
78
|
+
|
|
79
|
+
All configuration via CLI flags and kb-labs.config.json.
|
|
80
|
+
|
|
81
|
+
### CLI Flags
|
|
82
|
+
|
|
83
|
+
- `--json`: Output JSON format
|
|
84
|
+
- `--quiet`: Quiet mode
|
|
85
|
+
- `--verbose`: Verbose output
|
|
86
|
+
|
|
87
|
+
## 🔗 Dependencies
|
|
88
|
+
|
|
89
|
+
### Runtime Dependencies
|
|
90
|
+
|
|
91
|
+
- `@kb-labs/analytics-sdk-node` (`link:../../../kb-labs-analytics/packages/analytics-sdk-node`): Analytics SDK
|
|
92
|
+
- `@kb-labs/release-core` (`link:../release-core`): Release core
|
|
93
|
+
- `@kb-labs/release-checks` (`link:../release-checks`): Release checks
|
|
94
|
+
- `@kb-labs/changelog` (`link:../changelog`): Changelog package
|
|
95
|
+
- `@kb-labs/cli-core` (`link:../../../kb-labs-cli/packages/core`): CLI core
|
|
96
|
+
- `@kb-labs/cli-commands` (`link:../../../kb-labs-cli/packages/commands`): CLI commands
|
|
97
|
+
- `@kb-labs/shared-cli-ui` (`link:../../../kb-labs-shared/packages/cli-ui`): Shared CLI UI
|
|
98
|
+
- `@kb-labs/core` (`link:../../../kb-labs-core`): Core package
|
|
99
|
+
- `@kb-labs/core-bundle` (`link:../../../kb-labs-core/packages/bundle`): Bundle package
|
|
100
|
+
- `@kb-labs/plugin-manifest` (`link:../../../kb-labs-plugin/packages/manifest`): Plugin manifest
|
|
101
|
+
- `@aws-sdk/client-s3` (`^3.676.0`): AWS S3 client
|
|
102
|
+
- `ajv` (`^8.17.1`): JSON schema validation
|
|
103
|
+
- `ajv-formats` (`^3.0.1`): AJV formats
|
|
104
|
+
- `glob` (`^10.3.10`): File globbing
|
|
105
|
+
- `globby` (`^11.0.0`): File pattern matching
|
|
106
|
+
- `semver` (`^7.6.0`): SemVer parsing
|
|
107
|
+
- `simple-git` (`^3.25.0`): Git operations
|
|
108
|
+
- `uuidv7` (`^0.6.1`): UUID v7 generation
|
|
109
|
+
- `yaml` (`^2.8.0`): YAML parsing
|
|
110
|
+
- `zod` (`^4.1.5`): Schema validation
|
|
111
|
+
|
|
112
|
+
### Development Dependencies
|
|
113
|
+
|
|
114
|
+
- `@kb-labs/devkit` (`link:../../../kb-labs-devkit`): DevKit presets
|
|
115
|
+
- `@types/node` (`^24.7.0`): Node.js types
|
|
116
|
+
- `tsup` (`^8`): TypeScript bundler
|
|
117
|
+
- `typescript` (`^5`): TypeScript compiler
|
|
118
|
+
- `vitest` (`^3`): Test runner
|
|
119
|
+
|
|
120
|
+
## 🧪 Testing
|
|
121
|
+
|
|
122
|
+
### Test Structure
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
src/__tests__/
|
|
126
|
+
└── manifest.v2.spec.ts
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Test Coverage
|
|
130
|
+
|
|
131
|
+
- **Current Coverage**: ~50%
|
|
132
|
+
- **Target Coverage**: 90%
|
|
133
|
+
|
|
134
|
+
## 📈 Performance
|
|
135
|
+
|
|
136
|
+
### Performance Characteristics
|
|
137
|
+
|
|
138
|
+
- **Time Complexity**: O(1) for command registration, O(n) for command execution
|
|
139
|
+
- **Space Complexity**: O(1)
|
|
140
|
+
- **Bottlenecks**: Release operations
|
|
141
|
+
|
|
142
|
+
## 🔒 Security
|
|
143
|
+
|
|
144
|
+
### Security Considerations
|
|
145
|
+
|
|
146
|
+
- **Registry Authentication**: Secure registry authentication
|
|
147
|
+
- **Path Validation**: Path validation for file operations
|
|
148
|
+
|
|
149
|
+
### Known Vulnerabilities
|
|
150
|
+
|
|
151
|
+
- None
|
|
152
|
+
|
|
153
|
+
## 🐛 Known Issues & Limitations
|
|
154
|
+
|
|
155
|
+
### Known Issues
|
|
156
|
+
|
|
157
|
+
- None currently
|
|
158
|
+
|
|
159
|
+
### Limitations
|
|
160
|
+
|
|
161
|
+
- **Command Types**: Fixed command types
|
|
162
|
+
- **Output Formats**: Fixed output formats
|
|
163
|
+
|
|
164
|
+
### Future Improvements
|
|
165
|
+
|
|
166
|
+
- **More Commands**: Additional commands
|
|
167
|
+
- **Custom Output Formats**: Custom output format support
|
|
168
|
+
|
|
169
|
+
## 🔄 Migration & Breaking Changes
|
|
170
|
+
|
|
171
|
+
### Migration from Previous Versions
|
|
172
|
+
|
|
173
|
+
No breaking changes in current version (0.1.0).
|
|
174
|
+
|
|
175
|
+
### Breaking Changes in Future Versions
|
|
176
|
+
|
|
177
|
+
- None planned
|
|
178
|
+
|
|
179
|
+
## 📚 Examples
|
|
180
|
+
|
|
181
|
+
### Example 1: Plan Release
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
kb release:plan
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Example 2: Run Release
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
kb release:run
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Example 3: Verify Release
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
kb release:verify
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Example 4: Generate Changelog
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
kb release:changelog
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 🤝 Contributing
|
|
206
|
+
|
|
207
|
+
See [CONTRIBUTING.md](../../CONTRIBUTING.md) for development guidelines.
|
|
208
|
+
|
|
209
|
+
## 📄 License
|
|
210
|
+
|
|
211
|
+
MIT © KB Labs
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
interface ChangelogFlags {
|
|
5
|
+
scope?: string;
|
|
6
|
+
from?: string;
|
|
7
|
+
to?: string;
|
|
8
|
+
'since-tag'?: string;
|
|
9
|
+
format?: 'json' | 'md' | 'both';
|
|
10
|
+
level?: 'compact' | 'standard' | 'detailed';
|
|
11
|
+
template?: string;
|
|
12
|
+
'breaking-only'?: boolean;
|
|
13
|
+
json?: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<ChangelogFlags>, unknown>;
|
|
16
|
+
|
|
17
|
+
export { _default as default };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { mkdir, readFile, writeFile, stat } from 'fs/promises';
|
|
3
|
+
import { defineCommand, findRepoRoot, useLoader, useConfig, useLLM, displayArtifacts } from '@kb-labs/sdk';
|
|
4
|
+
import { planRelease } from '@kb-labs/release-manager-core';
|
|
5
|
+
import 'globby';
|
|
6
|
+
import { generateChangelog, generateSimpleChangelog } from '@kb-labs/release-manager-changelog';
|
|
7
|
+
|
|
8
|
+
// src/cli/commands/changelog.ts
|
|
9
|
+
function createChangelogGenerator(config, llm) {
|
|
10
|
+
return {
|
|
11
|
+
async generate(plan, opts) {
|
|
12
|
+
const locale = config.changelog?.locale || "en";
|
|
13
|
+
const packages = plan.packages.map((pkg) => ({
|
|
14
|
+
name: pkg.name,
|
|
15
|
+
path: pkg.path,
|
|
16
|
+
currentVersion: pkg.currentVersion,
|
|
17
|
+
nextVersion: pkg.nextVersion,
|
|
18
|
+
bump: pkg.bump === "auto" ? "patch" : pkg.bump
|
|
19
|
+
}));
|
|
20
|
+
try {
|
|
21
|
+
const result = await generateChangelog({
|
|
22
|
+
repoRoot: opts.repoRoot,
|
|
23
|
+
gitCwd: opts.gitCwd,
|
|
24
|
+
packages,
|
|
25
|
+
range: { to: "HEAD" },
|
|
26
|
+
changelog: {
|
|
27
|
+
template: config.changelog?.template ?? void 0,
|
|
28
|
+
locale,
|
|
29
|
+
metadata: config.changelog?.metadata,
|
|
30
|
+
ignoreAuthors: config.changelog?.ignoreAuthors,
|
|
31
|
+
includeTypes: config.changelog?.includeTypes,
|
|
32
|
+
excludeTypes: config.changelog?.excludeTypes,
|
|
33
|
+
collapseMerges: config.changelog?.collapseMerges,
|
|
34
|
+
collapseReverts: config.changelog?.collapseReverts,
|
|
35
|
+
preferMergeSummary: config.changelog?.preferMergeSummary
|
|
36
|
+
},
|
|
37
|
+
git: {
|
|
38
|
+
autoUnshallow: config.git?.autoUnshallow,
|
|
39
|
+
requireSignedTags: config.git?.requireSignedTags,
|
|
40
|
+
baseUrl: config.git?.baseUrl ?? void 0
|
|
41
|
+
},
|
|
42
|
+
platform: llm ? { llm } : void 0
|
|
43
|
+
});
|
|
44
|
+
return result.markdown;
|
|
45
|
+
} catch {
|
|
46
|
+
return generateSimpleChangelog(packages, locale);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/cli/commands/changelog.ts
|
|
53
|
+
var changelog_default = defineCommand({
|
|
54
|
+
id: "release:changelog",
|
|
55
|
+
description: "Generate changelog from conventional commits",
|
|
56
|
+
handler: {
|
|
57
|
+
async execute(ctx, input) {
|
|
58
|
+
const { flags } = input;
|
|
59
|
+
const cwd = ctx.cwd || process.cwd();
|
|
60
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
61
|
+
const loader = useLoader("Loading configuration...");
|
|
62
|
+
loader.start();
|
|
63
|
+
const fileConfig = await useConfig();
|
|
64
|
+
const config = fileConfig ?? {};
|
|
65
|
+
loader.update({ text: "Discovering packages..." });
|
|
66
|
+
const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope });
|
|
67
|
+
if (plan.packages.length === 0) {
|
|
68
|
+
loader.fail(`No packages found matching scope: ${flags.scope || "all"}`);
|
|
69
|
+
return { exitCode: 1 };
|
|
70
|
+
}
|
|
71
|
+
let gitCwd = repoRoot;
|
|
72
|
+
if (flags.scope && plan.packages[0]) {
|
|
73
|
+
try {
|
|
74
|
+
gitCwd = await findRepoRoot(plan.packages[0].path);
|
|
75
|
+
} catch {
|
|
76
|
+
gitCwd = plan.packages[0].path;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
loader.update({ text: "Generating changelog..." });
|
|
80
|
+
const llm = useLLM();
|
|
81
|
+
const generator = createChangelogGenerator(config, llm ?? void 0);
|
|
82
|
+
const markdown = await generator.generate(plan, { repoRoot, gitCwd, config });
|
|
83
|
+
const format = flags.format || config.changelog?.format || "both";
|
|
84
|
+
loader.update({ text: "Saving artifacts..." });
|
|
85
|
+
const outputDir = join(repoRoot, ".kb", "release");
|
|
86
|
+
const artifacts = [];
|
|
87
|
+
if (!flags.json) {
|
|
88
|
+
await mkdir(outputDir, { recursive: true });
|
|
89
|
+
if (markdown && (format === "md" || format === "both")) {
|
|
90
|
+
const changelogPath = join(outputDir, "CHANGELOG.md");
|
|
91
|
+
let existing = "";
|
|
92
|
+
try {
|
|
93
|
+
existing = await readFile(changelogPath, "utf-8");
|
|
94
|
+
const footerStart = existing.indexOf("\n---\n\n*Generated automatically");
|
|
95
|
+
if (footerStart !== -1) {
|
|
96
|
+
existing = existing.substring(0, footerStart);
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
}
|
|
100
|
+
const combined = existing ? `${markdown}
|
|
101
|
+
|
|
102
|
+
${existing}` : markdown;
|
|
103
|
+
await writeFile(changelogPath, combined, "utf-8");
|
|
104
|
+
const stats = await stat(changelogPath);
|
|
105
|
+
artifacts.push({
|
|
106
|
+
name: "Changelog",
|
|
107
|
+
path: changelogPath,
|
|
108
|
+
size: stats.size,
|
|
109
|
+
modified: stats.mtime,
|
|
110
|
+
description: "Generated changelog in Markdown format"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
loader.succeed("Changelog generated successfully");
|
|
115
|
+
if (flags.json) {
|
|
116
|
+
ctx.ui?.json?.({
|
|
117
|
+
packagesCount: plan.packages.length,
|
|
118
|
+
markdown: format === "md" || format === "both" ? markdown : void 0,
|
|
119
|
+
artifacts: artifacts.map((a) => ({ name: a.name, path: a.path, size: a.size ?? 0 }))
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
const sections = [];
|
|
123
|
+
sections.push({
|
|
124
|
+
header: "Summary",
|
|
125
|
+
items: [
|
|
126
|
+
`Packages: ${plan.packages.map((p) => p.name).join(", ")}`,
|
|
127
|
+
`Format: ${format === "both" ? "Markdown + JSON" : format}`
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
if (artifacts.length > 0) {
|
|
131
|
+
const artifactsLines = displayArtifacts(artifacts, {
|
|
132
|
+
showSize: true,
|
|
133
|
+
showTime: true,
|
|
134
|
+
showDescription: true,
|
|
135
|
+
maxItems: 10,
|
|
136
|
+
title: ""
|
|
137
|
+
});
|
|
138
|
+
sections.push({ header: "Artifacts", items: artifactsLines });
|
|
139
|
+
}
|
|
140
|
+
ctx.ui.sideBox({
|
|
141
|
+
title: "Changelog Generated",
|
|
142
|
+
sections,
|
|
143
|
+
status: "success"
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
exitCode: 0,
|
|
148
|
+
artifacts: artifacts.map((a) => ({ name: a.name, path: a.path, size: a.size ?? 0 }))
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
export { changelog_default as default };
|
|
155
|
+
//# sourceMappingURL=changelog.js.map
|
|
156
|
+
//# sourceMappingURL=changelog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/changelog-factory.ts","../../../src/cli/commands/changelog.ts"],"names":["join","readFile"],"mappings":"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","file":"changelog.js","sourcesContent":["/**\n * Shared changelog generator factory.\n * Used by both CLI (run.ts) and REST (run-handler.ts) to avoid duplication.\n */\n\nimport {\n generateChangelog,\n generateSimpleChangelog,\n type ChangelogPackageInfo,\n} from '@kb-labs/release-manager-changelog';\nimport type { ReleaseConfig, ChangelogGenerator } from '@kb-labs/release-manager-core';\n\nexport function createChangelogGenerator(config: ReleaseConfig, llm?: any): ChangelogGenerator {\n return {\n async generate(plan, opts) {\n const locale = (config.changelog?.locale as 'en' | 'ru') || 'en';\n const packages: ChangelogPackageInfo[] = plan.packages.map(pkg => ({\n name: pkg.name,\n path: pkg.path,\n currentVersion: pkg.currentVersion,\n nextVersion: pkg.nextVersion,\n bump: pkg.bump === 'auto' ? 'patch' : pkg.bump,\n }));\n try {\n const result = await generateChangelog({\n repoRoot: opts.repoRoot,\n gitCwd: opts.gitCwd,\n packages,\n range: { to: 'HEAD' },\n changelog: {\n template: config.changelog?.template ?? undefined,\n locale,\n metadata: config.changelog?.metadata,\n ignoreAuthors: config.changelog?.ignoreAuthors,\n includeTypes: config.changelog?.includeTypes as string[],\n excludeTypes: config.changelog?.excludeTypes as string[],\n collapseMerges: config.changelog?.collapseMerges,\n collapseReverts: config.changelog?.collapseReverts,\n preferMergeSummary: config.changelog?.preferMergeSummary,\n },\n git: {\n autoUnshallow: config.git?.autoUnshallow,\n requireSignedTags: config.git?.requireSignedTags,\n baseUrl: config.git?.baseUrl ?? undefined,\n },\n platform: llm ? { llm } : undefined,\n });\n return result.markdown;\n } catch {\n return generateSimpleChangelog(packages, locale);\n }\n },\n };\n}\n","/**\n * Release changelog command — thin adapter over planRelease + createChangelogGenerator.\n */\n\nimport { join } from 'node:path';\nimport { stat, writeFile, mkdir, readFile } from 'node:fs/promises';\nimport { defineCommand, type CLIInput, type PluginContextV3, useLLM, useLoader, displayArtifacts, type ArtifactInfo, useConfig } from '@kb-labs/sdk';\nimport { planRelease, type ReleaseConfig } from '@kb-labs/release-manager-core';\nimport { findRepoRoot } from '../../shared/utils';\nimport { createChangelogGenerator } from '../../shared/changelog-factory';\n\ninterface ChangelogFlags {\n scope?: string;\n from?: string;\n to?: string;\n 'since-tag'?: string;\n format?: 'json' | 'md' | 'both';\n level?: 'compact' | 'standard' | 'detailed';\n template?: string;\n 'breaking-only'?: boolean;\n json?: boolean;\n}\n\ninterface ReleaseChangelogResult {\n exitCode: number;\n artifacts?: Array<{ name: string; path: string; size: number }>;\n}\n\nexport default defineCommand({\n id: 'release:changelog',\n description: 'Generate changelog from conventional commits',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<ChangelogFlags>): Promise<ReleaseChangelogResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n // 1. Load config + discover packages\n const loader = useLoader('Loading configuration...');\n loader.start();\n\n const fileConfig = await useConfig<ReleaseConfig>();\n const config: ReleaseConfig = fileConfig ?? {};\n\n loader.update({ text: 'Discovering packages...' });\n\n const plan = await planRelease({ cwd: repoRoot, config, scope: flags.scope });\n\n if (plan.packages.length === 0) {\n loader.fail(`No packages found matching scope: ${flags.scope || 'all'}`);\n return { exitCode: 1 };\n }\n\n // 2. Determine git working directory (for submodule support)\n let gitCwd = repoRoot;\n if (flags.scope && plan.packages[0]) {\n try {\n gitCwd = await findRepoRoot(plan.packages[0].path);\n } catch {\n gitCwd = plan.packages[0].path;\n }\n }\n\n // 3. Generate changelog via shared factory\n loader.update({ text: 'Generating changelog...' });\n\n const llm = useLLM();\n const generator = createChangelogGenerator(config, llm ?? undefined);\n const markdown = await generator.generate(plan, { repoRoot, gitCwd, config });\n\n const format = flags.format || config.changelog?.format || 'both';\n\n // 4. Save artifacts\n loader.update({ text: 'Saving artifacts...' });\n\n const outputDir = join(repoRoot, '.kb', 'release');\n const artifacts: ArtifactInfo[] = [];\n\n if (!flags.json) {\n await mkdir(outputDir, { recursive: true });\n\n if (markdown && (format === 'md' || format === 'both')) {\n const changelogPath = join(outputDir, 'CHANGELOG.md');\n\n // Read existing and prepend new content (newest first)\n let existing = '';\n try {\n existing = await readFile(changelogPath, 'utf-8');\n const footerStart = existing.indexOf('\\n---\\n\\n*Generated automatically');\n if (footerStart !== -1) {\n existing = existing.substring(0, footerStart);\n }\n } catch { /* file doesn't exist yet */ }\n\n const combined = existing ? `${markdown}\\n\\n${existing}` : markdown;\n await writeFile(changelogPath, combined, 'utf-8');\n\n const stats = await stat(changelogPath);\n artifacts.push({\n name: 'Changelog',\n path: changelogPath,\n size: stats.size,\n modified: stats.mtime,\n description: 'Generated changelog in Markdown format',\n });\n }\n }\n\n loader.succeed('Changelog generated successfully');\n\n // 5. Output\n if (flags.json) {\n ctx.ui?.json?.({\n packagesCount: plan.packages.length,\n markdown: format === 'md' || format === 'both' ? markdown : undefined,\n artifacts: artifacts.map(a => ({ name: a.name, path: a.path, size: a.size ?? 0 })),\n });\n } else {\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n sections.push({\n header: 'Summary',\n items: [\n `Packages: ${plan.packages.map(p => p.name).join(', ')}`,\n `Format: ${format === 'both' ? 'Markdown + JSON' : format}`,\n ],\n });\n\n if (artifacts.length > 0) {\n const artifactsLines = displayArtifacts(artifacts, {\n showSize: true,\n showTime: true,\n showDescription: true,\n maxItems: 10,\n title: '',\n });\n sections.push({ header: 'Artifacts', items: artifactsLines });\n }\n\n ctx.ui.sideBox({\n title: 'Changelog Generated',\n sections,\n status: 'success',\n });\n }\n\n return {\n exitCode: 0,\n artifacts: artifacts.map(a => ({ name: a.name, path: a.path, size: a.size ?? 0 })),\n };\n },\n },\n});\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
interface PlanFlags {
|
|
5
|
+
scope?: string;
|
|
6
|
+
bump?: 'patch' | 'minor' | 'major' | 'auto';
|
|
7
|
+
strict?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<PlanFlags>, unknown>;
|
|
11
|
+
|
|
12
|
+
export { _default as default };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { defineCommand, findRepoRoot, useLoader, useConfig, displayArtifacts } from '@kb-labs/sdk';
|
|
2
|
+
import { planRelease } from '@kb-labs/release-manager-core';
|
|
3
|
+
import 'path';
|
|
4
|
+
import 'fs/promises';
|
|
5
|
+
import 'globby';
|
|
6
|
+
|
|
7
|
+
// src/cli/commands/plan.ts
|
|
8
|
+
function scopeToDir(scope) {
|
|
9
|
+
return scope.replace(/^@/, "").replace(/\//g, "-").replace(/:/g, "-").replace(/\*/g, "");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// src/cli/commands/plan.ts
|
|
13
|
+
var plan_default = defineCommand({
|
|
14
|
+
id: "release:plan",
|
|
15
|
+
description: "Analyze changes and prepare release plan",
|
|
16
|
+
handler: {
|
|
17
|
+
async execute(ctx, input) {
|
|
18
|
+
const { flags } = input;
|
|
19
|
+
const cwd = ctx.cwd || process.cwd();
|
|
20
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
21
|
+
const configLoader = useLoader("Loading release configuration...");
|
|
22
|
+
configLoader.start();
|
|
23
|
+
const fileConfig = await useConfig();
|
|
24
|
+
const config = {
|
|
25
|
+
...fileConfig,
|
|
26
|
+
...flags.bump && { bump: flags.bump },
|
|
27
|
+
...flags.strict !== void 0 && { strict: flags.strict }
|
|
28
|
+
};
|
|
29
|
+
configLoader.succeed("Configuration loaded");
|
|
30
|
+
const planLoader = useLoader("Discovering packages and planning release...");
|
|
31
|
+
planLoader.start();
|
|
32
|
+
const plan = await planRelease({
|
|
33
|
+
cwd: repoRoot,
|
|
34
|
+
config,
|
|
35
|
+
scope: flags.scope,
|
|
36
|
+
bumpOverride: flags.bump
|
|
37
|
+
});
|
|
38
|
+
if (plan.packages.length === 0) {
|
|
39
|
+
planLoader.fail(`No packages found matching scope: ${flags.scope || "all"}`);
|
|
40
|
+
} else {
|
|
41
|
+
planLoader.succeed(`Found ${plan.packages.length} package(s) to release`);
|
|
42
|
+
}
|
|
43
|
+
const scopeDir = scopeToDir(flags.scope ?? "root");
|
|
44
|
+
const planDir = ctx.runtime.fs.join(repoRoot, ".kb", "release", "plans", scopeDir, "current");
|
|
45
|
+
const planPath = ctx.runtime.fs.join(planDir, "plan.json");
|
|
46
|
+
const artifacts = [];
|
|
47
|
+
if (!flags.json) {
|
|
48
|
+
await ctx.runtime.fs.mkdir(planDir, { recursive: true });
|
|
49
|
+
await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: "utf-8" });
|
|
50
|
+
const stats = await ctx.runtime.fs.stat(planPath);
|
|
51
|
+
artifacts.push({
|
|
52
|
+
name: "Release Plan",
|
|
53
|
+
path: planPath,
|
|
54
|
+
size: stats.size,
|
|
55
|
+
modified: new Date(stats.mtime),
|
|
56
|
+
description: "Detailed release plan (JSON)"
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
ctx.platform?.logger?.info?.("Release plan completed", {
|
|
60
|
+
packagesCount: plan.packages.length,
|
|
61
|
+
strategy: plan.strategy,
|
|
62
|
+
registry: plan.registry
|
|
63
|
+
});
|
|
64
|
+
if (flags.json) {
|
|
65
|
+
ctx.ui?.json?.(plan);
|
|
66
|
+
} else {
|
|
67
|
+
const sections = [];
|
|
68
|
+
sections.push({
|
|
69
|
+
header: "Summary",
|
|
70
|
+
items: [
|
|
71
|
+
`Strategy: ${plan.strategy}`,
|
|
72
|
+
`Registry: ${plan.registry}`,
|
|
73
|
+
`Packages: ${plan.packages.length}`
|
|
74
|
+
]
|
|
75
|
+
});
|
|
76
|
+
if (plan.packages.length > 0) {
|
|
77
|
+
const packageItems = [];
|
|
78
|
+
for (const pkg of plan.packages) {
|
|
79
|
+
const versionInfo = pkg.currentVersion && pkg.nextVersion ? `${pkg.currentVersion} \u2192 ${pkg.nextVersion}` : pkg.nextVersion || "new";
|
|
80
|
+
packageItems.push(`${ctx.ui.symbols.success} ${pkg.name}: ${versionInfo}`);
|
|
81
|
+
}
|
|
82
|
+
sections.push({
|
|
83
|
+
header: "Packages to release",
|
|
84
|
+
items: packageItems
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
sections.push({
|
|
88
|
+
items: ["No packages to release"]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (artifacts.length > 0) {
|
|
92
|
+
const artifactsLines = displayArtifacts(artifacts, {
|
|
93
|
+
showSize: true,
|
|
94
|
+
showTime: true,
|
|
95
|
+
showDescription: true,
|
|
96
|
+
maxItems: 10,
|
|
97
|
+
title: ""
|
|
98
|
+
});
|
|
99
|
+
sections.push({
|
|
100
|
+
header: "Artifacts",
|
|
101
|
+
items: artifactsLines
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
ctx.ui.sideBox({
|
|
105
|
+
title: "Release Plan",
|
|
106
|
+
sections,
|
|
107
|
+
status: "success"
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return { exitCode: 0, plan };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export { plan_default as default };
|
|
116
|
+
//# sourceMappingURL=plan.js.map
|
|
117
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/cli/commands/plan.ts"],"names":[],"mappings":"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","file":"plan.js","sourcesContent":["import { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport globby from 'globby';\n\nexport { findRepoRoot } from '@kb-labs/sdk';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n\n/**\n * Resolve scope name to absolute filesystem path.\n * Scans all package.json in repoRoot to find the matching package by name.\n */\nexport async function resolveScopePath(repoRoot: string, scope: string): Promise<string> {\n if (scope === 'root') {\n return repoRoot;\n }\n\n if (scope.startsWith('@')) {\n const packageJsonPaths = await globby('**/package.json', {\n cwd: repoRoot,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/.*/**'],\n });\n\n for (const pkgJsonPath of packageJsonPaths) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n if (pkg.name === scope) {\n return join(pkgJsonPath, '..');\n }\n } catch { /* skip */ }\n }\n }\n\n // Direct path or fallback\n return join(repoRoot, scope);\n}\n","/**\n * Release plan command\n */\n\nimport {\n defineCommand,\n type CLIInput,\n type CommandResult,\n type PluginContextV3,\n useLoader,\n displayArtifacts,\n type ArtifactInfo,\n useConfig,\n} from '@kb-labs/sdk';\nimport { planRelease, type VersionBump, type ReleaseConfig } from '@kb-labs/release-manager-core';\nimport { findRepoRoot, scopeToDir } from '../../shared/utils';\n\ninterface PlanFlags {\n scope?: string;\n bump?: 'patch' | 'minor' | 'major' | 'auto';\n strict?: boolean;\n json?: boolean;\n}\n\ntype ReleasePlanResult = CommandResult & {\n plan?: {\n strategy: string;\n registry: string;\n packages: Array<{\n name: string;\n currentVersion?: string;\n nextVersion?: string;\n }>;\n };\n};\n\nexport default defineCommand({\n id: 'release:plan',\n description: 'Analyze changes and prepare release plan',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<PlanFlags>): Promise<ReleasePlanResult> {\n const { flags } = input;\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n // Load configuration\n const configLoader = useLoader('Loading release configuration...');\n configLoader.start();\n\n const fileConfig = await useConfig<ReleaseConfig>();\n\n // Merge CLI overrides\n const config: ReleaseConfig = {\n ...fileConfig,\n ...(flags.bump && { bump: flags.bump }),\n ...(flags.strict !== undefined && { strict: flags.strict }),\n };\n\n configLoader.succeed('Configuration loaded');\n\n // Create release plan\n const planLoader = useLoader('Discovering packages and planning release...');\n planLoader.start();\n\n const plan = await planRelease({\n cwd: repoRoot,\n config,\n scope: flags.scope,\n bumpOverride: flags.bump as VersionBump | undefined,\n });\n\n if (plan.packages.length === 0) {\n planLoader.fail(`No packages found matching scope: ${flags.scope || 'all'}`);\n } else {\n planLoader.succeed(`Found ${plan.packages.length} package(s) to release`);\n }\n\n // Save plan to .kb/release/plans/{scope}/current/plan.json\n const scopeDir = scopeToDir(flags.scope ?? 'root');\n const planDir = ctx.runtime.fs.join(repoRoot, '.kb', 'release', 'plans', scopeDir, 'current');\n const planPath = ctx.runtime.fs.join(planDir, 'plan.json');\n const artifacts: ArtifactInfo[] = [];\n\n if (!flags.json) {\n await ctx.runtime.fs.mkdir(planDir, { recursive: true });\n await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: 'utf-8' });\n\n const stats = await ctx.runtime.fs.stat(planPath);\n artifacts.push({\n name: 'Release Plan',\n path: planPath,\n size: stats.size,\n modified: new Date(stats.mtime),\n description: 'Detailed release plan (JSON)',\n });\n }\n\n ctx.platform?.logger?.info?.('Release plan completed', {\n packagesCount: plan.packages.length,\n strategy: plan.strategy,\n registry: plan.registry,\n });\n\n if (flags.json) {\n ctx.ui?.json?.(plan);\n } else {\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n // Summary\n sections.push({\n header: 'Summary',\n items: [\n `Strategy: ${plan.strategy}`,\n `Registry: ${plan.registry}`,\n `Packages: ${plan.packages.length}`,\n ],\n });\n\n // Packages section\n if (plan.packages.length > 0) {\n const packageItems: string[] = [];\n for (const pkg of plan.packages) {\n const versionInfo =\n pkg.currentVersion && pkg.nextVersion\n ? `${pkg.currentVersion} → ${pkg.nextVersion}`\n : pkg.nextVersion || 'new';\n packageItems.push(`${ctx.ui.symbols.success} ${pkg.name}: ${versionInfo}`);\n }\n sections.push({\n header: 'Packages to release',\n items: packageItems,\n });\n } else {\n sections.push({\n items: ['No packages to release'],\n });\n }\n\n // Artifacts section\n if (artifacts.length > 0) {\n const artifactsLines = displayArtifacts(artifacts, {\n showSize: true,\n showTime: true,\n showDescription: true,\n maxItems: 10,\n title: '',\n });\n sections.push({\n header: 'Artifacts',\n items: artifactsLines,\n });\n }\n\n ctx.ui.sideBox({\n title: 'Release Plan',\n sections,\n status: 'success',\n });\n }\n\n return { exitCode: 0, plan };\n },\n },\n});\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
interface PublishFlags {
|
|
5
|
+
scope?: string;
|
|
6
|
+
otp?: string;
|
|
7
|
+
'dry-run'?: boolean;
|
|
8
|
+
tag?: string;
|
|
9
|
+
access?: string;
|
|
10
|
+
token?: string;
|
|
11
|
+
json?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<PublishFlags>, unknown>;
|
|
14
|
+
|
|
15
|
+
export { _default as default };
|