@tpitre/story-ui 2.1.5 → 2.3.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/.env.sample +82 -11
- package/README.md +130 -4
- package/dist/cli/deploy.d.ts +17 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +696 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +55 -2
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +437 -110
- package/dist/mcp-server/index.d.ts +2 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +138 -6
- package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
- package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
- package/dist/mcp-server/mcp-stdio-server.js +638 -0
- package/dist/mcp-server/routes/claude.d.ts +3 -0
- package/dist/mcp-server/routes/claude.d.ts.map +1 -0
- package/dist/mcp-server/routes/claude.js +60 -23
- package/dist/mcp-server/routes/components.d.ts +4 -0
- package/dist/mcp-server/routes/components.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.d.ts +38 -0
- package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.js +183 -0
- package/dist/mcp-server/routes/generateStory.d.ts +3 -0
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStory.js +274 -115
- package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStoryStream.js +947 -0
- package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
- package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/hybridStories.js +214 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.js +489 -0
- package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
- package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/memoryStories.js +13 -7
- package/dist/mcp-server/routes/providers.d.ts +89 -0
- package/dist/mcp-server/routes/providers.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.js +369 -0
- package/dist/mcp-server/routes/storySync.d.ts +26 -0
- package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
- package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.js +18 -0
- package/dist/mcp-server/sessionManager.d.ts +50 -0
- package/dist/mcp-server/sessionManager.d.ts.map +1 -0
- package/dist/mcp-server/sessionManager.js +125 -0
- package/dist/story-generator/componentBlacklist.d.ts +21 -0
- package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
- package/dist/story-generator/componentBlacklist.js +4 -0
- package/dist/story-generator/componentDiscovery.d.ts +28 -0
- package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.js +205 -0
- package/dist/story-generator/configLoader.d.ts +33 -0
- package/dist/story-generator/configLoader.d.ts.map +1 -0
- package/dist/story-generator/configLoader.js +8 -1
- package/dist/story-generator/considerationsLoader.d.ts +32 -0
- package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
- package/dist/story-generator/considerationsLoader.js +2 -1
- package/dist/story-generator/documentation-sources.d.ts +28 -0
- package/dist/story-generator/documentation-sources.d.ts.map +1 -0
- package/dist/story-generator/documentationLoader.d.ts +64 -0
- package/dist/story-generator/documentationLoader.d.ts.map +1 -0
- package/dist/story-generator/documentationLoader.js +4 -3
- package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
- package/dist/story-generator/dynamicPackageDiscovery.js +31 -22
- package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.js +162 -21
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
- package/dist/story-generator/framework-adapters/index.d.ts +97 -0
- package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/index.js +198 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
- package/dist/story-generator/framework-adapters/types.d.ts +182 -0
- package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/types.js +8 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
- package/dist/story-generator/generateStory.d.ts +7 -0
- package/dist/story-generator/generateStory.d.ts.map +1 -0
- package/dist/story-generator/gitignoreManager.d.ts +50 -0
- package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/gitignoreManager.js +7 -6
- package/dist/story-generator/imageProcessor.d.ts +80 -0
- package/dist/story-generator/imageProcessor.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.js +391 -0
- package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
- package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.js +135 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/claude-provider.js +414 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
- package/dist/story-generator/llm-providers/index.d.ts +63 -0
- package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/index.js +169 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/openai-provider.js +458 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/settings-manager.js +173 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
- package/dist/story-generator/llm-providers/types.d.ts +153 -0
- package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/types.js +8 -0
- package/dist/story-generator/logger.d.ts +14 -0
- package/dist/story-generator/logger.d.ts.map +1 -0
- package/dist/story-generator/logger.js +119 -0
- package/dist/story-generator/postProcessStory.d.ts +6 -0
- package/dist/story-generator/postProcessStory.d.ts.map +1 -0
- package/dist/story-generator/postProcessStory.js +8 -7
- package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
- package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/productionGitignoreManager.js +11 -10
- package/dist/story-generator/promptGenerator.d.ts +48 -0
- package/dist/story-generator/promptGenerator.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.js +186 -1
- package/dist/story-generator/storyHistory.d.ts +44 -0
- package/dist/story-generator/storyHistory.d.ts.map +1 -0
- package/dist/story-generator/storySync.d.ts +68 -0
- package/dist/story-generator/storySync.d.ts.map +1 -0
- package/dist/story-generator/storyTracker.d.ts +48 -0
- package/dist/story-generator/storyTracker.d.ts.map +1 -0
- package/dist/story-generator/storyTracker.js +2 -1
- package/dist/story-generator/storyValidator.d.ts +6 -0
- package/dist/story-generator/storyValidator.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.js +141 -3
- package/dist/story-generator/urlRedirectService.d.ts +21 -0
- package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
- package/dist/story-generator/urlRedirectService.js +140 -0
- package/dist/story-generator/validateStory.d.ts +19 -0
- package/dist/story-generator/validateStory.d.ts.map +1 -0
- package/dist/story-generator/validateStory.js +6 -2
- package/dist/story-generator/visionPrompts.d.ts +88 -0
- package/dist/story-generator/visionPrompts.d.ts.map +1 -0
- package/dist/story-generator/visionPrompts.js +462 -0
- package/dist/story-ui.config.d.ts +78 -0
- package/dist/story-ui.config.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
- package/dist/templates/StoryUI/index.d.ts +3 -0
- package/dist/templates/StoryUI/index.d.ts.map +1 -0
- package/dist/templates/StoryUI/index.js +2 -0
- package/package.json +35 -4
- package/templates/StoryUI/StoryUIPanel.tsx +1973 -388
- package/templates/StoryUI/index.tsx +1 -1
- package/templates/StoryUI/manager.tsx +264 -0
- package/templates/mcp-config-claude.json +11 -0
- package/templates/mcp-example.md +76 -0
- package/templates/production-app/.env.example +11 -0
- package/templates/production-app/index.html +66 -0
- package/templates/production-app/package.json +30 -0
- package/templates/production-app/public/favicon.svg +5 -0
- package/templates/production-app/src/App.tsx +1157 -0
- package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
- package/templates/production-app/src/componentRegistry.ts +315 -0
- package/templates/production-app/src/considerations.ts +16 -0
- package/templates/production-app/src/index.css +284 -0
- package/templates/production-app/src/main.tsx +25 -0
- package/templates/production-app/tsconfig.json +32 -0
- package/templates/production-app/tsconfig.node.json +11 -0
- package/templates/production-app/vite.config.ts +83 -0
- package/templates/react-import-rule.json +2 -2
- package/dist/index.js +0 -12
- package/dist/story-ui.config.loader.js +0 -205
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface StoryVersion {
|
|
2
|
+
id: string;
|
|
3
|
+
timestamp: number;
|
|
4
|
+
prompt: string;
|
|
5
|
+
code: string;
|
|
6
|
+
fileName: string;
|
|
7
|
+
parentId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StoryHistory {
|
|
10
|
+
storyId: string;
|
|
11
|
+
title: string;
|
|
12
|
+
versions: StoryVersion[];
|
|
13
|
+
currentVersionId: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class StoryHistoryManager {
|
|
16
|
+
private historyDir;
|
|
17
|
+
private histories;
|
|
18
|
+
constructor(projectRoot: string);
|
|
19
|
+
private ensureHistoryDir;
|
|
20
|
+
private loadHistories;
|
|
21
|
+
private saveHistory;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new story history or add a version to existing history
|
|
24
|
+
*/
|
|
25
|
+
addVersion(fileName: string, prompt: string, code: string, parentVersionId?: string): StoryVersion;
|
|
26
|
+
/**
|
|
27
|
+
* Get the current version of a story by filename
|
|
28
|
+
*/
|
|
29
|
+
getCurrentVersion(fileName: string): StoryVersion | null;
|
|
30
|
+
/**
|
|
31
|
+
* Get all versions for a story
|
|
32
|
+
*/
|
|
33
|
+
getHistory(fileName: string): StoryHistory | null;
|
|
34
|
+
/**
|
|
35
|
+
* Find a story by partial filename match
|
|
36
|
+
*/
|
|
37
|
+
findStoryByPartialName(partialName: string): StoryHistory | null;
|
|
38
|
+
private titleFromFileName;
|
|
39
|
+
/**
|
|
40
|
+
* Clean up old versions, keeping only the last N versions
|
|
41
|
+
*/
|
|
42
|
+
pruneHistory(maxVersionsPerStory?: number): void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=storyHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storyHistory.d.ts","sourceRoot":"","sources":["../../story-generator/storyHistory.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAwC;gBAE7C,WAAW,EAAE,MAAM;IAM/B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,MAAM,GACvB,YAAY;IAiCf;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IASxD;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAKjD;;OAEG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAUhE,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,YAAY,CAAC,mBAAmB,GAAE,MAAW;CAU9C"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Story synchronization service that keeps chat interface, file system, and memory in sync
|
|
4
|
+
*/
|
|
5
|
+
export declare class StorySyncService {
|
|
6
|
+
private config;
|
|
7
|
+
private isProduction;
|
|
8
|
+
constructor(config: StoryUIConfig);
|
|
9
|
+
/**
|
|
10
|
+
* Gets all available stories from both file system and memory
|
|
11
|
+
*/
|
|
12
|
+
getAllStories(): Promise<SyncedStory[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Gets stories from the file system
|
|
15
|
+
*/
|
|
16
|
+
private getFileSystemStories;
|
|
17
|
+
/**
|
|
18
|
+
* Deletes a story from both file system and memory
|
|
19
|
+
*/
|
|
20
|
+
deleteStory(storyId: string): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Gets a specific story by ID
|
|
23
|
+
*/
|
|
24
|
+
getStory(storyId: string): Promise<SyncedStory | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Clears all stories
|
|
27
|
+
*/
|
|
28
|
+
clearAllStories(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Syncs localStorage chat history with actual stories
|
|
31
|
+
*/
|
|
32
|
+
syncChatHistory(): Promise<ChatSyncResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Validates that a chat session corresponds to an actual story
|
|
35
|
+
*/
|
|
36
|
+
validateChatSession(chatId: string): Promise<boolean>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Synced story interface that combines file system and memory stories
|
|
40
|
+
*/
|
|
41
|
+
export interface SyncedStory {
|
|
42
|
+
id: string;
|
|
43
|
+
title: string;
|
|
44
|
+
fileName: string;
|
|
45
|
+
description: string;
|
|
46
|
+
createdAt: Date;
|
|
47
|
+
lastAccessed: Date;
|
|
48
|
+
source: 'filesystem' | 'memory';
|
|
49
|
+
content: string;
|
|
50
|
+
prompt?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Chat synchronization result
|
|
54
|
+
*/
|
|
55
|
+
export interface ChatSyncResult {
|
|
56
|
+
actualStories: {
|
|
57
|
+
id: string;
|
|
58
|
+
title: string;
|
|
59
|
+
fileName: string;
|
|
60
|
+
lastUpdated: number;
|
|
61
|
+
}[];
|
|
62
|
+
shouldClearOrphanedChats: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Gets or creates the global story sync service
|
|
66
|
+
*/
|
|
67
|
+
export declare function getStorySyncService(config: StoryUIConfig): StorySyncService;
|
|
68
|
+
//# sourceMappingURL=storySync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storySync.d.ts","sourceRoot":"","sources":["../../story-generator/storySync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,YAAY,CAAU;gBAElB,MAAM,EAAE,aAAa;IAMjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IA4C7C;;OAEG;YACW,oBAAoB;IA0DlC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BpD;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK5D;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,cAAc,CAAC;IAehD;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAI5D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,MAAM,EAAE,YAAY,GAAG,QAAQ,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAOD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,CAK3E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
+
export interface StoryMapping {
|
|
3
|
+
title: string;
|
|
4
|
+
fileName: string;
|
|
5
|
+
storyId: string;
|
|
6
|
+
hash: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
updatedAt: string;
|
|
9
|
+
prompt: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class StoryTracker {
|
|
12
|
+
private mappingFile;
|
|
13
|
+
private mappings;
|
|
14
|
+
constructor(config: StoryUIConfig);
|
|
15
|
+
/**
|
|
16
|
+
* Load existing mappings from disk
|
|
17
|
+
*/
|
|
18
|
+
private loadMappings;
|
|
19
|
+
/**
|
|
20
|
+
* Save mappings to disk
|
|
21
|
+
*/
|
|
22
|
+
private saveMappings;
|
|
23
|
+
/**
|
|
24
|
+
* Find an existing story by title
|
|
25
|
+
*/
|
|
26
|
+
findByTitle(title: string): StoryMapping | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Find an existing story by prompt similarity
|
|
29
|
+
*/
|
|
30
|
+
findByPrompt(prompt: string): StoryMapping | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Register a new or updated story
|
|
33
|
+
*/
|
|
34
|
+
registerStory(mapping: StoryMapping): void;
|
|
35
|
+
/**
|
|
36
|
+
* Remove a story mapping
|
|
37
|
+
*/
|
|
38
|
+
removeStory(titleOrFileName: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get all story mappings
|
|
41
|
+
*/
|
|
42
|
+
getAllMappings(): StoryMapping[];
|
|
43
|
+
/**
|
|
44
|
+
* Clean up orphaned mappings (stories that no longer exist)
|
|
45
|
+
*/
|
|
46
|
+
cleanupOrphaned(generatedStoriesPath: string): number;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=storyTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storyTracker.d.ts","sourceRoot":"","sources":["../../story-generator/storyTracker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,MAAM,EAAE,aAAa;IAMjC;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAkBpD;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IA4CtD;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAwB1C;;OAEG;IACH,WAAW,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO;IAqB7C;;OAEG;IACH,cAAc,IAAI,YAAY,EAAE;IAIhC;;OAEG;IACH,eAAe,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM;CAiBtD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { logger } from './logger.js';
|
|
3
4
|
export class StoryTracker {
|
|
4
5
|
constructor(config) {
|
|
5
6
|
this.mappingFile = path.join(path.dirname(config.generatedStoriesPath), '.story-mappings.json');
|
|
@@ -88,7 +89,7 @@ export class StoryTracker {
|
|
|
88
89
|
// This prevents false positives like "card" matching "card layouts" vs "card animations"
|
|
89
90
|
const similarityThreshold = Math.max(4, Math.floor(promptKeywords.length * 0.9));
|
|
90
91
|
if (sharedKeywords.length >= similarityThreshold && promptKeywords.length >= 4) {
|
|
91
|
-
|
|
92
|
+
logger.log(`🔄 Found similar story: "${mapping.title}" (${sharedKeywords.length}/${promptKeywords.length} keywords match)`);
|
|
92
93
|
return mapping;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storyValidator.d.ts","sourceRoot":"","sources":["../../story-generator/storyValidator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE,CA2CrE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
+
export interface DesignSystemInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
type: 'chakra-ui' | 'antd' | 'mantine' | 'shadcn' | 'generic';
|
|
5
|
+
scope?: string;
|
|
6
|
+
primaryPackage: string;
|
|
7
|
+
commonComponents: string[];
|
|
8
|
+
layoutComponents: string[];
|
|
9
|
+
formComponents: string[];
|
|
10
|
+
importPatterns: {
|
|
11
|
+
default: string[];
|
|
12
|
+
named: string[];
|
|
13
|
+
};
|
|
14
|
+
designTokens?: {
|
|
15
|
+
spacing?: string;
|
|
16
|
+
colors?: string;
|
|
17
|
+
typography?: string;
|
|
18
|
+
};
|
|
19
|
+
/** For shadcn/ui: parsed components.json configuration */
|
|
20
|
+
shadcnConfig?: {
|
|
21
|
+
style?: string;
|
|
22
|
+
aliases?: {
|
|
23
|
+
components?: string;
|
|
24
|
+
utils?: string;
|
|
25
|
+
ui?: string;
|
|
26
|
+
};
|
|
27
|
+
tailwind?: {
|
|
28
|
+
cssVariables?: boolean;
|
|
29
|
+
baseColor?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Universal adapter to make Story UI work with any React design system
|
|
35
|
+
*/
|
|
36
|
+
export declare class UniversalDesignSystemAdapter {
|
|
37
|
+
private projectRoot;
|
|
38
|
+
private detectedSystems;
|
|
39
|
+
constructor(projectRoot?: string);
|
|
40
|
+
/**
|
|
41
|
+
* Auto-detect which design systems are available in the project
|
|
42
|
+
*/
|
|
43
|
+
detectDesignSystems(): Promise<DesignSystemInfo[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Generate optimal Story UI config for detected design systems
|
|
46
|
+
*/
|
|
47
|
+
generateOptimalConfig(): Partial<StoryUIConfig>;
|
|
48
|
+
/**
|
|
49
|
+
* Detect shadcn/ui by checking for components.json config file
|
|
50
|
+
* and common shadcn dependencies (class-variance-authority, tailwind-merge, etc.)
|
|
51
|
+
*/
|
|
52
|
+
private checkForShadcn;
|
|
53
|
+
/**
|
|
54
|
+
* Discover which shadcn components are actually installed in the project
|
|
55
|
+
*/
|
|
56
|
+
private discoverShadcnComponents;
|
|
57
|
+
private checkForChakraUI;
|
|
58
|
+
private checkForAntDesign;
|
|
59
|
+
private checkForMantine;
|
|
60
|
+
private checkForGenericReactComponents;
|
|
61
|
+
private getPrimaryDesignSystem;
|
|
62
|
+
private getShadcnConfig;
|
|
63
|
+
private getChakraUIConfig;
|
|
64
|
+
private getAntDesignConfig;
|
|
65
|
+
private getMantineConfig;
|
|
66
|
+
private getGenericReactConfig;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=universalDesignSystemAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"universalDesignSystemAdapter.d.ts","sourceRoot":"","sources":["../../story-generator/universalDesignSystemAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE;QACd,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,0DAA0D;IAC1D,YAAY,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE;YACR,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,EAAE,CAAC,EAAE,MAAM,CAAC;SACb,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,YAAY,CAAC,EAAE,OAAO,CAAC;YACvB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAA0B;gBAErC,WAAW,GAAE,MAAsB;IAI/C;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA8BxD;;OAEG;IACH,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC;IAuB/C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAwEtB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuChC,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,8BAA8B;IA8BtC,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,qBAAqB;CAiB9B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { logger } from './logger.js';
|
|
3
4
|
/**
|
|
4
5
|
* Universal adapter to make Story UI work with any React design system
|
|
5
6
|
*/
|
|
@@ -14,7 +15,7 @@ export class UniversalDesignSystemAdapter {
|
|
|
14
15
|
async detectDesignSystems() {
|
|
15
16
|
const packageJsonPath = path.join(this.projectRoot, 'package.json');
|
|
16
17
|
if (!fs.existsSync(packageJsonPath)) {
|
|
17
|
-
|
|
18
|
+
logger.log('📦 No package.json found for design system detection');
|
|
18
19
|
return [];
|
|
19
20
|
}
|
|
20
21
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
@@ -25,11 +26,12 @@ export class UniversalDesignSystemAdapter {
|
|
|
25
26
|
};
|
|
26
27
|
this.detectedSystems = [];
|
|
27
28
|
// Check for known design systems
|
|
29
|
+
this.checkForShadcn(allDeps);
|
|
28
30
|
this.checkForChakraUI(allDeps);
|
|
29
31
|
this.checkForAntDesign(allDeps);
|
|
30
32
|
this.checkForMantine(allDeps);
|
|
31
33
|
this.checkForGenericReactComponents(allDeps);
|
|
32
|
-
|
|
34
|
+
logger.log(`🎨 Detected ${this.detectedSystems.length} design systems:`, this.detectedSystems.map(ds => ds.name));
|
|
33
35
|
return this.detectedSystems;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
@@ -41,6 +43,8 @@ export class UniversalDesignSystemAdapter {
|
|
|
41
43
|
return this.getGenericReactConfig();
|
|
42
44
|
}
|
|
43
45
|
switch (primarySystem.type) {
|
|
46
|
+
case 'shadcn':
|
|
47
|
+
return this.getShadcnConfig(primarySystem);
|
|
44
48
|
case 'chakra-ui':
|
|
45
49
|
return this.getChakraUIConfig();
|
|
46
50
|
case 'antd':
|
|
@@ -52,6 +56,111 @@ export class UniversalDesignSystemAdapter {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
// Design system detection methods
|
|
59
|
+
/**
|
|
60
|
+
* Detect shadcn/ui by checking for components.json config file
|
|
61
|
+
* and common shadcn dependencies (class-variance-authority, tailwind-merge, etc.)
|
|
62
|
+
*/
|
|
63
|
+
checkForShadcn(deps) {
|
|
64
|
+
const componentsJsonPath = path.join(this.projectRoot, 'components.json');
|
|
65
|
+
const hasShadcnConfig = fs.existsSync(componentsJsonPath);
|
|
66
|
+
// Check for common shadcn/ui dependencies
|
|
67
|
+
const shadcnIndicators = [
|
|
68
|
+
'class-variance-authority',
|
|
69
|
+
'tailwind-merge',
|
|
70
|
+
'clsx',
|
|
71
|
+
'@radix-ui/react-slot',
|
|
72
|
+
'@radix-ui/react-dialog',
|
|
73
|
+
'@radix-ui/react-dropdown-menu',
|
|
74
|
+
'@radix-ui/react-select',
|
|
75
|
+
'lucide-react'
|
|
76
|
+
];
|
|
77
|
+
const foundIndicators = shadcnIndicators.filter(pkg => deps[pkg]);
|
|
78
|
+
const hasStrongIndicators = foundIndicators.length >= 3;
|
|
79
|
+
if (hasShadcnConfig || hasStrongIndicators) {
|
|
80
|
+
let shadcnConfig = undefined;
|
|
81
|
+
let componentPath = '@/components/ui';
|
|
82
|
+
let utilsPath = '@/lib/utils';
|
|
83
|
+
// Parse components.json if it exists
|
|
84
|
+
if (hasShadcnConfig) {
|
|
85
|
+
try {
|
|
86
|
+
const configContent = fs.readFileSync(componentsJsonPath, 'utf-8');
|
|
87
|
+
const config = JSON.parse(configContent);
|
|
88
|
+
shadcnConfig = {
|
|
89
|
+
style: config.style,
|
|
90
|
+
aliases: config.aliases,
|
|
91
|
+
tailwind: config.tailwind ? {
|
|
92
|
+
cssVariables: config.tailwind.cssVariables,
|
|
93
|
+
baseColor: config.tailwind.baseColor
|
|
94
|
+
} : undefined
|
|
95
|
+
};
|
|
96
|
+
// Use configured paths
|
|
97
|
+
componentPath = config.aliases?.ui || config.aliases?.components || '@/components/ui';
|
|
98
|
+
utilsPath = config.aliases?.utils || '@/lib/utils';
|
|
99
|
+
logger.log(`📦 Found shadcn/ui config: style=${config.style}, components=${componentPath}`);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
logger.log('⚠️ Could not parse components.json, using defaults');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Scan for actual shadcn components in the project
|
|
106
|
+
const discoveredComponents = this.discoverShadcnComponents();
|
|
107
|
+
this.detectedSystems.push({
|
|
108
|
+
name: 'shadcn/ui',
|
|
109
|
+
type: 'shadcn',
|
|
110
|
+
primaryPackage: componentPath,
|
|
111
|
+
commonComponents: discoveredComponents.length > 0
|
|
112
|
+
? discoveredComponents
|
|
113
|
+
: ['Button', 'Card', 'Input', 'Dialog', 'Select', 'Checkbox', 'Label', 'Badge'],
|
|
114
|
+
layoutComponents: ['Card', 'Separator', 'Sheet', 'Tabs'],
|
|
115
|
+
formComponents: ['Input', 'Button', 'Select', 'Checkbox', 'RadioGroup', 'Switch', 'Textarea', 'Label'],
|
|
116
|
+
importPatterns: {
|
|
117
|
+
default: [],
|
|
118
|
+
named: ['cn'] // utility function
|
|
119
|
+
},
|
|
120
|
+
shadcnConfig
|
|
121
|
+
});
|
|
122
|
+
logger.log(`✨ Detected shadcn/ui with ${discoveredComponents.length || 'default'} components`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Discover which shadcn components are actually installed in the project
|
|
127
|
+
*/
|
|
128
|
+
discoverShadcnComponents() {
|
|
129
|
+
const components = [];
|
|
130
|
+
// Common paths where shadcn components might be located
|
|
131
|
+
const possiblePaths = [
|
|
132
|
+
path.join(this.projectRoot, 'components', 'ui'),
|
|
133
|
+
path.join(this.projectRoot, 'src', 'components', 'ui'),
|
|
134
|
+
path.join(this.projectRoot, 'app', 'components', 'ui'),
|
|
135
|
+
];
|
|
136
|
+
for (const uiPath of possiblePaths) {
|
|
137
|
+
if (fs.existsSync(uiPath)) {
|
|
138
|
+
try {
|
|
139
|
+
const files = fs.readdirSync(uiPath);
|
|
140
|
+
for (const file of files) {
|
|
141
|
+
// Extract component name from file (button.tsx -> Button)
|
|
142
|
+
const match = file.match(/^([a-z-]+)\.(tsx|ts|jsx|js)$/i);
|
|
143
|
+
if (match) {
|
|
144
|
+
// Convert kebab-case to PascalCase (e.g., date-picker -> DatePicker)
|
|
145
|
+
const componentName = match[1]
|
|
146
|
+
.split('-')
|
|
147
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
148
|
+
.join('');
|
|
149
|
+
components.push(componentName);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (components.length > 0) {
|
|
153
|
+
logger.log(`📁 Found ${components.length} shadcn components in ${uiPath}`);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
// Continue checking other paths
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return components;
|
|
163
|
+
}
|
|
55
164
|
checkForChakraUI(deps) {
|
|
56
165
|
if (deps['@chakra-ui/react']) {
|
|
57
166
|
this.detectedSystems.push({
|
|
@@ -135,7 +244,8 @@ export class UniversalDesignSystemAdapter {
|
|
|
135
244
|
// Configuration generators
|
|
136
245
|
getPrimaryDesignSystem() {
|
|
137
246
|
// Prioritize based on completeness and popularity
|
|
138
|
-
|
|
247
|
+
// shadcn first since it's explicitly configured in the project
|
|
248
|
+
const priorities = ['shadcn', 'chakra-ui', 'antd', 'mantine', 'generic'];
|
|
139
249
|
for (const priority of priorities) {
|
|
140
250
|
const system = this.detectedSystems.find(ds => ds.type === priority);
|
|
141
251
|
if (system)
|
|
@@ -143,6 +253,34 @@ export class UniversalDesignSystemAdapter {
|
|
|
143
253
|
}
|
|
144
254
|
return this.detectedSystems[0] || null;
|
|
145
255
|
}
|
|
256
|
+
getShadcnConfig(system) {
|
|
257
|
+
const componentPath = system.primaryPackage || '@/components/ui';
|
|
258
|
+
const utilsPath = system.shadcnConfig?.aliases?.utils || '@/lib/utils';
|
|
259
|
+
return {
|
|
260
|
+
designSystemGuidelines: {
|
|
261
|
+
name: "shadcn/ui",
|
|
262
|
+
preferredComponents: {
|
|
263
|
+
layout: componentPath,
|
|
264
|
+
buttons: componentPath,
|
|
265
|
+
forms: componentPath
|
|
266
|
+
},
|
|
267
|
+
// shadcn-specific guidelines for AI generation
|
|
268
|
+
additionalNotes: `
|
|
269
|
+
shadcn/ui components are locally installed in the project.
|
|
270
|
+
- Import components from "${componentPath}" (e.g., import { Button } from "${componentPath}/button")
|
|
271
|
+
- Use the cn() utility from "${utilsPath}" for conditional classes
|
|
272
|
+
- Components use Tailwind CSS for styling
|
|
273
|
+
- Use CSS variables for theming (--primary, --secondary, --muted, etc.)
|
|
274
|
+
- Prefer composition over configuration
|
|
275
|
+
`.trim()
|
|
276
|
+
},
|
|
277
|
+
layoutRules: {
|
|
278
|
+
multiColumnWrapper: "div",
|
|
279
|
+
columnComponent: "div",
|
|
280
|
+
containerComponent: "div"
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
146
284
|
getChakraUIConfig() {
|
|
147
285
|
return {
|
|
148
286
|
designSystemGuidelines: {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface UrlRedirect {
|
|
2
|
+
oldUrl: string;
|
|
3
|
+
newUrl: string;
|
|
4
|
+
oldTitle: string;
|
|
5
|
+
newTitle: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
storyId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class UrlRedirectService {
|
|
10
|
+
private redirectsPath;
|
|
11
|
+
private redirects;
|
|
12
|
+
constructor(storageDir: string);
|
|
13
|
+
private ensureDirectoryExists;
|
|
14
|
+
private loadRedirects;
|
|
15
|
+
private saveRedirects;
|
|
16
|
+
addRedirect(oldUrl: string, newUrl: string, oldTitle: string, newTitle: string, storyId: string): void;
|
|
17
|
+
getRedirect(oldUrl: string): UrlRedirect | null;
|
|
18
|
+
getAllRedirects(): UrlRedirect[];
|
|
19
|
+
getRedirectScript(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=urlRedirectService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlRedirectService.d.ts","sourceRoot":"","sources":["../../story-generator/urlRedirectService.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAuC;gBAE5C,UAAU,EAAE,MAAM;IAK9B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,aAAa;IAWrB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IA8B/F,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI/C,eAAe,IAAI,WAAW,EAAE;IAKhC,iBAAiB,IAAI,MAAM;CAsE5B"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { logger } from './logger.js';
|
|
4
|
+
export class UrlRedirectService {
|
|
5
|
+
constructor(storageDir) {
|
|
6
|
+
this.redirects = new Map();
|
|
7
|
+
this.redirectsPath = path.join(storageDir, '.story-ui', 'redirects.json');
|
|
8
|
+
this.loadRedirects();
|
|
9
|
+
}
|
|
10
|
+
ensureDirectoryExists() {
|
|
11
|
+
const dir = path.dirname(this.redirectsPath);
|
|
12
|
+
if (!fs.existsSync(dir)) {
|
|
13
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
loadRedirects() {
|
|
17
|
+
try {
|
|
18
|
+
if (fs.existsSync(this.redirectsPath)) {
|
|
19
|
+
const data = fs.readFileSync(this.redirectsPath, 'utf-8');
|
|
20
|
+
const redirectArray = JSON.parse(data);
|
|
21
|
+
this.redirects = new Map(redirectArray.map(r => [r.oldUrl, r]));
|
|
22
|
+
logger.log(`📍 Loaded ${this.redirects.size} URL redirects`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.log('⚠️ Failed to load redirects, starting fresh:', error);
|
|
27
|
+
this.redirects = new Map();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
saveRedirects() {
|
|
31
|
+
try {
|
|
32
|
+
this.ensureDirectoryExists();
|
|
33
|
+
const redirectArray = Array.from(this.redirects.values());
|
|
34
|
+
fs.writeFileSync(this.redirectsPath, JSON.stringify(redirectArray, null, 2));
|
|
35
|
+
logger.log(`💾 Saved ${redirectArray.length} URL redirects`);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
logger.log('❌ Failed to save redirects:', error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
addRedirect(oldUrl, newUrl, oldTitle, newTitle, storyId) {
|
|
42
|
+
// Don't create a redirect if URLs are the same
|
|
43
|
+
if (oldUrl === newUrl) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const redirect = {
|
|
47
|
+
oldUrl,
|
|
48
|
+
newUrl,
|
|
49
|
+
oldTitle,
|
|
50
|
+
newTitle,
|
|
51
|
+
timestamp: new Date().toISOString(),
|
|
52
|
+
storyId
|
|
53
|
+
};
|
|
54
|
+
this.redirects.set(oldUrl, redirect);
|
|
55
|
+
// Also handle redirect chains (if A->B exists and we add B->C, update A->C)
|
|
56
|
+
for (const [url, existingRedirect] of this.redirects.entries()) {
|
|
57
|
+
if (existingRedirect.newUrl === oldUrl) {
|
|
58
|
+
existingRedirect.newUrl = newUrl;
|
|
59
|
+
existingRedirect.newTitle = newTitle;
|
|
60
|
+
logger.log(`🔄 Updated redirect chain: ${url} → ${newUrl}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
this.saveRedirects();
|
|
64
|
+
logger.log(`➡️ Added redirect: ${oldUrl} → ${newUrl}`);
|
|
65
|
+
}
|
|
66
|
+
getRedirect(oldUrl) {
|
|
67
|
+
return this.redirects.get(oldUrl) || null;
|
|
68
|
+
}
|
|
69
|
+
getAllRedirects() {
|
|
70
|
+
return Array.from(this.redirects.values());
|
|
71
|
+
}
|
|
72
|
+
// Get a JavaScript snippet that can be injected into Storybook
|
|
73
|
+
getRedirectScript() {
|
|
74
|
+
const redirectMap = Object.fromEntries(Array.from(this.redirects.entries()).map(([oldUrl, redirect]) => [
|
|
75
|
+
oldUrl,
|
|
76
|
+
{ newUrl: redirect.newUrl, message: `Story updated: "${redirect.oldTitle}" → "${redirect.newTitle}"` }
|
|
77
|
+
]));
|
|
78
|
+
return `
|
|
79
|
+
// Story UI URL Redirect Handler
|
|
80
|
+
(function() {
|
|
81
|
+
const redirects = ${JSON.stringify(redirectMap, null, 2)};
|
|
82
|
+
|
|
83
|
+
function checkForRedirect() {
|
|
84
|
+
const currentPath = window.location.pathname + window.location.search;
|
|
85
|
+
|
|
86
|
+
for (const [oldUrl, redirect] of Object.entries(redirects)) {
|
|
87
|
+
if (currentPath.includes(oldUrl)) {
|
|
88
|
+
console.log('[Story UI] Redirecting from', oldUrl, 'to', redirect.newUrl);
|
|
89
|
+
|
|
90
|
+
// Show a brief notification
|
|
91
|
+
const notification = document.createElement('div');
|
|
92
|
+
notification.style.cssText = \`
|
|
93
|
+
position: fixed;
|
|
94
|
+
top: 20px;
|
|
95
|
+
right: 20px;
|
|
96
|
+
background: #1890ff;
|
|
97
|
+
color: white;
|
|
98
|
+
padding: 12px 20px;
|
|
99
|
+
border-radius: 4px;
|
|
100
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
101
|
+
z-index: 9999;
|
|
102
|
+
font-family: sans-serif;
|
|
103
|
+
font-size: 14px;
|
|
104
|
+
\`;
|
|
105
|
+
notification.textContent = redirect.message;
|
|
106
|
+
document.body.appendChild(notification);
|
|
107
|
+
|
|
108
|
+
// Redirect after a brief delay
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
window.location.href = redirect.newUrl;
|
|
111
|
+
}, 1500);
|
|
112
|
+
|
|
113
|
+
// Remove notification after redirect
|
|
114
|
+
setTimeout(() => notification.remove(), 1400);
|
|
115
|
+
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Check on page load
|
|
123
|
+
if (window.location.pathname.includes('/story/')) {
|
|
124
|
+
checkForRedirect();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Also check when navigation occurs in single-page app
|
|
128
|
+
let lastPath = window.location.pathname;
|
|
129
|
+
setInterval(() => {
|
|
130
|
+
if (window.location.pathname !== lastPath) {
|
|
131
|
+
lastPath = window.location.pathname;
|
|
132
|
+
if (window.location.pathname.includes('/story/')) {
|
|
133
|
+
checkForRedirect();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}, 100);
|
|
137
|
+
})();
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
isValid: boolean;
|
|
3
|
+
errors: string[];
|
|
4
|
+
warnings: string[];
|
|
5
|
+
fixedCode?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Validates TypeScript code syntax and attempts to fix common issues
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateStoryCode(code: string, fileName?: string, config?: any): ValidationResult;
|
|
11
|
+
/**
|
|
12
|
+
* Extracts and validates code blocks from AI responses
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractAndValidateCodeBlock(aiResponse: string, config?: any): ValidationResult;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a fallback story template when generation fails
|
|
17
|
+
*/
|
|
18
|
+
export declare function createFallbackStory(prompt: string, config: any): string;
|
|
19
|
+
//# sourceMappingURL=validateStory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateStory.d.ts","sourceRoot":"","sources":["../../story-generator/validateStory.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAoB,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAgG9G;AAoYD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAqC9F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,MAAM,CA+BvE"}
|