@filmwhisper/shared-types 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FilmWhisper Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schemas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * TDD RED → GREEN: Zod schema validation tests for fw-files core types
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { SegmentSchema, UtteranceSchema, TranscriptSchema, FwProjectSchema, ProcessingStatusSchema, JobStatusSchema, ReviewStatusSchema, TimelineClipSchema, JobSchema, } from "../schemas/fw-files.schema.js";
6
+ // ============================================================
7
+ // Segment
8
+ // ============================================================
9
+ describe("SegmentSchema", () => {
10
+ const validSegment = {
11
+ segment_index: 0,
12
+ start_ms: 0,
13
+ end_ms: 5000,
14
+ editorial_role: "establishing",
15
+ energy: 7,
16
+ story_value: 8,
17
+ summary: "Wide shot of sunset over the ocean",
18
+ };
19
+ it("should validate a valid segment", () => {
20
+ const result = SegmentSchema.safeParse(validSegment);
21
+ expect(result.success).toBe(true);
22
+ });
23
+ it("should reject segment with negative start_ms", () => {
24
+ const result = SegmentSchema.safeParse({ ...validSegment, start_ms: -1 });
25
+ expect(result.success).toBe(false);
26
+ });
27
+ it("should reject segment where end_ms <= start_ms", () => {
28
+ const result = SegmentSchema.safeParse({
29
+ ...validSegment,
30
+ start_ms: 5000,
31
+ end_ms: 3000,
32
+ });
33
+ expect(result.success).toBe(false);
34
+ });
35
+ it("should reject segment with empty summary", () => {
36
+ const result = SegmentSchema.safeParse({ ...validSegment, summary: "" });
37
+ expect(result.success).toBe(false);
38
+ });
39
+ it("should reject segment without required fields", () => {
40
+ const result = SegmentSchema.safeParse({
41
+ segment_index: 0,
42
+ start_ms: 0,
43
+ });
44
+ expect(result.success).toBe(false);
45
+ });
46
+ });
47
+ // ============================================================
48
+ // Utterance
49
+ // ============================================================
50
+ describe("UtteranceSchema", () => {
51
+ const validUtterance = {
52
+ speaker_label: "Speaker 1",
53
+ text: "Hello world",
54
+ start_ms: 0,
55
+ end_ms: 2000,
56
+ confidence: 0.95,
57
+ };
58
+ it("should validate a valid utterance", () => {
59
+ const result = UtteranceSchema.safeParse(validUtterance);
60
+ expect(result.success).toBe(true);
61
+ });
62
+ it("should reject confidence > 1", () => {
63
+ const result = UtteranceSchema.safeParse({
64
+ ...validUtterance,
65
+ confidence: 1.5,
66
+ });
67
+ expect(result.success).toBe(false);
68
+ });
69
+ it("should reject confidence < 0", () => {
70
+ const result = UtteranceSchema.safeParse({
71
+ ...validUtterance,
72
+ confidence: -0.1,
73
+ });
74
+ expect(result.success).toBe(false);
75
+ });
76
+ });
77
+ // ============================================================
78
+ // Transcript
79
+ // ============================================================
80
+ describe("TranscriptSchema", () => {
81
+ it("should validate a valid transcript", () => {
82
+ const result = TranscriptSchema.safeParse({
83
+ speakers: ["Speaker 1", "Speaker 2"],
84
+ utterances: [
85
+ {
86
+ speaker_label: "Speaker 1",
87
+ text: "Hello",
88
+ start_ms: 0,
89
+ end_ms: 1000,
90
+ confidence: 0.9,
91
+ },
92
+ ],
93
+ });
94
+ expect(result.success).toBe(true);
95
+ });
96
+ it("should allow empty speakers and utterances", () => {
97
+ const result = TranscriptSchema.safeParse({
98
+ speakers: [],
99
+ utterances: [],
100
+ });
101
+ expect(result.success).toBe(true);
102
+ });
103
+ });
104
+ // ============================================================
105
+ // ProcessingStatus / JobStatus / ReviewStatus (enums)
106
+ // ============================================================
107
+ describe("Status enums", () => {
108
+ it("ProcessingStatus accepts valid values", () => {
109
+ for (const v of ["pending", "running", "complete", "failed"]) {
110
+ expect(ProcessingStatusSchema.safeParse(v).success).toBe(true);
111
+ }
112
+ });
113
+ it("ProcessingStatus rejects invalid values", () => {
114
+ expect(ProcessingStatusSchema.safeParse("cancelled").success).toBe(false);
115
+ });
116
+ it("JobStatus accepts cancelled", () => {
117
+ expect(JobStatusSchema.safeParse("cancelled").success).toBe(true);
118
+ });
119
+ it("ReviewStatus accepts valid values", () => {
120
+ for (const v of ["keep", "exclude", "needs_review"]) {
121
+ expect(ReviewStatusSchema.safeParse(v).success).toBe(true);
122
+ }
123
+ });
124
+ });
125
+ // ============================================================
126
+ // FwProject
127
+ // ============================================================
128
+ describe("FwProjectSchema", () => {
129
+ const validProject = {
130
+ fw_version: "1.0.0",
131
+ schema: "project",
132
+ name: "My Film",
133
+ source_path: "/videos/raw",
134
+ language: "ko",
135
+ created_at: "2026-03-20T00:00:00Z",
136
+ updated_at: "2026-03-20T00:00:00Z",
137
+ };
138
+ it("should validate a valid project", () => {
139
+ const result = FwProjectSchema.safeParse(validProject);
140
+ expect(result.success).toBe(true);
141
+ });
142
+ it("should accept optional fields", () => {
143
+ const result = FwProjectSchema.safeParse({
144
+ ...validProject,
145
+ proxy_spec: "1280x720",
146
+ target_duration_seconds: 120,
147
+ });
148
+ expect(result.success).toBe(true);
149
+ });
150
+ it("should reject schema !== 'project'", () => {
151
+ const result = FwProjectSchema.safeParse({
152
+ ...validProject,
153
+ schema: "asset",
154
+ });
155
+ expect(result.success).toBe(false);
156
+ });
157
+ });
158
+ // ============================================================
159
+ // TimelineClip
160
+ // ============================================================
161
+ describe("TimelineClipSchema", () => {
162
+ const validClip = {
163
+ id: "clip_001",
164
+ asset_hash: "abc123",
165
+ clip_index: 0,
166
+ in_point_ms: 0,
167
+ out_point_ms: 5000,
168
+ created_at: "2026-03-20T00:00:00Z",
169
+ updated_at: "2026-03-20T00:00:00Z",
170
+ };
171
+ it("should validate a valid clip", () => {
172
+ const result = TimelineClipSchema.safeParse(validClip);
173
+ expect(result.success).toBe(true);
174
+ });
175
+ it("should accept optional editorial_rationale", () => {
176
+ const result = TimelineClipSchema.safeParse({
177
+ ...validClip,
178
+ editorial_rationale: "Establishing shot for scene transition",
179
+ });
180
+ expect(result.success).toBe(true);
181
+ });
182
+ it("should reject clip where out_point <= in_point", () => {
183
+ const result = TimelineClipSchema.safeParse({
184
+ ...validClip,
185
+ in_point_ms: 5000,
186
+ out_point_ms: 3000,
187
+ });
188
+ expect(result.success).toBe(false);
189
+ });
190
+ });
191
+ // ============================================================
192
+ // Job
193
+ // ============================================================
194
+ describe("JobSchema", () => {
195
+ const validJob = {
196
+ job_id: "job_001",
197
+ type: "transcode",
198
+ status: "pending",
199
+ progress_pct: 0,
200
+ created_at: "2026-03-20T00:00:00Z",
201
+ updated_at: "2026-03-20T00:00:00Z",
202
+ };
203
+ it("should validate a valid job", () => {
204
+ const result = JobSchema.safeParse(validJob);
205
+ expect(result.success).toBe(true);
206
+ });
207
+ it("should reject progress_pct > 100", () => {
208
+ const result = JobSchema.safeParse({
209
+ ...validJob,
210
+ progress_pct: 150,
211
+ });
212
+ expect(result.success).toBe(false);
213
+ });
214
+ it("should reject progress_pct < 0", () => {
215
+ const result = JobSchema.safeParse({
216
+ ...validJob,
217
+ progress_pct: -10,
218
+ });
219
+ expect(result.success).toBe(false);
220
+ });
221
+ });
222
+ //# sourceMappingURL=schemas.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.js","sourceRoot":"","sources":["../../src/__tests__/schemas.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * MCP error codes for FilmWhisper v2
3
+ * See: DESIGN.md §4 공통 규약
4
+ */
5
+ export declare const MCP_ERROR_CODES: {
6
+ readonly PROJECT_NOT_FOUND: "project_not_found";
7
+ readonly ASSET_NOT_FOUND: "asset_not_found";
8
+ readonly INVALID_INPUT: "invalid_input";
9
+ readonly PROCESSING_IN_PROGRESS: "processing_in_progress";
10
+ readonly NO_EDIT_PACKAGE: "no_edit_package";
11
+ readonly STALE_EDIT_PACKAGE: "stale_edit_package";
12
+ readonly INSUFFICIENT_FOOTAGE: "insufficient_footage";
13
+ readonly FFMPEG_ERROR: "ffmpeg_error";
14
+ readonly PROVIDER_ERROR: "provider_error";
15
+ readonly ENGINE_UNAVAILABLE: "engine_unavailable";
16
+ readonly LOCK_CONFLICT: "lock_conflict";
17
+ readonly REVISION_CONFLICT: "revision_conflict";
18
+ readonly JOB_CANCELLED: "job_cancelled";
19
+ readonly DEPENDENCY_NOT_READY: "dependency_not_ready";
20
+ readonly PROVIDER_TIMEOUT: "provider_timeout";
21
+ readonly CORRUPT_PROJECT: "corrupt_project";
22
+ readonly MEDIA_MISSING: "media_missing";
23
+ };
24
+ export type McpErrorCode = (typeof MCP_ERROR_CODES)[keyof typeof MCP_ERROR_CODES];
25
+ export interface McpError {
26
+ code: McpErrorCode;
27
+ message: string;
28
+ details?: Record<string, unknown>;
29
+ }
30
+ /** Error envelope as specified in DESIGN.md §4: { error: { code, message, details } } */
31
+ export interface McpErrorResponse {
32
+ error: McpError;
33
+ }
34
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;CAkBlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAElF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,CAAC;CACjB"}
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * MCP error codes for FilmWhisper v2
3
+ * See: DESIGN.md §4 공통 규약
4
+ */
5
+ export const MCP_ERROR_CODES = {
6
+ PROJECT_NOT_FOUND: "project_not_found",
7
+ ASSET_NOT_FOUND: "asset_not_found",
8
+ INVALID_INPUT: "invalid_input",
9
+ PROCESSING_IN_PROGRESS: "processing_in_progress",
10
+ NO_EDIT_PACKAGE: "no_edit_package",
11
+ STALE_EDIT_PACKAGE: "stale_edit_package",
12
+ INSUFFICIENT_FOOTAGE: "insufficient_footage",
13
+ FFMPEG_ERROR: "ffmpeg_error",
14
+ PROVIDER_ERROR: "provider_error",
15
+ ENGINE_UNAVAILABLE: "engine_unavailable",
16
+ LOCK_CONFLICT: "lock_conflict",
17
+ REVISION_CONFLICT: "revision_conflict",
18
+ JOB_CANCELLED: "job_cancelled",
19
+ DEPENDENCY_NOT_READY: "dependency_not_ready",
20
+ PROVIDER_TIMEOUT: "provider_timeout",
21
+ CORRUPT_PROJECT: "corrupt_project",
22
+ MEDIA_MISSING: "media_missing",
23
+ };
24
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,iBAAiB,EAAE,mBAAmB;IACtC,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,sBAAsB,EAAE,wBAAwB;IAChD,eAAe,EAAE,iBAAiB;IAClC,kBAAkB,EAAE,oBAAoB;IACxC,oBAAoB,EAAE,sBAAsB;IAC5C,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,gBAAgB;IAChC,kBAAkB,EAAE,oBAAoB;IACxC,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,aAAa,EAAE,eAAe;IAC9B,oBAAoB,EAAE,sBAAsB;IAC5C,gBAAgB,EAAE,kBAAkB;IACpC,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;CACtB,CAAC"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * .fw file format types (JSON files — immutable data) + SQLite row types (mutable state)
3
+ * See: DESIGN.md §2.1
4
+ */
5
+ export interface FwProject {
6
+ fw_version: string;
7
+ schema: "project";
8
+ name: string;
9
+ source_path: string;
10
+ language: string;
11
+ proxy_spec?: string;
12
+ target_duration_seconds?: number;
13
+ created_at: string;
14
+ updated_at: string;
15
+ }
16
+ export interface FwAsset {
17
+ fw_version: string;
18
+ schema: "asset";
19
+ asset_hash: string;
20
+ filename: string;
21
+ source_path: string;
22
+ duration_seconds: number;
23
+ created_at: string;
24
+ updated_at: string;
25
+ transcode_status: ProcessingStatus;
26
+ transcribe_status: ProcessingStatus;
27
+ analyze_status: ProcessingStatus;
28
+ proxy_path?: string;
29
+ analysis?: AssetAnalysis;
30
+ transcript?: Transcript;
31
+ segments?: Segment[];
32
+ }
33
+ /** Asset-level processing status (subset — no "cancelled" since assets aren't cancelled individually) */
34
+ export type ProcessingStatus = "pending" | "running" | "complete" | "failed";
35
+ /** Job-level status (full set, maps to jobs table CHECK constraint) */
36
+ export type JobStatus = "pending" | "running" | "complete" | "failed" | "cancelled";
37
+ export interface TechnicalAnalysis {
38
+ scenes: Array<{
39
+ start_ms: number;
40
+ end_ms: number;
41
+ score: number;
42
+ }>;
43
+ audio_levels: {
44
+ mean_volume_db: number;
45
+ max_volume_db: number;
46
+ };
47
+ silence_ranges: Array<{
48
+ start_ms: number;
49
+ end_ms: number;
50
+ }>;
51
+ duration_ms: number;
52
+ }
53
+ export interface SemanticAnalysis {
54
+ subject: string;
55
+ editorial_role: string;
56
+ energy: number;
57
+ shot_type: string;
58
+ story_value: number;
59
+ summary: string;
60
+ }
61
+ export interface AssetAnalysis {
62
+ technical?: TechnicalAnalysis;
63
+ semantic?: SemanticAnalysis;
64
+ segments?: Segment[];
65
+ }
66
+ export interface Transcript {
67
+ speakers: string[];
68
+ utterances: Utterance[];
69
+ }
70
+ export interface Utterance {
71
+ speaker_label: string;
72
+ text: string;
73
+ start_ms: number;
74
+ end_ms: number;
75
+ confidence: number;
76
+ }
77
+ export interface Segment {
78
+ segment_index: number;
79
+ start_ms: number;
80
+ end_ms: number;
81
+ editorial_role: string;
82
+ energy: number;
83
+ story_value: number;
84
+ summary: string;
85
+ }
86
+ export type ExportFormat = "premiere-xml" | "davinci-xml" | "fcpxml";
87
+ export type RevisionScope = "timeline" | "reviews" | "project" | "jobs" | "fts";
88
+ export interface RevisionEntry {
89
+ scope: RevisionScope;
90
+ revision: number;
91
+ }
92
+ export interface Job {
93
+ job_id: string;
94
+ type: string;
95
+ status: JobStatus;
96
+ progress_pct: number;
97
+ result?: Record<string, unknown>;
98
+ error?: string;
99
+ created_at: string;
100
+ updated_at: string;
101
+ }
102
+ export interface UndoOperation {
103
+ type: string;
104
+ before: Record<string, unknown> | null;
105
+ after: Record<string, unknown> | null;
106
+ }
107
+ export interface UndoHistoryEntry {
108
+ id: number;
109
+ scope: RevisionScope;
110
+ operation: UndoOperation;
111
+ created_at: string;
112
+ }
113
+ export type ReviewStatus = "keep" | "exclude" | "needs_review";
114
+ export interface TimelineClip {
115
+ id: string;
116
+ asset_hash: string;
117
+ clip_index: number;
118
+ in_point_ms: number;
119
+ out_point_ms: number;
120
+ editorial_rationale?: string;
121
+ created_at: string;
122
+ updated_at: string;
123
+ }
124
+ export interface SegmentReview {
125
+ asset_hash: string;
126
+ segment_index: number;
127
+ status: ReviewStatus;
128
+ reviewer?: string;
129
+ updated_at: string;
130
+ }
131
+ export interface SegmentSource {
132
+ rowid?: number;
133
+ asset_hash: string;
134
+ segment_index: number;
135
+ transcript_text?: string;
136
+ analysis_summary?: string;
137
+ editorial_role?: string;
138
+ speaker_labels?: string;
139
+ }
140
+ //# sourceMappingURL=fw-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fw-files.d.ts","sourceRoot":"","sources":["../src/fw-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * .fw file format types (JSON files — immutable data) + SQLite row types (mutable state)
3
+ * See: DESIGN.md §2.1
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=fw-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fw-files.js","sourceRoot":"","sources":["../src/fw-files.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,5 @@
1
+ export * from "./ipc.js";
2
+ export * from "./fw-files.js";
3
+ export * from "./mcp-tools.js";
4
+ export * from "./errors.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./ipc.js";
2
+ export * from "./fw-files.js";
3
+ export * from "./mcp-tools.js";
4
+ export * from "./errors.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}