@tpitre/story-ui 3.1.0 → 3.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/README.md +25 -72
- package/dist/cli/deploy.d.ts +0 -7
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/deploy.js +10 -421
- package/dist/cli/index.js +0 -29
- package/dist/mcp-server/index.js +20 -66
- package/dist/mcp-server/mcp-stdio-server.js +40 -110
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStory.js +46 -117
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStoryStream.js +30 -72
- package/dist/mcp-server/routes/mcpRemote.d.ts +7 -3
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -1
- package/dist/mcp-server/routes/mcpRemote.js +353 -254
- package/dist/story-generator/generateStory.d.ts.map +1 -1
- package/dist/story-generator/generateStory.js +25 -0
- package/package.json +7 -7
- package/dist/mcp-server/routes/hybridStories.d.ts +0 -18
- package/dist/mcp-server/routes/hybridStories.d.ts.map +0 -1
- package/dist/mcp-server/routes/hybridStories.js +0 -214
- package/dist/mcp-server/routes/memoryStories.d.ts +0 -26
- package/dist/mcp-server/routes/memoryStories.d.ts.map +0 -1
- package/dist/mcp-server/routes/memoryStories.js +0 -147
- package/dist/mcp-server/routes/storySync.d.ts +0 -26
- package/dist/mcp-server/routes/storySync.d.ts.map +0 -1
- package/dist/mcp-server/routes/storySync.js +0 -147
- package/dist/mcp-server/sessionManager.d.ts +0 -50
- package/dist/mcp-server/sessionManager.d.ts.map +0 -1
- package/dist/mcp-server/sessionManager.js +0 -125
- package/dist/story-generator/inMemoryStoryService.d.ts +0 -89
- package/dist/story-generator/inMemoryStoryService.d.ts.map +0 -1
- package/dist/story-generator/inMemoryStoryService.js +0 -128
- package/dist/story-generator/productionGitignoreManager.d.ts +0 -91
- package/dist/story-generator/productionGitignoreManager.d.ts.map +0 -1
- package/dist/story-generator/productionGitignoreManager.js +0 -340
- package/dist/story-generator/storySync.d.ts +0 -68
- package/dist/story-generator/storySync.d.ts.map +0 -1
- package/dist/story-generator/storySync.js +0 -201
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
interface SessionStory {
|
|
2
|
-
id: string;
|
|
3
|
-
fileName: string;
|
|
4
|
-
title: string;
|
|
5
|
-
prompt: string;
|
|
6
|
-
timestamp: Date;
|
|
7
|
-
keywords: string[];
|
|
8
|
-
}
|
|
9
|
-
export declare class SessionManager {
|
|
10
|
-
private static instance;
|
|
11
|
-
private sessions;
|
|
12
|
-
private currentStoryId;
|
|
13
|
-
private constructor();
|
|
14
|
-
static getInstance(): SessionManager;
|
|
15
|
-
/**
|
|
16
|
-
* Track a newly generated story in the current session
|
|
17
|
-
*/
|
|
18
|
-
trackStory(sessionId: string, story: {
|
|
19
|
-
id: string;
|
|
20
|
-
fileName: string;
|
|
21
|
-
title: string;
|
|
22
|
-
prompt: string;
|
|
23
|
-
}): void;
|
|
24
|
-
/**
|
|
25
|
-
* Get the current story being discussed
|
|
26
|
-
*/
|
|
27
|
-
getCurrentStory(sessionId: string): SessionStory | null;
|
|
28
|
-
/**
|
|
29
|
-
* Find a story by context (keywords in the user's message)
|
|
30
|
-
*/
|
|
31
|
-
findStoryByContext(sessionId: string, userMessage: string): SessionStory | null;
|
|
32
|
-
/**
|
|
33
|
-
* Get all stories in the current session
|
|
34
|
-
*/
|
|
35
|
-
getSessionStories(sessionId: string): SessionStory[];
|
|
36
|
-
/**
|
|
37
|
-
* Set the current story being discussed
|
|
38
|
-
*/
|
|
39
|
-
setCurrentStory(sessionId: string, storyId: string): void;
|
|
40
|
-
/**
|
|
41
|
-
* Clear session data (for cleanup)
|
|
42
|
-
*/
|
|
43
|
-
clearSession(sessionId: string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Extract meaningful keywords from text
|
|
46
|
-
*/
|
|
47
|
-
private extractKeywords;
|
|
48
|
-
}
|
|
49
|
-
export {};
|
|
50
|
-
//# sourceMappingURL=sessionManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../mcp-server/sessionManager.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,cAAc,CAAuB;IAE7C,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QACnC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB;IAmBD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IASvD;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAiC/E;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE;IAIpD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAQlD;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM;IAO9B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkCxB"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
export class SessionManager {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.sessions = new Map();
|
|
4
|
-
this.currentStoryId = null;
|
|
5
|
-
}
|
|
6
|
-
static getInstance() {
|
|
7
|
-
if (!SessionManager.instance) {
|
|
8
|
-
SessionManager.instance = new SessionManager();
|
|
9
|
-
}
|
|
10
|
-
return SessionManager.instance;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Track a newly generated story in the current session
|
|
14
|
-
*/
|
|
15
|
-
trackStory(sessionId, story) {
|
|
16
|
-
const sessionStories = this.sessions.get(sessionId) || [];
|
|
17
|
-
// Extract keywords from prompt and title for smart matching
|
|
18
|
-
const keywords = this.extractKeywords(story.prompt + ' ' + story.title);
|
|
19
|
-
const sessionStory = {
|
|
20
|
-
...story,
|
|
21
|
-
timestamp: new Date(),
|
|
22
|
-
keywords
|
|
23
|
-
};
|
|
24
|
-
sessionStories.push(sessionStory);
|
|
25
|
-
this.sessions.set(sessionId, sessionStories);
|
|
26
|
-
this.currentStoryId = story.id;
|
|
27
|
-
console.error(`[SessionManager] Tracked story: ${story.title} (${story.id}) for session ${sessionId}`);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Get the current story being discussed
|
|
31
|
-
*/
|
|
32
|
-
getCurrentStory(sessionId) {
|
|
33
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
34
|
-
if (this.currentStoryId) {
|
|
35
|
-
return stories.find(s => s.id === this.currentStoryId) || null;
|
|
36
|
-
}
|
|
37
|
-
// Return the most recent story if no current story is set
|
|
38
|
-
return stories[stories.length - 1] || null;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Find a story by context (keywords in the user's message)
|
|
42
|
-
*/
|
|
43
|
-
findStoryByContext(sessionId, userMessage) {
|
|
44
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
45
|
-
if (stories.length === 0)
|
|
46
|
-
return null;
|
|
47
|
-
const messageKeywords = this.extractKeywords(userMessage.toLowerCase());
|
|
48
|
-
// Score each story based on keyword matches
|
|
49
|
-
const scoredStories = stories.map(story => {
|
|
50
|
-
const score = story.keywords.filter(keyword => messageKeywords.some(msgKeyword => msgKeyword.includes(keyword) || keyword.includes(msgKeyword))).length;
|
|
51
|
-
return { story, score };
|
|
52
|
-
});
|
|
53
|
-
// Sort by score and recency
|
|
54
|
-
scoredStories.sort((a, b) => {
|
|
55
|
-
if (a.score !== b.score)
|
|
56
|
-
return b.score - a.score;
|
|
57
|
-
return b.story.timestamp.getTime() - a.story.timestamp.getTime();
|
|
58
|
-
});
|
|
59
|
-
// Return the best match if it has any keyword matches
|
|
60
|
-
if (scoredStories[0].score > 0) {
|
|
61
|
-
this.currentStoryId = scoredStories[0].story.id;
|
|
62
|
-
console.error(`[SessionManager] Found story by context: ${scoredStories[0].story.title} (score: ${scoredStories[0].score})`);
|
|
63
|
-
return scoredStories[0].story;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get all stories in the current session
|
|
69
|
-
*/
|
|
70
|
-
getSessionStories(sessionId) {
|
|
71
|
-
return this.sessions.get(sessionId) || [];
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Set the current story being discussed
|
|
75
|
-
*/
|
|
76
|
-
setCurrentStory(sessionId, storyId) {
|
|
77
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
78
|
-
if (stories.some(s => s.id === storyId)) {
|
|
79
|
-
this.currentStoryId = storyId;
|
|
80
|
-
console.error(`[SessionManager] Set current story to: ${storyId}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Clear session data (for cleanup)
|
|
85
|
-
*/
|
|
86
|
-
clearSession(sessionId) {
|
|
87
|
-
this.sessions.delete(sessionId);
|
|
88
|
-
if (this.currentStoryId) {
|
|
89
|
-
this.currentStoryId = null;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Extract meaningful keywords from text
|
|
94
|
-
*/
|
|
95
|
-
extractKeywords(text) {
|
|
96
|
-
// Remove common words and extract meaningful terms
|
|
97
|
-
const commonWords = new Set([
|
|
98
|
-
'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
99
|
-
'of', 'with', 'by', 'from', 'up', 'about', 'into', 'through', 'during',
|
|
100
|
-
'before', 'after', 'above', 'below', 'between', 'under', 'again', 'further',
|
|
101
|
-
'then', 'once', 'create', 'make', 'generate', 'build', 'add', 'update',
|
|
102
|
-
'component', 'story', 'please', 'should', 'would', 'could'
|
|
103
|
-
]);
|
|
104
|
-
const words = text.toLowerCase()
|
|
105
|
-
.replace(/[^a-z0-9\s]/g, ' ')
|
|
106
|
-
.split(/\s+/)
|
|
107
|
-
.filter(word => word.length > 2 && !commonWords.has(word));
|
|
108
|
-
// Also extract compound terms (like "toast notification")
|
|
109
|
-
const phrases = [];
|
|
110
|
-
const importantPhrases = [
|
|
111
|
-
'toast notification', 'banner notification', 'success message',
|
|
112
|
-
'error message', 'warning message', 'info message',
|
|
113
|
-
'dark mode', 'light mode', 'switch', 'toggle', 'button',
|
|
114
|
-
'card', 'alert', 'modal', 'dialog', 'form', 'input',
|
|
115
|
-
'table', 'list', 'grid', 'layout', 'navigation', 'menu'
|
|
116
|
-
];
|
|
117
|
-
const lowerText = text.toLowerCase();
|
|
118
|
-
for (const phrase of importantPhrases) {
|
|
119
|
-
if (lowerText.includes(phrase)) {
|
|
120
|
-
phrases.push(phrase);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return [...new Set([...words, ...phrases])];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
-
/**
|
|
3
|
-
* In-memory story service for production environments
|
|
4
|
-
* Stores generated stories in memory and serves them via API
|
|
5
|
-
*/
|
|
6
|
-
export declare class InMemoryStoryService {
|
|
7
|
-
private stories;
|
|
8
|
-
private config;
|
|
9
|
-
constructor(config: StoryUIConfig);
|
|
10
|
-
/**
|
|
11
|
-
* Stores a generated story in memory
|
|
12
|
-
*/
|
|
13
|
-
storeStory(story: GeneratedStory): void;
|
|
14
|
-
/**
|
|
15
|
-
* Retrieves a story by ID
|
|
16
|
-
*/
|
|
17
|
-
getStory(id: string): GeneratedStory | null;
|
|
18
|
-
/**
|
|
19
|
-
* Gets all stored stories
|
|
20
|
-
*/
|
|
21
|
-
getAllStories(): GeneratedStory[];
|
|
22
|
-
/**
|
|
23
|
-
* Deletes a story by ID
|
|
24
|
-
*/
|
|
25
|
-
deleteStory(id: string): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Clears all stories
|
|
28
|
-
*/
|
|
29
|
-
clearAllStories(): void;
|
|
30
|
-
/**
|
|
31
|
-
* Gets story content for Storybook integration
|
|
32
|
-
*/
|
|
33
|
-
getStoryContent(id: string): string | null;
|
|
34
|
-
/**
|
|
35
|
-
* Gets story metadata for listing
|
|
36
|
-
*/
|
|
37
|
-
getStoryMetadata(): StoryMetadata[];
|
|
38
|
-
/**
|
|
39
|
-
* Cleans up old stories to prevent memory leaks
|
|
40
|
-
*/
|
|
41
|
-
private cleanupOldStories;
|
|
42
|
-
/**
|
|
43
|
-
* Counts components used in a story
|
|
44
|
-
*/
|
|
45
|
-
private countComponents;
|
|
46
|
-
/**
|
|
47
|
-
* Gets memory usage statistics
|
|
48
|
-
*/
|
|
49
|
-
getMemoryStats(): MemoryStats;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Generated story interface
|
|
53
|
-
*/
|
|
54
|
-
export interface GeneratedStory {
|
|
55
|
-
id: string;
|
|
56
|
-
title: string;
|
|
57
|
-
description: string;
|
|
58
|
-
content: string;
|
|
59
|
-
createdAt: Date;
|
|
60
|
-
lastAccessed: Date;
|
|
61
|
-
prompt?: string;
|
|
62
|
-
components?: string[];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Story metadata for listing
|
|
66
|
-
*/
|
|
67
|
-
export interface StoryMetadata {
|
|
68
|
-
id: string;
|
|
69
|
-
title: string;
|
|
70
|
-
description: string;
|
|
71
|
-
createdAt: Date;
|
|
72
|
-
lastAccessed: Date;
|
|
73
|
-
componentCount: number;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Memory usage statistics
|
|
77
|
-
*/
|
|
78
|
-
export interface MemoryStats {
|
|
79
|
-
storyCount: number;
|
|
80
|
-
totalSizeBytes: number;
|
|
81
|
-
averageSizeBytes: number;
|
|
82
|
-
oldestStory: Date | null;
|
|
83
|
-
newestStory: Date | null;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Gets or creates the global story service instance
|
|
87
|
-
*/
|
|
88
|
-
export declare function getInMemoryStoryService(config: StoryUIConfig): InMemoryStoryService;
|
|
89
|
-
//# sourceMappingURL=inMemoryStoryService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inMemoryStoryService.d.ts","sourceRoot":"","sources":["../../story-generator/inMemoryStoryService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAIjC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAWvC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAS3C;;OAEG;IACH,aAAa,IAAI,cAAc,EAAE;IAMjC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,eAAe,IAAI,IAAI;IAIvB;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK1C;;OAEG;IACH,gBAAgB,IAAI,aAAa,EAAE;IAWnC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,cAAc,IAAI,WAAW;CAgB9B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAOD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,oBAAoB,CAKnF"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory story service for production environments
|
|
3
|
-
* Stores generated stories in memory and serves them via API
|
|
4
|
-
*/
|
|
5
|
-
export class InMemoryStoryService {
|
|
6
|
-
constructor(config) {
|
|
7
|
-
this.stories = new Map();
|
|
8
|
-
this.config = config;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Stores a generated story in memory
|
|
12
|
-
*/
|
|
13
|
-
storeStory(story) {
|
|
14
|
-
this.stories.set(story.id, {
|
|
15
|
-
...story,
|
|
16
|
-
createdAt: new Date(),
|
|
17
|
-
lastAccessed: new Date()
|
|
18
|
-
});
|
|
19
|
-
// Clean up old stories to prevent memory leaks
|
|
20
|
-
this.cleanupOldStories();
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Retrieves a story by ID
|
|
24
|
-
*/
|
|
25
|
-
getStory(id) {
|
|
26
|
-
const story = this.stories.get(id);
|
|
27
|
-
if (story) {
|
|
28
|
-
story.lastAccessed = new Date();
|
|
29
|
-
return story;
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Gets all stored stories
|
|
35
|
-
*/
|
|
36
|
-
getAllStories() {
|
|
37
|
-
return Array.from(this.stories.values()).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Deletes a story by ID
|
|
41
|
-
*/
|
|
42
|
-
deleteStory(id) {
|
|
43
|
-
return this.stories.delete(id);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Clears all stories
|
|
47
|
-
*/
|
|
48
|
-
clearAllStories() {
|
|
49
|
-
this.stories.clear();
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Gets story content for Storybook integration
|
|
53
|
-
*/
|
|
54
|
-
getStoryContent(id) {
|
|
55
|
-
const story = this.stories.get(id);
|
|
56
|
-
return story ? story.content : null;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Gets story metadata for listing
|
|
60
|
-
*/
|
|
61
|
-
getStoryMetadata() {
|
|
62
|
-
return Array.from(this.stories.values()).map(story => ({
|
|
63
|
-
id: story.id,
|
|
64
|
-
title: story.title,
|
|
65
|
-
description: story.description,
|
|
66
|
-
createdAt: story.createdAt,
|
|
67
|
-
lastAccessed: story.lastAccessed,
|
|
68
|
-
componentCount: this.countComponents(story.content)
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Cleans up old stories to prevent memory leaks
|
|
73
|
-
*/
|
|
74
|
-
cleanupOldStories() {
|
|
75
|
-
const maxStories = 50; // Keep maximum 50 stories in memory
|
|
76
|
-
const maxAge = 24 * 60 * 60 * 1000; // 24 hours
|
|
77
|
-
const now = Date.now();
|
|
78
|
-
// Remove stories older than maxAge
|
|
79
|
-
for (const [id, story] of this.stories.entries()) {
|
|
80
|
-
if (now - story.lastAccessed.getTime() > maxAge) {
|
|
81
|
-
this.stories.delete(id);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// If still too many stories, remove oldest ones
|
|
85
|
-
if (this.stories.size > maxStories) {
|
|
86
|
-
const sortedStories = Array.from(this.stories.entries())
|
|
87
|
-
.sort(([, a], [, b]) => a.lastAccessed.getTime() - b.lastAccessed.getTime());
|
|
88
|
-
const toRemove = sortedStories.slice(0, this.stories.size - maxStories);
|
|
89
|
-
for (const [id] of toRemove) {
|
|
90
|
-
this.stories.delete(id);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Counts components used in a story
|
|
96
|
-
*/
|
|
97
|
-
countComponents(content) {
|
|
98
|
-
const componentMatches = content.match(/<[A-Z][A-Za-z0-9]*\s/g);
|
|
99
|
-
return componentMatches ? new Set(componentMatches).size : 0;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Gets memory usage statistics
|
|
103
|
-
*/
|
|
104
|
-
getMemoryStats() {
|
|
105
|
-
const stories = Array.from(this.stories.values());
|
|
106
|
-
const totalSize = stories.reduce((sum, story) => sum + story.content.length, 0);
|
|
107
|
-
return {
|
|
108
|
-
storyCount: this.stories.size,
|
|
109
|
-
totalSizeBytes: totalSize,
|
|
110
|
-
averageSizeBytes: stories.length > 0 ? Math.round(totalSize / stories.length) : 0,
|
|
111
|
-
oldestStory: stories.reduce((oldest, story) => !oldest || story.createdAt < oldest.createdAt ? story : oldest, null)?.createdAt || null,
|
|
112
|
-
newestStory: stories.reduce((newest, story) => !newest || story.createdAt > newest.createdAt ? story : newest, null)?.createdAt || null
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Global in-memory story service instance
|
|
118
|
-
*/
|
|
119
|
-
let globalStoryService = null;
|
|
120
|
-
/**
|
|
121
|
-
* Gets or creates the global story service instance
|
|
122
|
-
*/
|
|
123
|
-
export function getInMemoryStoryService(config) {
|
|
124
|
-
if (!globalStoryService) {
|
|
125
|
-
globalStoryService = new InMemoryStoryService(config);
|
|
126
|
-
}
|
|
127
|
-
return globalStoryService;
|
|
128
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
-
/**
|
|
3
|
-
* Production-ready gitignore manager that handles both development and server environments
|
|
4
|
-
*/
|
|
5
|
-
export declare class ProductionGitignoreManager {
|
|
6
|
-
private config;
|
|
7
|
-
private projectRoot;
|
|
8
|
-
private isProduction;
|
|
9
|
-
constructor(config: StoryUIConfig, projectRoot?: string);
|
|
10
|
-
/**
|
|
11
|
-
* Detects if we're running in a production/read-only environment
|
|
12
|
-
*/
|
|
13
|
-
private detectProductionEnvironment;
|
|
14
|
-
/**
|
|
15
|
-
* Tests if we can write to the project root
|
|
16
|
-
*/
|
|
17
|
-
private canWriteToProjectRoot;
|
|
18
|
-
/**
|
|
19
|
-
* Main setup method that adapts to environment
|
|
20
|
-
*/
|
|
21
|
-
setupGitignoreIntegration(): void;
|
|
22
|
-
/**
|
|
23
|
-
* Production environment: Use in-memory story generation
|
|
24
|
-
*/
|
|
25
|
-
private handleProductionEnvironment;
|
|
26
|
-
/**
|
|
27
|
-
* Development environment: Full gitignore management
|
|
28
|
-
*/
|
|
29
|
-
private handleDevelopmentEnvironment;
|
|
30
|
-
/**
|
|
31
|
-
* Validates that production environment is properly configured
|
|
32
|
-
*/
|
|
33
|
-
private validateProductionSetup;
|
|
34
|
-
/**
|
|
35
|
-
* Sets up temporary directory for production story generation
|
|
36
|
-
*/
|
|
37
|
-
private setupTemporaryDirectory;
|
|
38
|
-
/**
|
|
39
|
-
* Gets a writable temporary directory for production
|
|
40
|
-
*/
|
|
41
|
-
getProductionTempDirectory(): string;
|
|
42
|
-
/**
|
|
43
|
-
* Creates the generated directory if it doesn't exist (development only)
|
|
44
|
-
*/
|
|
45
|
-
private ensureGeneratedDirectoryExists;
|
|
46
|
-
/**
|
|
47
|
-
* Ensures the generated stories directory is added to .gitignore (development only)
|
|
48
|
-
*/
|
|
49
|
-
private ensureGeneratedDirectoryIgnored;
|
|
50
|
-
/**
|
|
51
|
-
* Gets the relative path from project root to generated stories directory
|
|
52
|
-
*/
|
|
53
|
-
private getRelativeGeneratedPath;
|
|
54
|
-
/**
|
|
55
|
-
* Creates a new .gitignore file with Story UI section
|
|
56
|
-
*/
|
|
57
|
-
private createGitignore;
|
|
58
|
-
/**
|
|
59
|
-
* Checks if the generated path is already ignored
|
|
60
|
-
*/
|
|
61
|
-
private isPathIgnored;
|
|
62
|
-
/**
|
|
63
|
-
* Adds ignore rule to existing .gitignore
|
|
64
|
-
*/
|
|
65
|
-
private addIgnoreRule;
|
|
66
|
-
/**
|
|
67
|
-
* Generates the gitignore section for Story UI
|
|
68
|
-
*/
|
|
69
|
-
private generateGitignoreSection;
|
|
70
|
-
/**
|
|
71
|
-
* Creates a README in the generated directory explaining its purpose (development only)
|
|
72
|
-
*/
|
|
73
|
-
private createGeneratedDirectoryReadme;
|
|
74
|
-
/**
|
|
75
|
-
* Cleans up old generated stories (safe for both environments)
|
|
76
|
-
*/
|
|
77
|
-
cleanupOldStories(maxAge?: number): void;
|
|
78
|
-
/**
|
|
79
|
-
* Gets the appropriate directory for story generation based on environment
|
|
80
|
-
*/
|
|
81
|
-
getStoryGenerationPath(): string;
|
|
82
|
-
/**
|
|
83
|
-
* Checks if we're in production mode
|
|
84
|
-
*/
|
|
85
|
-
isProductionMode(): boolean;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Convenience function to set up gitignore for Story UI (production-ready)
|
|
89
|
-
*/
|
|
90
|
-
export declare function setupProductionGitignore(config: StoryUIConfig, projectRoot?: string): ProductionGitignoreManager;
|
|
91
|
-
//# sourceMappingURL=productionGitignoreManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"productionGitignoreManager.d.ts","sourceRoot":"","sources":["../../story-generator/productionGitignoreManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;GAEG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAU;gBAElB,MAAM,EAAE,aAAa,EAAE,WAAW,GAAE,MAAsB;IAMtE;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAuBnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,yBAAyB,IAAI,IAAI;IAQjC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAQpC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAmB/B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;OAEG;IACH,0BAA0B,IAAI,MAAM;IAuBpC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IAStC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IA0BvC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAOhC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IAyCtC;;OAEG;IACH,iBAAiB,CAAC,MAAM,GAAE,MAAgC,GAAG,IAAI;IAoCjE;;OAEG;IACH,sBAAsB,IAAI,MAAM;IAYhC;;OAEG;IACH,gBAAgB,IAAI,OAAO;CAG5B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,0BAA0B,CAIhH"}
|