@versatiles/release-tool 2.6.0 → 2.7.1

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 CHANGED
@@ -203,41 +203,51 @@ flowchart TB
203
203
  subgraph 0["src"]
204
204
  subgraph 1["commands"]
205
205
  2["check.ts"]
206
- 5["deps-graph.ts"]
207
- 6["deps-upgrade.ts"]
208
- 8["doc-command.ts"]
209
- A["doc-typescript.ts"]
210
- B["markdown.ts"]
211
- C["release-npm.ts"]
206
+ 6["deps-graph.ts"]
207
+ 7["deps-upgrade.ts"]
208
+ 9["doc-command.ts"]
209
+ B["doc-typescript.ts"]
210
+ C["markdown.ts"]
211
+ D["release-npm.ts"]
212
212
  end
213
213
  subgraph 3["lib"]
214
214
  4["log.ts"]
215
- 7["shell.ts"]
216
- 9["utils.ts"]
217
- D["git.ts"]
215
+ 5["errors.ts"]
216
+ 8["shell.ts"]
217
+ A["utils.ts"]
218
+ E["changelog.ts"]
219
+ F["git.ts"]
220
+ G["retry.ts"]
221
+ I["benchmark.ts"]
218
222
  end
219
- E["index.ts"]
223
+ H["index.ts"]
220
224
  end
221
225
  2-->4
222
- 5-->4
226
+ 4-->5
223
227
  6-->4
224
- 6-->7
225
228
  7-->4
226
- 8-->9
227
- A-->4
228
- B-->9
229
- C-->D
230
- C-->4
231
- C-->7
232
- D-->7
233
- E-->2
234
- E-->5
235
- E-->6
236
- E-->8
237
- E-->A
238
- E-->B
239
- E-->C
240
- E-->4
229
+ 7-->8
230
+ 8-->4
231
+ 9-->A
232
+ B-->4
233
+ C-->5
234
+ C-->A
235
+ D-->E
236
+ D-->5
237
+ D-->F
238
+ D-->4
239
+ D-->G
240
+ D-->8
241
+ E-->F
242
+ F-->8
243
+ H-->2
244
+ H-->6
245
+ H-->7
246
+ H-->9
247
+ H-->B
248
+ H-->C
249
+ H-->D
250
+ H-->4
241
251
 
242
252
  class 0,1,3 subgraphs;
243
253
  classDef subgraphs fill-opacity:0.1, fill:#888, color:#888, stroke:#888;
@@ -1,3 +1,27 @@
1
+ /**
2
+ * Runs all project checks including package.json and workflow validation.
3
+ *
4
+ * @param directory - The project directory to check
5
+ */
1
6
  export declare function check(directory: string): void;
7
+ /**
8
+ * Validates package.json configuration for VersaTiles projects.
9
+ *
10
+ * Checks for:
11
+ * - Required scripts (build, check, prepack, release)
12
+ * - Recommended scripts (test, doc, upgrade, doc-graph)
13
+ * - Script configurations following best practices
14
+ * - Unnecessary dependencies
15
+ *
16
+ * @param directory - The project directory containing package.json
17
+ * @throws {VrtError} If package.json is missing required scripts
18
+ */
2
19
  export declare function checkPackage(directory: string): void;
20
+ /**
21
+ * Validates GitHub Actions workflow configuration.
22
+ *
23
+ * Checks for the presence of expected workflow files.
24
+ *
25
+ * @param directory - The project directory to check
26
+ */
3
27
  export declare function checkWorkflow(directory: string): void;
@@ -1,10 +1,27 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
- import { panic, info, warn } from '../lib/log.js';
3
2
  import { resolve } from 'path';
3
+ import { info, panic, warn } from '../lib/log.js';
4
+ /**
5
+ * Runs all project checks including package.json and workflow validation.
6
+ *
7
+ * @param directory - The project directory to check
8
+ */
4
9
  export function check(directory) {
5
10
  checkPackage(directory);
6
11
  checkWorkflow(directory);
7
12
  }
13
+ /**
14
+ * Validates package.json configuration for VersaTiles projects.
15
+ *
16
+ * Checks for:
17
+ * - Required scripts (build, check, prepack, release)
18
+ * - Recommended scripts (test, doc, upgrade, doc-graph)
19
+ * - Script configurations following best practices
20
+ * - Unnecessary dependencies
21
+ *
22
+ * @param directory - The project directory containing package.json
23
+ * @throws {VrtError} If package.json is missing required scripts
24
+ */
8
25
  export function checkPackage(directory) {
9
26
  const pack = JSON.parse(readFileSync(resolve(directory, 'package.json'), 'utf8'));
10
27
  const { scripts } = pack;
@@ -60,6 +77,13 @@ export function checkPackage(directory) {
60
77
  }
61
78
  });
62
79
  }
80
+ /**
81
+ * Validates GitHub Actions workflow configuration.
82
+ *
83
+ * Checks for the presence of expected workflow files.
84
+ *
85
+ * @param directory - The project directory to check
86
+ */
63
87
  export function checkWorkflow(directory) {
64
88
  if (!existsSync(resolve(directory, '.github/workflows/pages.yml'))) {
65
89
  info('GitHub Pages workflow not found');
@@ -1 +1,23 @@
1
+ /**
2
+ * Generates a Mermaid dependency graph for the project's source files.
3
+ *
4
+ * Uses dependency-cruiser to analyze imports and outputs a Mermaid flowchart
5
+ * diagram to stdout. The output is wrapped in markdown code blocks for
6
+ * easy inclusion in documentation.
7
+ *
8
+ * Configuration:
9
+ * - Only includes files from `src/` directory
10
+ * - Excludes test files, declaration files, and mocks
11
+ * - Uses ELK layout for better graph rendering
12
+ *
13
+ * @param directory - The project directory to analyze
14
+ * @throws {VrtError} If dependency analysis fails
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * // Generate graph and pipe to doc-insert
19
+ * await generateDependencyGraph('./');
20
+ * // Output: ```mermaid\nflowchart TB\n...\n```
21
+ * ```
22
+ */
1
23
  export declare function generateDependencyGraph(directory: string): Promise<void>;
@@ -1,12 +1,34 @@
1
1
  import { cruise } from 'dependency-cruiser';
2
2
  import { panic } from '../lib/log.js';
3
+ /**
4
+ * Generates a Mermaid dependency graph for the project's source files.
5
+ *
6
+ * Uses dependency-cruiser to analyze imports and outputs a Mermaid flowchart
7
+ * diagram to stdout. The output is wrapped in markdown code blocks for
8
+ * easy inclusion in documentation.
9
+ *
10
+ * Configuration:
11
+ * - Only includes files from `src/` directory
12
+ * - Excludes test files, declaration files, and mocks
13
+ * - Uses ELK layout for better graph rendering
14
+ *
15
+ * @param directory - The project directory to analyze
16
+ * @throws {VrtError} If dependency analysis fails
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Generate graph and pipe to doc-insert
21
+ * await generateDependencyGraph('./');
22
+ * // Output: ```mermaid\nflowchart TB\n...\n```
23
+ * ```
24
+ */
3
25
  export async function generateDependencyGraph(directory) {
4
26
  let cruiseResult;
5
27
  try {
6
28
  cruiseResult = await cruise([directory], {
7
29
  includeOnly: '^src',
8
30
  outputType: 'mermaid',
9
- exclude: ['\\.(test|d)\\.ts$', 'node_modules', '__mocks__/'],
31
+ exclude: ['\\.(test|d|mock)\\.ts$', 'node_modules', '__mocks__/'],
10
32
  });
11
33
  }
12
34
  catch (pError) {
@@ -24,7 +24,7 @@ export async function upgradeDependencies(directory) {
24
24
  });
25
25
  });
26
26
  const shell = new Shell(directory);
27
- await check('Remove lock file and node_modules', shell.stdout('rm -f package-lock.json && rm -rf node_modules'));
27
+ await shell.run('rm -f package-lock.json && rm -rf node_modules', false);
28
28
  await check('Reinstall all dependencies', shell.stdout('npm i'));
29
29
  // Final log message
30
30
  info('All dependencies are up to date');
@@ -1,6 +1,42 @@
1
- export declare function generateTypescriptDocs(options: {
1
+ /**
2
+ * Output format for generated TypeScript documentation.
3
+ */
4
+ export type DocFormat = 'markdown' | 'wiki' | 'html';
5
+ /**
6
+ * Options for generating TypeScript documentation.
7
+ */
8
+ export interface TypescriptDocOptions {
9
+ /** Path to the entry point file (default: './src/index.ts') */
2
10
  entryPoint?: string;
11
+ /** Output directory for generated docs (default: './docs') */
3
12
  outputPath?: string;
4
- format?: 'markdown' | 'wiki' | 'html';
13
+ /** Documentation format: 'markdown', 'wiki', or 'html' (default: 'markdown') */
14
+ format?: DocFormat;
15
+ /** Suppress info-level logging (default: false) */
5
16
  quiet?: boolean;
6
- }): Promise<void>;
17
+ }
18
+ /**
19
+ * Generates TypeScript documentation using TypeDoc.
20
+ *
21
+ * Supports multiple output formats:
22
+ * - `markdown`: Standard Markdown files using typedoc-plugin-markdown
23
+ * - `wiki`: GitHub Wiki compatible Markdown using typedoc-github-wiki-theme
24
+ * - `html`: HTML documentation using typedoc-github-theme
25
+ *
26
+ * @param options - Configuration options for documentation generation
27
+ * @throws {VrtError} If project conversion fails or validation errors occur
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * // Generate markdown docs from default entry point
32
+ * await generateTypescriptDocs({ format: 'markdown' });
33
+ *
34
+ * // Generate HTML docs to custom directory
35
+ * await generateTypescriptDocs({
36
+ * entryPoint: './src/main.ts',
37
+ * outputPath: './api-docs',
38
+ * format: 'html'
39
+ * });
40
+ * ```
41
+ */
42
+ export declare function generateTypescriptDocs(options: TypescriptDocOptions): Promise<void>;
@@ -1,5 +1,29 @@
1
1
  import * as td from 'typedoc';
2
2
  import { panic, warn } from '../lib/log.js';
3
+ /**
4
+ * Generates TypeScript documentation using TypeDoc.
5
+ *
6
+ * Supports multiple output formats:
7
+ * - `markdown`: Standard Markdown files using typedoc-plugin-markdown
8
+ * - `wiki`: GitHub Wiki compatible Markdown using typedoc-github-wiki-theme
9
+ * - `html`: HTML documentation using typedoc-github-theme
10
+ *
11
+ * @param options - Configuration options for documentation generation
12
+ * @throws {VrtError} If project conversion fails or validation errors occur
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // Generate markdown docs from default entry point
17
+ * await generateTypescriptDocs({ format: 'markdown' });
18
+ *
19
+ * // Generate HTML docs to custom directory
20
+ * await generateTypescriptDocs({
21
+ * entryPoint: './src/main.ts',
22
+ * outputPath: './api-docs',
23
+ * format: 'html'
24
+ * });
25
+ * ```
26
+ */
3
27
  export async function generateTypescriptDocs(options) {
4
28
  const { entryPoint, outputPath, quiet } = options;
5
29
  const format = options.format ?? 'markdown';
@@ -1,4 +1,4 @@
1
- import type { Root, PhrasingContent } from 'mdast';
1
+ import type { PhrasingContent, Root } from 'mdast';
2
2
  /**
3
3
  * Injects a Markdown segment under a specified heading in a Markdown document.
4
4
  * Optionally, the injected segment can be made foldable for better readability.
@@ -17,5 +17,13 @@ export declare function injectMarkdown(document: string, segment: string, headin
17
17
  * @returns The Markdown document with an updated TOC.
18
18
  */
19
19
  export declare function updateTOC(main: string, heading: string): string;
20
+ /**
21
+ * Converts a PhrasingContent node to its HTML representation.
22
+ * Handles all PhrasingContent types defined in mdast.
23
+ *
24
+ * @param node The phrasing content node to convert.
25
+ * @returns The HTML string representation.
26
+ * @throws {VrtError} For reference types that require resolution (footnote, image, link references).
27
+ */
20
28
  export declare function nodeToHtml(node: PhrasingContent): string;
21
29
  export declare function parseMarkdown(document: string): Root;
@@ -1,6 +1,7 @@
1
1
  import { remark } from 'remark';
2
2
  import remarkGfm from 'remark-gfm';
3
3
  import remarkStringify from 'remark-stringify';
4
+ import { markdownError, notImplementedError } from '../lib/errors.js';
4
5
  import { getErrorMessage } from '../lib/utils.js';
5
6
  // Custom blockquote handler that preserves GitHub alert syntax
6
7
  function blockquoteHandler(node, _parent, state, info) {
@@ -36,7 +37,7 @@ export function injectMarkdown(document, segment, heading, foldable) {
36
37
  }
37
38
  catch (error) {
38
39
  // Handle errors during the search for the start index.
39
- throw new Error(`Error while searching for segment "${heading}": ${getErrorMessage(error)}`);
40
+ throw markdownError(`Error while searching for segment "${heading}": ${getErrorMessage(error)}`);
40
41
  }
41
42
  // Get the depth of the specified heading to maintain the structure.
42
43
  const depth = getHeadingDepth(documentAst, startIndex);
@@ -102,9 +103,9 @@ export function updateTOC(main, heading) {
102
103
  function findSegmentStartIndex(mainAst, headingAst) {
103
104
  // Verify the structure of the headingAst.
104
105
  if (headingAst.children.length !== 1)
105
- throw Error('headingAst.children.length !== 1');
106
+ throw markdownError('headingAst.children.length !== 1');
106
107
  if (headingAst.children[0].type !== 'heading')
107
- throw Error("headingAst.children[0].type !== 'heading'");
108
+ throw markdownError("headingAst.children[0].type !== 'heading'");
108
109
  const sectionDepth = headingAst.children[0].depth;
109
110
  const sectionText = extractTextFromMDAsHTML(headingAst);
110
111
  // Search for the index of the heading in the main document AST.
@@ -116,9 +117,9 @@ function findSegmentStartIndex(mainAst, headingAst) {
116
117
  });
117
118
  // Handle the cases of no match or multiple matches.
118
119
  if (indexes.length < 1)
119
- throw Error('section not found');
120
+ throw markdownError('section not found');
120
121
  if (indexes.length > 1)
121
- throw Error('too many sections found');
122
+ throw markdownError('too many sections found');
122
123
  return indexes[0];
123
124
  }
124
125
  /**
@@ -148,7 +149,7 @@ function findNextHeadingIndex(mainAst, startIndex, depth) {
148
149
  function getHeadingDepth(mainAst, index) {
149
150
  const node = mainAst.children[index];
150
151
  if (node.type !== 'heading')
151
- throw Error("node.type !== 'heading'");
152
+ throw markdownError("node.type !== 'heading'");
152
153
  return node.depth;
153
154
  }
154
155
  /**
@@ -174,47 +175,108 @@ function mergeSegments(mainAst, segmentAst, startIndex, endIndex) {
174
175
  }
175
176
  /**
176
177
  * Extracts the textual content from a node in the AST.
177
- * @param node The AST node.
178
- * @returns The extracted text content.
179
- * @throws Error if the node type is unknown.
178
+ * Recursively processes nodes with children and extracts text values.
179
+ *
180
+ * @param node The AST node (Root or any RootContent type).
181
+ * @returns The extracted text content as HTML-escaped string.
180
182
  */
181
183
  function extractTextFromMDAsHTML(node) {
182
184
  switch (node.type) {
185
+ // Nodes with direct text value
183
186
  case 'inlineCode':
184
187
  case 'text':
185
188
  return textToHtml(node.value);
189
+ // Nodes with children to recurse into
186
190
  case 'heading':
187
191
  case 'root':
188
- return node.children.map(extractTextFromMDAsHTML).join('');
192
+ case 'paragraph':
193
+ case 'blockquote':
194
+ case 'listItem':
195
+ case 'tableCell':
196
+ case 'tableRow':
197
+ case 'link':
198
+ case 'emphasis':
199
+ case 'strong':
200
+ case 'delete':
201
+ return node.children.map((child) => extractTextFromMDAsHTML(child)).join('');
202
+ // Nodes with children but need special handling
203
+ case 'list':
204
+ return node.children.map((child) => extractTextFromMDAsHTML(child)).join('');
205
+ case 'table':
206
+ return node.children.map((child) => extractTextFromMDAsHTML(child)).join('');
207
+ // Nodes with alt text
208
+ case 'image':
209
+ return node.alt ? textToHtml(node.alt) : '';
210
+ // Nodes that don't contribute text content
189
211
  case 'html':
212
+ case 'code':
213
+ case 'thematicBreak':
214
+ case 'break':
215
+ case 'definition':
216
+ case 'footnoteDefinition':
217
+ case 'footnoteReference':
218
+ case 'imageReference':
219
+ case 'linkReference':
220
+ case 'yaml':
190
221
  return '';
191
- default:
192
- throw Error('unknown type: ' + node.type);
222
+ default: {
223
+ // TypeScript exhaustive check - this ensures we handle all types
224
+ const _exhaustiveCheck = node;
225
+ throw markdownError(`unhandled node type: ${node.type}`);
226
+ }
193
227
  }
194
228
  }
195
229
  /**
196
230
  * Generates an anchor ID for a Markdown heading based on its text content.
231
+ * Handles all PhrasingContent types that can appear in a heading.
232
+ *
197
233
  * @param node The heading node.
198
- * @returns The generated anchor ID.
199
- * @throws Error if the child node type is unknown.
234
+ * @returns The generated anchor ID, formatted for use in URLs.
200
235
  */
201
236
  function getMDAnchor(node) {
202
237
  let text = '';
203
238
  for (const c of node.children) {
204
239
  // Handle different types of child nodes to construct the anchor text.
205
240
  switch (c.type) {
241
+ // Check for explicit ID in HTML
206
242
  case 'html': {
207
243
  const match = /<a\s.*id\s*=\s*['"]([^'"]+)/i.exec(c.value);
208
244
  if (match)
209
245
  return match[1];
210
246
  break;
211
247
  }
248
+ // Nodes with direct text value
212
249
  case 'text':
213
250
  case 'inlineCode':
214
251
  text += c.value;
215
252
  break;
216
- default:
217
- throw Error('unknown type: ' + c.type);
253
+ // Nodes with children - recurse to extract text
254
+ case 'emphasis':
255
+ case 'strong':
256
+ case 'delete':
257
+ case 'link':
258
+ for (const child of c.children) {
259
+ if (child.type === 'text' || child.type === 'inlineCode') {
260
+ text += child.value;
261
+ }
262
+ }
263
+ break;
264
+ // Image - use alt text
265
+ case 'image':
266
+ if (c.alt)
267
+ text += c.alt;
268
+ break;
269
+ // Nodes that don't contribute to anchor text
270
+ case 'break':
271
+ case 'footnoteReference':
272
+ case 'imageReference':
273
+ case 'linkReference':
274
+ break;
275
+ default: {
276
+ // TypeScript exhaustive check
277
+ const _exhaustiveCheck = c;
278
+ throw markdownError(`unhandled phrasing content type: ${c.type}`);
279
+ }
218
280
  }
219
281
  }
220
282
  // Format the text to create a suitable anchor ID.
@@ -227,6 +289,8 @@ function getMDAnchor(node) {
227
289
  }
228
290
  /**
229
291
  * Converts a segment of the AST into a foldable HTML element.
292
+ * Headings become collapsible `<details>` sections.
293
+ *
230
294
  * @param ast The AST of the segment to be converted.
231
295
  */
232
296
  function convertToFoldable(ast) {
@@ -234,19 +298,56 @@ function convertToFoldable(ast) {
234
298
  const children = [];
235
299
  ast.children.forEach((c) => {
236
300
  switch (c.type) {
237
- case 'html':
238
- case 'list':
239
- case 'paragraph':
240
- children.push(c);
241
- break;
301
+ // Headings start new foldable sections
242
302
  case 'heading':
243
303
  closeDetails(c.depth);
244
304
  children.push({ type: 'html', value: '<details>' });
245
305
  children.push({ type: 'html', value: `<summary>${lineToHtml(c)}</summary>` });
246
306
  openDetails.unshift(c.depth);
247
307
  break;
248
- default:
249
- throw Error(`unknown type "${c.type}"`);
308
+ // Block content that gets included in sections
309
+ case 'html':
310
+ case 'list':
311
+ case 'paragraph':
312
+ case 'blockquote':
313
+ case 'code':
314
+ case 'table':
315
+ case 'thematicBreak':
316
+ children.push(c);
317
+ break;
318
+ // Definition content - include as-is
319
+ case 'definition':
320
+ case 'footnoteDefinition':
321
+ children.push(c);
322
+ break;
323
+ // YAML frontmatter - include as-is
324
+ case 'yaml':
325
+ children.push(c);
326
+ break;
327
+ // Inline/phrasing content that shouldn't appear at root level
328
+ // but handle gracefully if present
329
+ case 'text':
330
+ case 'inlineCode':
331
+ case 'emphasis':
332
+ case 'strong':
333
+ case 'delete':
334
+ case 'link':
335
+ case 'image':
336
+ case 'break':
337
+ case 'footnoteReference':
338
+ case 'imageReference':
339
+ case 'linkReference':
340
+ case 'listItem':
341
+ case 'tableCell':
342
+ case 'tableRow':
343
+ // These shouldn't normally appear at root level, but pass through
344
+ children.push(c);
345
+ break;
346
+ default: {
347
+ // TypeScript exhaustive check
348
+ const _exhaustiveCheck = c;
349
+ throw markdownError(`unhandled root content type: ${c.type}`);
350
+ }
250
351
  }
251
352
  });
252
353
  closeDetails(0);
@@ -261,6 +362,14 @@ function convertToFoldable(ast) {
261
362
  function lineToHtml(heading) {
262
363
  return `<h${heading.depth}>${nodesToHtml(heading.children)}</h${heading.depth}>`;
263
364
  }
365
+ /**
366
+ * Converts a PhrasingContent node to its HTML representation.
367
+ * Handles all PhrasingContent types defined in mdast.
368
+ *
369
+ * @param node The phrasing content node to convert.
370
+ * @returns The HTML string representation.
371
+ * @throws {VrtError} For reference types that require resolution (footnote, image, link references).
372
+ */
264
373
  export function nodeToHtml(node) {
265
374
  switch (node.type) {
266
375
  case 'html':
@@ -287,14 +396,18 @@ export function nodeToHtml(node) {
287
396
  attributes.push(`title="${node.title}"`);
288
397
  return `<img ${attributes.join(' ')} />`;
289
398
  }
399
+ // Reference types require definition resolution which is not supported
290
400
  case 'footnoteReference':
291
- throw new Error('Not implemented yet: "footnoteReference" case');
401
+ throw notImplementedError('footnoteReference - requires definition resolution');
292
402
  case 'imageReference':
293
- throw new Error('Not implemented yet: "imageReference" case');
403
+ throw notImplementedError('imageReference - requires definition resolution');
294
404
  case 'linkReference':
295
- throw new Error('Not implemented yet: "linkReference" case');
296
- default:
297
- throw Error('unknown type');
405
+ throw notImplementedError('linkReference - requires definition resolution');
406
+ default: {
407
+ // TypeScript exhaustive check
408
+ const _exhaustiveCheck = node;
409
+ throw markdownError(`unhandled phrasing content type: ${node.type}`);
410
+ }
298
411
  }
299
412
  }
300
413
  function nodesToHtml(children) {
@@ -1,2 +1,45 @@
1
1
  #!/usr/bin/env npx tsx
2
+ /**
3
+ * Options for the release process.
4
+ */
5
+ export interface ReleaseOptions {
6
+ /** The project directory containing package.json (default: current directory) */
7
+ directory?: string;
8
+ /** The git branch to release from (default: 'main') */
9
+ branch?: string;
10
+ /** If true, simulate the release without making changes (default: false) */
11
+ dryRun?: boolean;
12
+ }
13
+ /**
14
+ * Executes the npm release process.
15
+ *
16
+ * This function performs a complete release workflow:
17
+ * 1. Validates git state (correct branch, no uncommitted changes)
18
+ * 2. Pulls latest changes from remote
19
+ * 3. Verifies npm authentication
20
+ * 4. Prompts for new version (with suggestion based on conventional commits)
21
+ * 5. Runs project checks
22
+ * 6. Updates package.json version
23
+ * 7. Updates CHANGELOG.md
24
+ * 8. Publishes to npm (if not private)
25
+ * 9. Creates git commit and tag
26
+ * 10. Pushes to remote and creates GitHub release
27
+ *
28
+ * @param directory - The project directory containing package.json
29
+ * @param branch - The git branch to release from (default: 'main')
30
+ * @param dryRun - If true, simulate the release without making changes
31
+ * @throws {VrtError} If any step in the release process fails
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // Standard release from main branch
36
+ * await release('/path/to/project');
37
+ *
38
+ * // Dry run to preview release
39
+ * await release('/path/to/project', 'main', true);
40
+ *
41
+ * // Release from a different branch
42
+ * await release('/path/to/project', 'release');
43
+ * ```
44
+ */
2
45
  export declare function release(directory: string, branch?: string, dryRun?: boolean): Promise<void>;