[docs] Add API changelog generation demo

Add comprehensive demo showing API changelog generation across two versions (v1.29.0 → v1.30.2):

- Mock TypeScript definitions for both versions
- Generated JSON snapshots showing structured API surface
- Generated changelog with breaking changes, additions, and modifications
- Detailed README explaining the system and benefits

The demo showcases:
 Detection of breaking changes (queuePrompt → queuePromptAsync)
 Tracking of new additions (ExtensionMetadata interface, WorkflowId type)
 Identification of modifications (NodeDef enhancements, NodeStatus enum extensions)

This demonstrates the automated system that will run on every release to document API changes for extension developers.

Also exclude demo-snapshots directory from ESLint checking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
snomiao
2025-11-01 12:21:37 +00:00
parent 11922709a9
commit 75daf2e4d2
7 changed files with 892 additions and 1 deletions

View File

@@ -0,0 +1,49 @@
## v1.30.2 (2025-11-01)
Comparing v1.29.0 → v1.30.2. This changelog documents changes to the public API surface that third-party extensions and custom nodes depend on.
### ✨ Additions
**Type Aliases**
- `WorkflowId`
**Interfaces**
- `ExtensionMetadata`
- Members: `id`, `name`, `version`, `description`
### 🔄 Modifications
> **Note**: Some modifications may be breaking changes.
**Interfaces**
- `ComfyApi`
- ✨ Added member: `queuePromptAsync`
- ✨ Added member: `cancelPrompt`
- ✨ Added member: `getQueueStatus`
- ⚠️ **Breaking**: Removed member: `queuePrompt`
- `NodeDef`
- ✨ Added member: `input`
- ✨ Added member: `output`
- ✨ Added member: `output_name`
- `WorkflowMetadata`
- ✨ Added member: `tags`
- ✨ Added member: `thumbnail`
**Enums**
- `NodeStatus`
- ✨ Added enum value: `ERROR`
- ✨ Added enum value: `COMPLETED`
**Classes**
- `WorkflowManager`
- ✨ Added member: `cache`
- ✨ Added method: `deleteWorkflow()`
- ✨ Added method: `searchWorkflows()`
---

188
demo-snapshots/README.md Normal file
View File

@@ -0,0 +1,188 @@
# API Changelog Generation Demo
This demo showcases the automated API changelog generation system comparing two versions of the ComfyUI Frontend public API.
## Overview
The demo compares **v1.29.0****v1.30.2** to demonstrate:
- Breaking change detection
- API additions tracking
- Non-breaking modifications
- Human-readable changelog generation
## Demo Files
### Input Files
- **`v1.29.0.d.ts`** - TypeScript definitions representing the v1.29.0 API surface
- **`v1.30.2.d.ts`** - TypeScript definitions representing the v1.30.2 API surface
### Generated Files
- **`v1.29.0.json`** - Structured API snapshot from v1.29.0
- **`v1.30.2.json`** - Structured API snapshot from v1.30.2
- **`CHANGELOG-DEMO.md`** - Generated changelog comparing the two versions
## Running the Demo
```bash
# Generate API snapshots
node scripts/snapshot-api.js demo-snapshots/v1.29.0.d.ts > demo-snapshots/v1.29.0.json
node scripts/snapshot-api.js demo-snapshots/v1.30.2.d.ts > demo-snapshots/v1.30.2.json
# Compare snapshots and generate changelog
node scripts/compare-api-snapshots.js \
demo-snapshots/v1.29.0.json \
demo-snapshots/v1.30.2.json \
1.29.0 \
1.30.2 \
> demo-snapshots/CHANGELOG-DEMO.md
```
## Key Changes Detected
### ⚠️ Breaking Changes
1. **`ComfyApi.queuePrompt()` removed**
- Replaced with `queuePromptAsync()` which includes additional options
- Extension developers need to update their code to use the new async method
### ✨ New Additions
1. **New Interface: `ExtensionMetadata`**
- Provides metadata for extensions
- Fields: `id`, `name`, `version`, `description`
2. **New Type: `WorkflowId`**
- Type alias for workflow identifiers
3. **Enhanced `ComfyApi` Interface**
- `queuePromptAsync()` - Async queue with priority support
- `cancelPrompt()` - Cancel queued prompts
- `getQueueStatus()` - Query queue state
4. **Extended `NodeDef` Interface**
- `input` - Input specification
- `output` - Output types
- `output_name` - Output names
5. **Enhanced `NodeStatus` Enum**
- Added `ERROR` state
- Added `COMPLETED` state
6. **Extended `WorkflowManager` Class**
- `cache` property for workflow caching
- `deleteWorkflow()` method
- `searchWorkflows()` method
### 🔄 Non-Breaking Modifications
1. **`WorkflowMetadata` enhancements**
- Added optional `tags` field
- Added optional `thumbnail` field
## Real-World Usage
In production, this system will:
1. **Automatic Triggering**: Run after each NPM types release
2. **Version Detection**: Automatically detect current and previous versions from git tags
3. **Build Integration**: Build actual TypeScript types from the repository
4. **PR Creation**: Generate draft pull requests with the changelog
5. **Human Review**: Allow maintainers to review and enhance before merging
## Benefits for Extension Developers
### Clear Breaking Change Visibility
Extension developers can immediately see:
- What APIs were removed
- What signatures changed
- How to migrate their code
### Migration Planning
With clear documentation of additions and changes, developers can:
- Plan updates around breaking changes
- Adopt new features when ready
- Understand version compatibility
### Historical Reference
The cumulative `docs/API-CHANGELOG.md` provides:
- Complete API evolution history
- Context for design decisions
- Migration guides for major versions
## Example Extension Migration
### Before (v1.29.0)
```typescript
// Old code using queuePrompt
const result = await api.queuePrompt(workflow);
console.log('Queued:', result.prompt_id);
```
### After (v1.30.2)
```typescript
// New code using queuePromptAsync with priority
const result = await api.queuePromptAsync(workflow, { priority: 1 });
console.log('Queued:', result.prompt_id, 'Position:', result.number);
```
## Snapshot Structure
The JSON snapshots contain structured representations of:
```json
{
"types": { /* Type aliases */ },
"interfaces": { /* Interface definitions with members */ },
"enums": { /* Enum values */ },
"functions": { /* Exported functions */ },
"classes": { /* Class definitions with methods */ },
"constants": { /* Exported constants */ }
}
```
Each entry includes:
- **Name**: Identifier
- **Kind**: Type of declaration
- **Members/Methods**: Properties and functions
- **Types**: Parameter and return types
- **Visibility**: Public/private/protected modifiers
- **Optional**: Whether parameters/properties are optional
## Comparison Algorithm
The comparison script:
1. **Categorizes changes** into breaking, additions, and modifications
2. **Detects breaking changes**:
- Removed interfaces, classes, functions
- Removed methods or properties
- Changed method signatures
- Changed return types
- Removed enum values
3. **Tracks additions**:
- New interfaces, classes, types
- New methods and properties
- New enum values
4. **Identifies modifications**:
- Type changes
- Optionality changes
- Signature changes
## Future Enhancements
Planned improvements include:
- **LLM Enhancement**: Use AI to generate better descriptions and migration guides
- **Email Notifications**: Alert developers on mailing list for major changes
- **Release Notes Integration**: Auto-include in GitHub releases
- **Deprecation Tracking**: Mark APIs as deprecated before removal
- **Example Code**: Generate migration code snippets automatically
## Conclusion
This automated system ensures:
- ✅ Zero manual effort for changelog generation
- ✅ Consistent documentation format
- ✅ Clear breaking change visibility
- ✅ Historical API evolution tracking
- ✅ Better extension developer experience

58
demo-snapshots/v1.29.0.d.ts vendored Normal file
View File

@@ -0,0 +1,58 @@
/**
* Mock TypeScript definitions representing v1.29.0 API surface
* This represents the public API as it existed in version 1.29.0
*/
export interface ComfyApi {
/**
* Get API URL for backend calls
*/
apiURL(path: string): string
/**
* Get file URL for static resources
*/
fileURL(path: string): string
/**
* Queue a prompt for execution
*/
queuePrompt(prompt: object): Promise<{ prompt_id: string }>
/**
* Interrupt current execution
*/
interrupt(): Promise<void>
}
export interface NodeDef {
name: string
category: string
display_name?: string
description?: string
python_module: string
}
export enum NodeStatus {
IDLE = 'idle',
QUEUED = 'queued',
RUNNING = 'running'
}
export interface WorkflowMetadata {
title?: string
description?: string
author?: string
version?: string
}
export class WorkflowManager {
workflows: Map<string, object>
constructor()
loadWorkflow(id: string): Promise<object>
saveWorkflow(id: string, data: object): Promise<void>
}
export type NodeId = string

192
demo-snapshots/v1.29.0.json Normal file
View File

@@ -0,0 +1,192 @@
{
"types": {
"NodeId": {
"kind": "type",
"name": "NodeId",
"text": "export type NodeId = string;",
"exported": true
}
},
"interfaces": {
"ComfyApi": {
"kind": "interface",
"name": "ComfyApi",
"members": [
{
"name": "apiURL",
"kind": "method",
"parameters": [
{
"name": "path",
"type": "string",
"optional": false
}
],
"returnType": "string"
},
{
"name": "fileURL",
"kind": "method",
"parameters": [
{
"name": "path",
"type": "string",
"optional": false
}
],
"returnType": "string"
},
{
"name": "queuePrompt",
"kind": "method",
"parameters": [
{
"name": "prompt",
"type": "object",
"optional": false
}
],
"returnType": "Promise<{ prompt_id: string }>"
},
{
"name": "interrupt",
"kind": "method",
"parameters": [],
"returnType": "Promise<void>"
}
],
"exported": true,
"heritage": []
},
"NodeDef": {
"kind": "interface",
"name": "NodeDef",
"members": [
{
"name": "name",
"type": "string",
"optional": false
},
{
"name": "category",
"type": "string",
"optional": false
},
{
"name": "display_name",
"type": "string",
"optional": true
},
{
"name": "description",
"type": "string",
"optional": true
},
{
"name": "python_module",
"type": "string",
"optional": false
}
],
"exported": true,
"heritage": []
},
"WorkflowMetadata": {
"kind": "interface",
"name": "WorkflowMetadata",
"members": [
{
"name": "title",
"type": "string",
"optional": true
},
{
"name": "description",
"type": "string",
"optional": true
},
{
"name": "author",
"type": "string",
"optional": true
},
{
"name": "version",
"type": "string",
"optional": true
}
],
"exported": true,
"heritage": []
}
},
"enums": {
"NodeStatus": {
"kind": "enum",
"name": "NodeStatus",
"members": [
{
"name": "IDLE",
"value": "\"idle\""
},
{
"name": "QUEUED",
"value": "\"queued\""
},
{
"name": "RUNNING",
"value": "\"running\""
}
],
"exported": true
}
},
"functions": {},
"classes": {
"WorkflowManager": {
"kind": "class",
"name": "WorkflowManager",
"members": [
{
"name": "workflows",
"type": "Map<string, object>",
"visibility": "public"
}
],
"methods": [
{
"name": "loadWorkflow",
"parameters": [
{
"name": "id",
"type": "string",
"optional": false
}
],
"returnType": "Promise<object>",
"visibility": "public"
},
{
"name": "saveWorkflow",
"parameters": [
{
"name": "id",
"type": "string",
"optional": false
},
{
"name": "data",
"type": "object",
"optional": false
}
],
"returnType": "Promise<void>",
"visibility": "public"
}
],
"exported": true,
"heritage": []
}
},
"constants": {}
}

92
demo-snapshots/v1.30.2.d.ts vendored Normal file
View File

@@ -0,0 +1,92 @@
/**
* Mock TypeScript definitions representing v1.30.2 API surface
* This represents the public API with several breaking changes and additions
*/
export interface ComfyApi {
/**
* Get API URL for backend calls
*/
apiURL(path: string): string
/**
* Get file URL for static resources
*/
fileURL(path: string): string
/**
* Queue a prompt for execution (async version)
*/
queuePromptAsync(
prompt: object,
options?: { priority?: number }
): Promise<{ prompt_id: string; number: number }>
/**
* Cancel a queued prompt
*/
cancelPrompt(prompt_id: string): Promise<void>
/**
* Interrupt current execution
*/
interrupt(): Promise<void>
/**
* Get queue status
*/
getQueueStatus(): Promise<{ queue_running: any[]; queue_pending: any[] }>
}
export interface NodeDef {
name: string
category: string
display_name?: string
description?: string
python_module: string
input: {
required?: Record<string, any>
optional?: Record<string, any>
}
output: string[]
output_name: string[]
}
export enum NodeStatus {
IDLE = 'idle',
QUEUED = 'queued',
RUNNING = 'running',
ERROR = 'error',
COMPLETED = 'completed'
}
export interface WorkflowMetadata {
title?: string
description?: string
author?: string
version?: string
tags?: string[]
thumbnail?: string
}
export interface ExtensionMetadata {
id: string
name: string
version: string
description?: string
}
export class WorkflowManager {
workflows: Map<string, object>
cache: Map<string, object>
constructor()
loadWorkflow(id: string): Promise<object>
saveWorkflow(id: string, data: object): Promise<void>
deleteWorkflow(id: string): Promise<void>
searchWorkflows(query: string): Promise<object[]>
}
export type NodeId = string
export type WorkflowId = string

311
demo-snapshots/v1.30.2.json Normal file
View File

@@ -0,0 +1,311 @@
{
"types": {
"NodeId": {
"kind": "type",
"name": "NodeId",
"text": "export type NodeId = string;",
"exported": true
},
"WorkflowId": {
"kind": "type",
"name": "WorkflowId",
"text": "export type WorkflowId = string;",
"exported": true
}
},
"interfaces": {
"ComfyApi": {
"kind": "interface",
"name": "ComfyApi",
"members": [
{
"name": "apiURL",
"kind": "method",
"parameters": [
{
"name": "path",
"type": "string",
"optional": false
}
],
"returnType": "string"
},
{
"name": "fileURL",
"kind": "method",
"parameters": [
{
"name": "path",
"type": "string",
"optional": false
}
],
"returnType": "string"
},
{
"name": "queuePromptAsync",
"kind": "method",
"parameters": [
{
"name": "prompt",
"type": "object",
"optional": false
},
{
"name": "options",
"type": "{ priority?: number }",
"optional": true
}
],
"returnType": "Promise<{ prompt_id: string; number: number }>"
},
{
"name": "cancelPrompt",
"kind": "method",
"parameters": [
{
"name": "prompt_id",
"type": "string",
"optional": false
}
],
"returnType": "Promise<void>"
},
{
"name": "interrupt",
"kind": "method",
"parameters": [],
"returnType": "Promise<void>"
},
{
"name": "getQueueStatus",
"kind": "method",
"parameters": [],
"returnType": "Promise<{ queue_running: any[]; queue_pending: any[] }>"
}
],
"exported": true,
"heritage": []
},
"NodeDef": {
"kind": "interface",
"name": "NodeDef",
"members": [
{
"name": "name",
"type": "string",
"optional": false
},
{
"name": "category",
"type": "string",
"optional": false
},
{
"name": "display_name",
"type": "string",
"optional": true
},
{
"name": "description",
"type": "string",
"optional": true
},
{
"name": "python_module",
"type": "string",
"optional": false
},
{
"name": "input",
"type": "{\n required?: Record<string, any>;\n optional?: Record<string, any>;\n }",
"optional": false
},
{
"name": "output",
"type": "string[]",
"optional": false
},
{
"name": "output_name",
"type": "string[]",
"optional": false
}
],
"exported": true,
"heritage": []
},
"WorkflowMetadata": {
"kind": "interface",
"name": "WorkflowMetadata",
"members": [
{
"name": "title",
"type": "string",
"optional": true
},
{
"name": "description",
"type": "string",
"optional": true
},
{
"name": "author",
"type": "string",
"optional": true
},
{
"name": "version",
"type": "string",
"optional": true
},
{
"name": "tags",
"type": "string[]",
"optional": true
},
{
"name": "thumbnail",
"type": "string",
"optional": true
}
],
"exported": true,
"heritage": []
},
"ExtensionMetadata": {
"kind": "interface",
"name": "ExtensionMetadata",
"members": [
{
"name": "id",
"type": "string",
"optional": false
},
{
"name": "name",
"type": "string",
"optional": false
},
{
"name": "version",
"type": "string",
"optional": false
},
{
"name": "description",
"type": "string",
"optional": true
}
],
"exported": true,
"heritage": []
}
},
"enums": {
"NodeStatus": {
"kind": "enum",
"name": "NodeStatus",
"members": [
{
"name": "IDLE",
"value": "\"idle\""
},
{
"name": "QUEUED",
"value": "\"queued\""
},
{
"name": "RUNNING",
"value": "\"running\""
},
{
"name": "ERROR",
"value": "\"error\""
},
{
"name": "COMPLETED",
"value": "\"completed\""
}
],
"exported": true
}
},
"functions": {},
"classes": {
"WorkflowManager": {
"kind": "class",
"name": "WorkflowManager",
"members": [
{
"name": "workflows",
"type": "Map<string, object>",
"visibility": "public"
},
{
"name": "cache",
"type": "Map<string, object>",
"visibility": "public"
}
],
"methods": [
{
"name": "loadWorkflow",
"parameters": [
{
"name": "id",
"type": "string",
"optional": false
}
],
"returnType": "Promise<object>",
"visibility": "public"
},
{
"name": "saveWorkflow",
"parameters": [
{
"name": "id",
"type": "string",
"optional": false
},
{
"name": "data",
"type": "object",
"optional": false
}
],
"returnType": "Promise<void>",
"visibility": "public"
},
{
"name": "deleteWorkflow",
"parameters": [
{
"name": "id",
"type": "string",
"optional": false
}
],
"returnType": "Promise<void>",
"visibility": "public"
},
{
"name": "searchWorkflows",
"parameters": [
{
"name": "query",
"type": "string",
"optional": false
}
],
"returnType": "Promise<object[]>",
"visibility": "public"
}
],
"exported": true,
"heritage": []
}
},
"constants": {}
}

View File

@@ -58,7 +58,8 @@ export default defineConfig([
'src/extensions/core/*',
'src/scripts/*',
'src/types/generatedManagerTypes.ts',
'src/types/vue-shim.d.ts'
'src/types/vue-shim.d.ts',
'demo-snapshots/*'
]
},
{