@mytechtoday/augment-extensions 2.2.0 → 2.3.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 +154 -12
- package/augment-extensions/coding-standards/perl/README.md +173 -0
- package/cli/dist/commands/generate-shot-list/formatter/base-formatter.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/base-formatter.js +7 -5
- package/cli/dist/commands/generate-shot-list/formatter/base-formatter.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/json-formatter.d.ts +1 -0
- package/cli/dist/commands/generate-shot-list/formatter/json-formatter.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/json-formatter.js +6 -0
- package/cli/dist/commands/generate-shot-list/formatter/json-formatter.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/jsonl-formatter.d.ts +1 -0
- package/cli/dist/commands/generate-shot-list/formatter/jsonl-formatter.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/jsonl-formatter.js +6 -0
- package/cli/dist/commands/generate-shot-list/formatter/jsonl-formatter.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.d.ts +14 -0
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.js +44 -3
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/context-builder.d.ts +29 -1
- package/cli/dist/commands/generate-shot-list/generator/context-builder.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/context-builder.js +326 -27
- package/cli/dist/commands/generate-shot-list/generator/context-builder.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/index.d.ts +28 -0
- package/cli/dist/commands/generate-shot-list/generator/index.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/index.js +213 -38
- package/cli/dist/commands/generate-shot-list/generator/index.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/metadata-extractor.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/metadata-extractor.js +1 -0
- package/cli/dist/commands/generate-shot-list/generator/metadata-extractor.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/types.d.ts +10 -3
- package/cli/dist/commands/generate-shot-list/generator/types.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/schema/shot-list.schema.json +341 -0
- package/cli/dist/commands/generate-shot-list/schema/validator.d.ts +55 -0
- package/cli/dist/commands/generate-shot-list/schema/validator.d.ts.map +1 -0
- package/cli/dist/commands/generate-shot-list/schema/validator.js +180 -0
- package/cli/dist/commands/generate-shot-list/schema/validator.js.map +1 -0
- package/cli/dist/commands/generate-shot-list.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list.js +35 -24
- package/cli/dist/commands/generate-shot-list.js.map +1 -1
- package/cli/dist/commands/gui.d.ts.map +1 -1
- package/cli/dist/commands/gui.js +28 -9
- package/cli/dist/commands/gui.js.map +1 -1
- package/package.json +2 -1
|
@@ -4,8 +4,12 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Generates Markdown output with structured shot list, headings, metadata tables
|
|
6
6
|
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
7
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
11
|
exports.MarkdownFormatter = void 0;
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
13
|
const base_formatter_1 = require("./base-formatter");
|
|
10
14
|
/**
|
|
11
15
|
* Markdown formatter implementation
|
|
@@ -33,9 +37,9 @@ class MarkdownFormatter extends base_formatter_1.BaseFormatter {
|
|
|
33
37
|
parts.push('| Metric | Value |');
|
|
34
38
|
parts.push('|--------|-------|');
|
|
35
39
|
parts.push(`| Total Shots | ${shotList.totalShots} |`);
|
|
36
|
-
parts.push(`| Total Duration | ${this.
|
|
40
|
+
parts.push(`| Total Duration | ${this.formatTime(shotList.totalDuration)} |`); // Requirement 3: MM:SS format
|
|
37
41
|
parts.push(`| Total Characters | ${shotList.totalCharacters.toLocaleString()} |`);
|
|
38
|
-
parts.push(`| Average Shot Length | ${this.
|
|
42
|
+
parts.push(`| Average Shot Length | ${this.formatTime(Math.round(shotList.totalDuration / shotList.totalShots))} |`); // Requirement 3: MM:SS format
|
|
39
43
|
parts.push(`| Average Characters | ${this.getAverageCharCount(shotList)} |`);
|
|
40
44
|
parts.push(`| Max Characters | ${this.getMaxCharCount(shotList)} |`);
|
|
41
45
|
parts.push(`| Character Limit | ${maxChars} |`);
|
|
@@ -84,7 +88,10 @@ class MarkdownFormatter extends base_formatter_1.BaseFormatter {
|
|
|
84
88
|
parts.push(`| Shot Type | ${shot.metadata.shotType} |`);
|
|
85
89
|
parts.push(`| Camera Movement | ${shot.metadata.cameraMovement} |`);
|
|
86
90
|
parts.push(`| Framing | ${shot.metadata.framing} |`);
|
|
87
|
-
|
|
91
|
+
// Requirement 5: Visual Style Property
|
|
92
|
+
parts.push(`| Visual Style | ${shot.metadata.visualStyle || 'Reality'} |`);
|
|
93
|
+
// Requirement 6: Simplified character count display (no colors in file output)
|
|
94
|
+
parts.push(`| C: | ${shot.characterCount} / ${maxChars} |`);
|
|
88
95
|
if (shot.metadata.technicalNotes && shot.metadata.technicalNotes.length > 0) {
|
|
89
96
|
parts.push(`| Technical Notes | ${shot.metadata.technicalNotes.join(', ')} |`);
|
|
90
97
|
}
|
|
@@ -142,6 +149,40 @@ class MarkdownFormatter extends base_formatter_1.BaseFormatter {
|
|
|
142
149
|
return '🟡';
|
|
143
150
|
return '🟢';
|
|
144
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Get character count color function (Requirement 6)
|
|
154
|
+
* - Green if under 4000 characters
|
|
155
|
+
* - Yellow if between 4000 and 5000 characters
|
|
156
|
+
* - Red if over 5000 characters
|
|
157
|
+
*/
|
|
158
|
+
getCharacterCountColor(charCount, maxChars) {
|
|
159
|
+
if (charCount > 5000) {
|
|
160
|
+
return chalk_1.default.red;
|
|
161
|
+
}
|
|
162
|
+
else if (charCount >= 4000) {
|
|
163
|
+
return chalk_1.default.yellow;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return chalk_1.default.green;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get duration severity color (Requirement 4)
|
|
171
|
+
* - Red for shots exceeding max duration (error)
|
|
172
|
+
* - Yellow for shots approaching max duration (warning)
|
|
173
|
+
* - Green for shots within acceptable range
|
|
174
|
+
*/
|
|
175
|
+
getDurationSeverityColor(duration, maxDuration) {
|
|
176
|
+
if (duration > maxDuration) {
|
|
177
|
+
return chalk_1.default.red; // Error: exceeds max
|
|
178
|
+
}
|
|
179
|
+
else if (duration >= maxDuration * 0.9) {
|
|
180
|
+
return chalk_1.default.yellow; // Warning: approaching limit
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return chalk_1.default.green; // OK
|
|
184
|
+
}
|
|
185
|
+
}
|
|
145
186
|
/**
|
|
146
187
|
* Get file extension
|
|
147
188
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-formatter.js","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/formatter/markdown-formatter.ts"],"names":[],"mappings":";AAAA;;;;GAIG
|
|
1
|
+
{"version":3,"file":"markdown-formatter.js","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/formatter/markdown-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* build complete set and character descriptions per shot.
|
|
7
7
|
*
|
|
8
8
|
* Task: bd-shot-list-3.3
|
|
9
|
+
* Requirement 10: Rich Character Descriptions (Character Bible)
|
|
10
|
+
* Requirement 11: Rich Set Descriptions (Set Bible)
|
|
9
11
|
*/
|
|
10
12
|
import { Scene, SceneElement } from '../parser/types';
|
|
11
13
|
import { SceneContext, CharacterState } from './types';
|
|
@@ -19,20 +21,44 @@ export interface ContextBuilderConfig {
|
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Context Builder class
|
|
24
|
+
* Requirement 9: Track character blocking continuity across shots
|
|
25
|
+
* Requirement 10: Maintain Character Bible for consistent descriptions
|
|
26
|
+
* Requirement 11: Maintain Set Bible for consistent descriptions
|
|
22
27
|
*/
|
|
23
28
|
export declare class ContextBuilder {
|
|
24
29
|
private config;
|
|
30
|
+
private characterBlockingHistory;
|
|
31
|
+
private characterBible;
|
|
32
|
+
private setBible;
|
|
25
33
|
constructor(config: ContextBuilderConfig);
|
|
26
34
|
/**
|
|
27
35
|
* Build scene-level context from scene heading and elements
|
|
36
|
+
* Requirement 11: Use Set Bible to maintain rich, consistent set descriptions
|
|
28
37
|
*/
|
|
29
38
|
buildSceneContext(scene: Scene): SceneContext;
|
|
30
39
|
/**
|
|
31
40
|
* Build character states from scene elements
|
|
41
|
+
* Requirement 9: Maintain character blocking continuity across shots
|
|
42
|
+
* Requirement 10: Use Character Bible to maintain rich, consistent character descriptions
|
|
32
43
|
*/
|
|
33
44
|
buildCharacterStates(elements: SceneElement[], sceneContext: SceneContext): CharacterState[];
|
|
34
45
|
/**
|
|
35
|
-
* Extract
|
|
46
|
+
* Extract environment description from scene
|
|
47
|
+
* Requirement 11: Rich Set Descriptions
|
|
48
|
+
*/
|
|
49
|
+
private extractEnvironment;
|
|
50
|
+
/**
|
|
51
|
+
* Extract rich lighting description from scene elements
|
|
52
|
+
* Requirement 11: Rich Set Descriptions (lighting type, quality, direction, color temp)
|
|
53
|
+
*/
|
|
54
|
+
private extractRichLighting;
|
|
55
|
+
/**
|
|
56
|
+
* Extract set dressing elements from scene
|
|
57
|
+
* Requirement 11: Rich Set Descriptions
|
|
58
|
+
*/
|
|
59
|
+
private extractSetDressing;
|
|
60
|
+
/**
|
|
61
|
+
* Extract lighting from scene elements (legacy method, kept for compatibility)
|
|
36
62
|
*/
|
|
37
63
|
private extractLighting;
|
|
38
64
|
/**
|
|
@@ -49,6 +75,8 @@ export declare class ContextBuilder {
|
|
|
49
75
|
private extractEmotion;
|
|
50
76
|
/**
|
|
51
77
|
* Update character states from action line
|
|
78
|
+
* Requirement 9: Extract blocking, wardrobe, and physical appearance details
|
|
79
|
+
* Requirement 10: Extract props and accessories for Character Bible
|
|
52
80
|
*/
|
|
53
81
|
private updateCharacterStatesFromAction;
|
|
54
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/context-builder.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAkC,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AA6BD;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,wBAAwB,CAA0C;IAC1E,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,QAAQ,CAAyC;gBAE7C,MAAM,EAAE,oBAAoB;IAIxC;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY;IAuD7C;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,YAAY,EAAE,YAAY,GAAG,cAAc,EAAE;IAoF5F;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;;;OAIG;IACH,OAAO,CAAC,+BAA+B;CAmIxC"}
|
|
@@ -7,35 +7,79 @@
|
|
|
7
7
|
* build complete set and character descriptions per shot.
|
|
8
8
|
*
|
|
9
9
|
* Task: bd-shot-list-3.3
|
|
10
|
+
* Requirement 10: Rich Character Descriptions (Character Bible)
|
|
11
|
+
* Requirement 11: Rich Set Descriptions (Set Bible)
|
|
10
12
|
*/
|
|
11
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
14
|
exports.ContextBuilder = void 0;
|
|
13
15
|
/**
|
|
14
16
|
* Context Builder class
|
|
17
|
+
* Requirement 9: Track character blocking continuity across shots
|
|
18
|
+
* Requirement 10: Maintain Character Bible for consistent descriptions
|
|
19
|
+
* Requirement 11: Maintain Set Bible for consistent descriptions
|
|
15
20
|
*/
|
|
16
21
|
class ContextBuilder {
|
|
17
22
|
constructor(config) {
|
|
23
|
+
this.characterBlockingHistory = new Map();
|
|
24
|
+
this.characterBible = new Map(); // Requirement 10
|
|
25
|
+
this.setBible = new Map(); // Requirement 11
|
|
18
26
|
this.config = config;
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
21
29
|
* Build scene-level context from scene heading and elements
|
|
30
|
+
* Requirement 11: Use Set Bible to maintain rich, consistent set descriptions
|
|
22
31
|
*/
|
|
23
32
|
buildSceneContext(scene) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const location = scene.heading.location;
|
|
34
|
+
// Check if we have this set in the Set Bible
|
|
35
|
+
let setBibleEntry = this.setBible.get(location);
|
|
36
|
+
if (!setBibleEntry) {
|
|
37
|
+
// Create new Set Bible entry with rich description
|
|
38
|
+
setBibleEntry = {
|
|
39
|
+
location,
|
|
40
|
+
environment: this.extractEnvironment(scene),
|
|
41
|
+
lighting: this.extractRichLighting(scene),
|
|
42
|
+
atmosphere: this.extractAtmosphere(scene) || 'neutral',
|
|
43
|
+
weather: this.config.includeWeather ? this.extractWeather(scene) : undefined,
|
|
44
|
+
timeOfDay: scene.heading.timeOfDay,
|
|
45
|
+
setDressing: this.extractSetDressing(scene)
|
|
46
|
+
};
|
|
47
|
+
this.setBible.set(location, setBibleEntry);
|
|
31
48
|
}
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
else {
|
|
50
|
+
// Update Set Bible entry if new information is available
|
|
51
|
+
const newLighting = this.extractRichLighting(scene);
|
|
52
|
+
if (newLighting && newLighting !== 'natural') {
|
|
53
|
+
setBibleEntry.lighting = newLighting;
|
|
54
|
+
}
|
|
55
|
+
const newAtmosphere = this.extractAtmosphere(scene);
|
|
56
|
+
if (newAtmosphere) {
|
|
57
|
+
setBibleEntry.atmosphere = newAtmosphere;
|
|
58
|
+
}
|
|
59
|
+
const newWeather = this.extractWeather(scene);
|
|
60
|
+
if (newWeather) {
|
|
61
|
+
setBibleEntry.weather = newWeather;
|
|
62
|
+
}
|
|
63
|
+
setBibleEntry.timeOfDay = scene.heading.timeOfDay;
|
|
64
|
+
const newSetDressing = this.extractSetDressing(scene);
|
|
65
|
+
if (newSetDressing.length > 0) {
|
|
66
|
+
setBibleEntry.setDressing = [...new Set([...setBibleEntry.setDressing, ...newSetDressing])];
|
|
67
|
+
}
|
|
34
68
|
}
|
|
69
|
+
// Build rich context from Set Bible
|
|
70
|
+
const context = {
|
|
71
|
+
set: `${setBibleEntry.environment} - ${location}`,
|
|
72
|
+
lighting: setBibleEntry.lighting,
|
|
73
|
+
timeOfDay: setBibleEntry.timeOfDay,
|
|
74
|
+
atmosphere: setBibleEntry.atmosphere,
|
|
75
|
+
weather: setBibleEntry.weather
|
|
76
|
+
};
|
|
35
77
|
return context;
|
|
36
78
|
}
|
|
37
79
|
/**
|
|
38
80
|
* Build character states from scene elements
|
|
81
|
+
* Requirement 9: Maintain character blocking continuity across shots
|
|
82
|
+
* Requirement 10: Use Character Bible to maintain rich, consistent character descriptions
|
|
39
83
|
*/
|
|
40
84
|
buildCharacterStates(elements, sceneContext) {
|
|
41
85
|
const characterMap = new Map();
|
|
@@ -44,11 +88,41 @@ class ContextBuilder {
|
|
|
44
88
|
const dialogueElement = element;
|
|
45
89
|
const characterName = dialogueElement.dialogue.character.name;
|
|
46
90
|
if (!characterMap.has(characterName)) {
|
|
91
|
+
// Check Character Bible first, then blocking history
|
|
92
|
+
let bibleEntry = this.characterBible.get(characterName);
|
|
93
|
+
const previousState = this.characterBlockingHistory.get(characterName);
|
|
94
|
+
if (!bibleEntry && previousState) {
|
|
95
|
+
// Create Character Bible entry from previous state with verbose defaults
|
|
96
|
+
bibleEntry = {
|
|
97
|
+
name: characterName,
|
|
98
|
+
wardrobe: previousState.wardrobe || 'casual contemporary attire consisting of neutral-toned everyday clothing appropriate for the setting',
|
|
99
|
+
physicalAppearance: previousState.physicalAppearance || 'average build with unremarkable features, medium height, and a natural, unassuming presence',
|
|
100
|
+
props: [],
|
|
101
|
+
lastSeenPosition: previousState.position || 'positioned naturally within the frame',
|
|
102
|
+
lastSeenEmotion: previousState.emotion
|
|
103
|
+
};
|
|
104
|
+
this.characterBible.set(characterName, bibleEntry);
|
|
105
|
+
}
|
|
106
|
+
else if (!bibleEntry) {
|
|
107
|
+
// Create default Character Bible entry with verbose descriptions
|
|
108
|
+
bibleEntry = {
|
|
109
|
+
name: characterName,
|
|
110
|
+
wardrobe: 'casual contemporary attire consisting of neutral-toned everyday clothing appropriate for the setting',
|
|
111
|
+
physicalAppearance: 'average build with unremarkable features, medium height, and a natural, unassuming presence',
|
|
112
|
+
props: [],
|
|
113
|
+
lastSeenPosition: 'positioned naturally within the frame',
|
|
114
|
+
lastSeenEmotion: undefined
|
|
115
|
+
};
|
|
116
|
+
this.characterBible.set(characterName, bibleEntry);
|
|
117
|
+
}
|
|
118
|
+
// Build rich character state from Bible
|
|
47
119
|
characterMap.set(characterName, {
|
|
48
120
|
name: characterName,
|
|
49
|
-
position:
|
|
50
|
-
appearance: '
|
|
51
|
-
|
|
121
|
+
position: bibleEntry.lastSeenPosition,
|
|
122
|
+
appearance: `${bibleEntry.physicalAppearance}${bibleEntry.props.length > 0 ? ', carrying ' + bibleEntry.props.join(', ') : ''}`,
|
|
123
|
+
wardrobe: bibleEntry.wardrobe,
|
|
124
|
+
physicalAppearance: bibleEntry.physicalAppearance,
|
|
125
|
+
emotion: this.config.trackCharacterEmotions ? this.extractEmotion(dialogueElement) : bibleEntry.lastSeenEmotion,
|
|
52
126
|
action: undefined
|
|
53
127
|
});
|
|
54
128
|
}
|
|
@@ -58,6 +132,11 @@ class ContextBuilder {
|
|
|
58
132
|
const emotion = this.extractEmotion(dialogueElement);
|
|
59
133
|
if (emotion) {
|
|
60
134
|
characterMap.get(characterName).emotion = emotion;
|
|
135
|
+
// Update Bible
|
|
136
|
+
const bibleEntry = this.characterBible.get(characterName);
|
|
137
|
+
if (bibleEntry) {
|
|
138
|
+
bibleEntry.lastSeenEmotion = emotion;
|
|
139
|
+
}
|
|
61
140
|
}
|
|
62
141
|
}
|
|
63
142
|
}
|
|
@@ -67,42 +146,155 @@ class ContextBuilder {
|
|
|
67
146
|
this.updateCharacterStatesFromAction(actionElement, characterMap);
|
|
68
147
|
}
|
|
69
148
|
}
|
|
149
|
+
// Update blocking history and Character Bible for continuity
|
|
150
|
+
for (const [name, state] of characterMap.entries()) {
|
|
151
|
+
this.characterBlockingHistory.set(name, { ...state });
|
|
152
|
+
// Update Character Bible with latest information
|
|
153
|
+
const bibleEntry = this.characterBible.get(name);
|
|
154
|
+
if (bibleEntry) {
|
|
155
|
+
if (state.position)
|
|
156
|
+
bibleEntry.lastSeenPosition = state.position;
|
|
157
|
+
if (state.wardrobe)
|
|
158
|
+
bibleEntry.wardrobe = state.wardrobe;
|
|
159
|
+
if (state.physicalAppearance)
|
|
160
|
+
bibleEntry.physicalAppearance = state.physicalAppearance;
|
|
161
|
+
if (state.emotion)
|
|
162
|
+
bibleEntry.lastSeenEmotion = state.emotion;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
70
165
|
return Array.from(characterMap.values());
|
|
71
166
|
}
|
|
72
167
|
/**
|
|
73
|
-
* Extract
|
|
168
|
+
* Extract environment description from scene
|
|
169
|
+
* Requirement 11: Rich Set Descriptions
|
|
74
170
|
*/
|
|
75
|
-
|
|
171
|
+
extractEnvironment(scene) {
|
|
172
|
+
const intExt = scene.heading.intExt;
|
|
173
|
+
const location = scene.heading.location.toLowerCase();
|
|
174
|
+
// Determine environment type
|
|
175
|
+
if (intExt === 'INT') {
|
|
176
|
+
if (location.includes('office') || location.includes('workplace')) {
|
|
177
|
+
return 'Professional interior space';
|
|
178
|
+
}
|
|
179
|
+
else if (location.includes('home') || location.includes('house') || location.includes('apartment')) {
|
|
180
|
+
return 'Residential interior';
|
|
181
|
+
}
|
|
182
|
+
else if (location.includes('restaurant') || location.includes('cafe') || location.includes('bar')) {
|
|
183
|
+
return 'Commercial dining space';
|
|
184
|
+
}
|
|
185
|
+
else if (location.includes('store') || location.includes('shop')) {
|
|
186
|
+
return 'Retail interior';
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return 'Interior space';
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
if (location.includes('street') || location.includes('sidewalk')) {
|
|
194
|
+
return 'Urban exterior';
|
|
195
|
+
}
|
|
196
|
+
else if (location.includes('park') || location.includes('forest') || location.includes('field')) {
|
|
197
|
+
return 'Natural outdoor setting';
|
|
198
|
+
}
|
|
199
|
+
else if (location.includes('parking') || location.includes('lot')) {
|
|
200
|
+
return 'Paved exterior area';
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
return 'Exterior location';
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Extract rich lighting description from scene elements
|
|
209
|
+
* Requirement 11: Rich Set Descriptions (lighting type, quality, direction, color temp)
|
|
210
|
+
*/
|
|
211
|
+
extractRichLighting(scene) {
|
|
76
212
|
const timeOfDay = scene.heading.timeOfDay.toLowerCase();
|
|
77
|
-
|
|
213
|
+
const intExt = scene.heading.intExt;
|
|
214
|
+
// Build rich lighting description
|
|
215
|
+
let lightingType = '';
|
|
216
|
+
let lightingQuality = '';
|
|
217
|
+
let lightingDirection = '';
|
|
218
|
+
let colorTemp = '';
|
|
219
|
+
// Determine lighting type and color temperature based on time of day
|
|
78
220
|
if (timeOfDay.includes('night')) {
|
|
79
|
-
|
|
221
|
+
lightingType = intExt === 'INT' ? 'artificial overhead lighting' : 'moonlight and street lamps';
|
|
222
|
+
colorTemp = intExt === 'INT' ? 'warm tungsten (3200K)' : 'cool blue (5500K)';
|
|
223
|
+
lightingQuality = 'low-key, high contrast';
|
|
80
224
|
}
|
|
81
225
|
else if (timeOfDay.includes('day')) {
|
|
82
|
-
|
|
226
|
+
lightingType = intExt === 'INT' ? 'natural window light' : 'direct sunlight';
|
|
227
|
+
colorTemp = 'daylight balanced (5600K)';
|
|
228
|
+
lightingQuality = 'bright, even illumination';
|
|
229
|
+
lightingDirection = intExt === 'INT' ? 'from windows' : 'overhead sun';
|
|
83
230
|
}
|
|
84
231
|
else if (timeOfDay.includes('dawn') || timeOfDay.includes('dusk')) {
|
|
85
|
-
|
|
232
|
+
lightingType = 'golden hour natural light';
|
|
233
|
+
colorTemp = 'warm amber (3000K)';
|
|
234
|
+
lightingQuality = 'soft, diffused';
|
|
235
|
+
lightingDirection = 'low angle';
|
|
86
236
|
}
|
|
87
237
|
else if (timeOfDay.includes('evening')) {
|
|
88
|
-
|
|
238
|
+
lightingType = intExt === 'INT' ? 'mixed natural and artificial' : 'twilight ambient';
|
|
239
|
+
colorTemp = 'cool to warm transition (4500K)';
|
|
240
|
+
lightingQuality = 'moderate, transitional';
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
lightingType = 'natural ambient';
|
|
244
|
+
colorTemp = 'neutral (5000K)';
|
|
245
|
+
lightingQuality = 'balanced';
|
|
89
246
|
}
|
|
90
|
-
// Check action lines for lighting
|
|
247
|
+
// Check action lines for specific lighting details
|
|
91
248
|
for (const element of scene.elements) {
|
|
92
249
|
if (element.type === 'action') {
|
|
93
250
|
const text = element.text.toLowerCase();
|
|
94
251
|
if (text.includes('dark') || text.includes('shadows')) {
|
|
95
|
-
|
|
252
|
+
lightingQuality = 'low-key, dramatic shadows';
|
|
96
253
|
}
|
|
97
254
|
else if (text.includes('bright') || text.includes('sunlight')) {
|
|
98
|
-
|
|
255
|
+
lightingQuality = 'high-key, bright';
|
|
99
256
|
}
|
|
100
|
-
else if (text.includes('fluorescent')
|
|
101
|
-
|
|
257
|
+
else if (text.includes('fluorescent')) {
|
|
258
|
+
lightingType = 'fluorescent overhead';
|
|
259
|
+
colorTemp = 'cool white (4000K)';
|
|
260
|
+
}
|
|
261
|
+
else if (text.includes('candle') || text.includes('firelight')) {
|
|
262
|
+
lightingType = 'warm practical sources';
|
|
263
|
+
colorTemp = 'very warm (2000K)';
|
|
102
264
|
}
|
|
103
265
|
}
|
|
104
266
|
}
|
|
105
|
-
|
|
267
|
+
// Combine into rich description
|
|
268
|
+
return `${lightingType}, ${lightingQuality}${lightingDirection ? ', ' + lightingDirection : ''}, ${colorTemp}`;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Extract set dressing elements from scene
|
|
272
|
+
* Requirement 11: Rich Set Descriptions
|
|
273
|
+
*/
|
|
274
|
+
extractSetDressing(scene) {
|
|
275
|
+
const dressing = [];
|
|
276
|
+
const dressingKeywords = [
|
|
277
|
+
'table', 'chair', 'desk', 'lamp', 'picture', 'painting', 'plant',
|
|
278
|
+
'couch', 'sofa', 'bed', 'curtain', 'window', 'door', 'shelf',
|
|
279
|
+
'book', 'computer', 'phone', 'clock', 'mirror', 'rug', 'carpet'
|
|
280
|
+
];
|
|
281
|
+
for (const element of scene.elements) {
|
|
282
|
+
if (element.type === 'action') {
|
|
283
|
+
const text = element.text.toLowerCase();
|
|
284
|
+
for (const keyword of dressingKeywords) {
|
|
285
|
+
if (text.includes(keyword) && !dressing.includes(keyword)) {
|
|
286
|
+
dressing.push(keyword);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return dressing;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Extract lighting from scene elements (legacy method, kept for compatibility)
|
|
295
|
+
*/
|
|
296
|
+
extractLighting(scene) {
|
|
297
|
+
return this.extractRichLighting(scene);
|
|
106
298
|
}
|
|
107
299
|
/**
|
|
108
300
|
* Extract atmosphere from scene elements
|
|
@@ -152,14 +344,121 @@ class ContextBuilder {
|
|
|
152
344
|
}
|
|
153
345
|
/**
|
|
154
346
|
* Update character states from action line
|
|
347
|
+
* Requirement 9: Extract blocking, wardrobe, and physical appearance details
|
|
348
|
+
* Requirement 10: Extract props and accessories for Character Bible
|
|
155
349
|
*/
|
|
156
350
|
updateCharacterStatesFromAction(actionElement, characterMap) {
|
|
157
|
-
// Simple implementation: look for character names in action text
|
|
158
|
-
// and update their action field
|
|
159
351
|
const text = actionElement.text;
|
|
160
352
|
for (const [name, state] of characterMap.entries()) {
|
|
161
353
|
if (text.includes(name)) {
|
|
162
354
|
state.action = text;
|
|
355
|
+
// Extract position/blocking keywords
|
|
356
|
+
const positionKeywords = [
|
|
357
|
+
'stands', 'sits', 'walks', 'enters', 'exits', 'moves',
|
|
358
|
+
'left', 'right', 'center', 'foreground', 'background',
|
|
359
|
+
'door', 'window', 'table', 'chair', 'corner'
|
|
360
|
+
];
|
|
361
|
+
for (const keyword of positionKeywords) {
|
|
362
|
+
if (text.toLowerCase().includes(keyword)) {
|
|
363
|
+
// Extract sentence containing the keyword for position context
|
|
364
|
+
const sentences = text.split(/[.!?]/);
|
|
365
|
+
for (const sentence of sentences) {
|
|
366
|
+
if (sentence.toLowerCase().includes(keyword) && sentence.includes(name)) {
|
|
367
|
+
state.position = sentence.trim();
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Extract wardrobe keywords (Requirement 10: Rich character descriptions)
|
|
375
|
+
// Enhanced to capture multiple sentences for verbose descriptions
|
|
376
|
+
const wardrobeKeywords = [
|
|
377
|
+
'wearing', 'dressed in', 'suit', 'dress', 'shirt', 'jacket',
|
|
378
|
+
'coat', 'hat', 'uniform', 'costume', 'clothes', 'tie', 'shoes',
|
|
379
|
+
'jeans', 'pants', 'skirt', 'blouse', 'sweater', 'hoodie', 'robe',
|
|
380
|
+
'cloak', 'vest', 'boots', 'gloves', 'scarf', 'belt'
|
|
381
|
+
];
|
|
382
|
+
for (const keyword of wardrobeKeywords) {
|
|
383
|
+
if (text.toLowerCase().includes(keyword)) {
|
|
384
|
+
const sentences = text.split(/[.!?]/).filter(s => s.trim().length > 0);
|
|
385
|
+
const relevantSentences = [];
|
|
386
|
+
// Collect all sentences mentioning the character and wardrobe
|
|
387
|
+
for (const sentence of sentences) {
|
|
388
|
+
if (sentence.toLowerCase().includes(keyword) && sentence.includes(name)) {
|
|
389
|
+
relevantSentences.push(sentence.trim());
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (relevantSentences.length > 0) {
|
|
393
|
+
// Join multiple sentences for verbose description
|
|
394
|
+
state.wardrobe = relevantSentences.join('. ');
|
|
395
|
+
// Update Character Bible
|
|
396
|
+
const bibleEntry = this.characterBible.get(name);
|
|
397
|
+
if (bibleEntry) {
|
|
398
|
+
bibleEntry.wardrobe = relevantSentences.join('. ');
|
|
399
|
+
}
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
// Extract physical appearance keywords (Requirement 10: Rich character descriptions)
|
|
405
|
+
// Enhanced to capture multiple sentences for verbose descriptions
|
|
406
|
+
const appearanceKeywords = [
|
|
407
|
+
'tall', 'short', 'thin', 'heavy', 'muscular', 'slender',
|
|
408
|
+
'hair', 'eyes', 'beard', 'glasses', 'scar', 'tattoo',
|
|
409
|
+
'young', 'old', 'middle-aged', 'athletic', 'stocky', 'petite',
|
|
410
|
+
'wrinkled', 'smooth', 'pale', 'tanned', 'freckled', 'bald',
|
|
411
|
+
'gray', 'blonde', 'brunette', 'redhead', 'blue eyes', 'brown eyes',
|
|
412
|
+
'green eyes', 'hazel eyes', 'clean-shaven', 'mustache', 'goatee'
|
|
413
|
+
];
|
|
414
|
+
for (const keyword of appearanceKeywords) {
|
|
415
|
+
if (text.toLowerCase().includes(keyword)) {
|
|
416
|
+
const sentences = text.split(/[.!?]/).filter(s => s.trim().length > 0);
|
|
417
|
+
const relevantSentences = [];
|
|
418
|
+
// Collect all sentences mentioning the character and appearance
|
|
419
|
+
for (const sentence of sentences) {
|
|
420
|
+
if (sentence.toLowerCase().includes(keyword) && sentence.includes(name)) {
|
|
421
|
+
relevantSentences.push(sentence.trim());
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (relevantSentences.length > 0) {
|
|
425
|
+
// Join multiple sentences for verbose description
|
|
426
|
+
state.physicalAppearance = relevantSentences.join('. ');
|
|
427
|
+
// Update Character Bible
|
|
428
|
+
const bibleEntry = this.characterBible.get(name);
|
|
429
|
+
if (bibleEntry) {
|
|
430
|
+
bibleEntry.physicalAppearance = relevantSentences.join('. ');
|
|
431
|
+
}
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// Extract props/accessories (Requirement 10: Rich character descriptions)
|
|
437
|
+
const propKeywords = [
|
|
438
|
+
'holding', 'carrying', 'grabs', 'picks up', 'puts down',
|
|
439
|
+
'briefcase', 'bag', 'purse', 'phone', 'keys', 'wallet',
|
|
440
|
+
'gun', 'knife', 'weapon', 'book', 'paper', 'document',
|
|
441
|
+
'coffee', 'drink', 'food', 'cigarette', 'lighter'
|
|
442
|
+
];
|
|
443
|
+
for (const keyword of propKeywords) {
|
|
444
|
+
if (text.toLowerCase().includes(keyword)) {
|
|
445
|
+
const sentences = text.split(/[.!?]/);
|
|
446
|
+
for (const sentence of sentences) {
|
|
447
|
+
if (sentence.toLowerCase().includes(keyword) && sentence.includes(name)) {
|
|
448
|
+
// Update Character Bible with prop
|
|
449
|
+
const bibleEntry = this.characterBible.get(name);
|
|
450
|
+
if (bibleEntry) {
|
|
451
|
+
const prop = sentence.trim();
|
|
452
|
+
if (!bibleEntry.props.includes(prop)) {
|
|
453
|
+
bibleEntry.props.push(prop);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
163
462
|
}
|
|
164
463
|
}
|
|
165
464
|
}
|