gooseworks 0.4.2 → 0.4.5-dev.15.facf60fb

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.
Files changed (156) hide show
  1. package/README.md +84 -22
  2. package/dist/agents/staging.d.ts +38 -0
  3. package/dist/agents/staging.d.ts.map +1 -0
  4. package/dist/agents/staging.js +309 -0
  5. package/dist/agents/staging.js.map +1 -0
  6. package/dist/auth/credentials.d.ts +1 -0
  7. package/dist/auth/credentials.d.ts.map +1 -1
  8. package/dist/auth/credentials.js +26 -8
  9. package/dist/auth/credentials.js.map +1 -1
  10. package/dist/auth/device-flow.d.ts +79 -0
  11. package/dist/auth/device-flow.d.ts.map +1 -0
  12. package/dist/auth/device-flow.js +411 -0
  13. package/dist/auth/device-flow.js.map +1 -0
  14. package/dist/auth/login-mode.d.ts +25 -0
  15. package/dist/auth/login-mode.d.ts.map +1 -0
  16. package/dist/auth/login-mode.js +87 -0
  17. package/dist/auth/login-mode.js.map +1 -0
  18. package/dist/auth/oauth-server.d.ts +2 -2
  19. package/dist/auth/oauth-server.d.ts.map +1 -1
  20. package/dist/auth/oauth-server.js +28 -5
  21. package/dist/auth/oauth-server.js.map +1 -1
  22. package/dist/auth/paste-login.d.ts +27 -0
  23. package/dist/auth/paste-login.d.ts.map +1 -0
  24. package/dist/auth/paste-login.js +203 -0
  25. package/dist/auth/paste-login.js.map +1 -0
  26. package/dist/commands/doctor.d.ts +29 -5
  27. package/dist/commands/doctor.d.ts.map +1 -1
  28. package/dist/commands/doctor.js +116 -63
  29. package/dist/commands/doctor.js.map +1 -1
  30. package/dist/commands/fetch.d.ts +1 -0
  31. package/dist/commands/fetch.d.ts.map +1 -1
  32. package/dist/commands/fetch.js +64 -29
  33. package/dist/commands/fetch.js.map +1 -1
  34. package/dist/commands/formats.js +2 -2
  35. package/dist/commands/formats.js.map +1 -1
  36. package/dist/commands/graphics/publish-flow.js +1 -1
  37. package/dist/commands/graphics/publish-flow.js.map +1 -1
  38. package/dist/commands/install.d.ts.map +1 -1
  39. package/dist/commands/install.js +126 -26
  40. package/dist/commands/install.js.map +1 -1
  41. package/dist/commands/launch.d.ts +3 -0
  42. package/dist/commands/launch.d.ts.map +1 -0
  43. package/dist/commands/launch.js +35 -0
  44. package/dist/commands/launch.js.map +1 -0
  45. package/dist/commands/login.d.ts +21 -1
  46. package/dist/commands/login.d.ts.map +1 -1
  47. package/dist/commands/login.js +112 -30
  48. package/dist/commands/login.js.map +1 -1
  49. package/dist/commands/logout.d.ts.map +1 -1
  50. package/dist/commands/logout.js +7 -1
  51. package/dist/commands/logout.js.map +1 -1
  52. package/dist/commands/skills.d.ts +50 -0
  53. package/dist/commands/skills.d.ts.map +1 -0
  54. package/dist/commands/skills.js +160 -0
  55. package/dist/commands/skills.js.map +1 -0
  56. package/dist/commands/styles.js +2 -2
  57. package/dist/commands/styles.js.map +1 -1
  58. package/dist/commands/tool.d.ts +17 -0
  59. package/dist/commands/tool.d.ts.map +1 -0
  60. package/dist/commands/tool.js +239 -0
  61. package/dist/commands/tool.js.map +1 -0
  62. package/dist/commands/update.d.ts.map +1 -1
  63. package/dist/commands/update.js +37 -6
  64. package/dist/commands/update.js.map +1 -1
  65. package/dist/commands/video-local.d.ts +9 -0
  66. package/dist/commands/video-local.d.ts.map +1 -0
  67. package/dist/commands/video-local.js +83 -0
  68. package/dist/commands/video-local.js.map +1 -0
  69. package/dist/commands/video-save.d.ts +3 -0
  70. package/dist/commands/video-save.d.ts.map +1 -0
  71. package/dist/commands/video-save.js +83 -0
  72. package/dist/commands/video-save.js.map +1 -0
  73. package/dist/config.d.ts.map +1 -1
  74. package/dist/config.js +14 -3
  75. package/dist/config.js.map +1 -1
  76. package/dist/environment.d.ts +9 -0
  77. package/dist/environment.d.ts.map +1 -0
  78. package/dist/environment.js +105 -0
  79. package/dist/environment.js.map +1 -0
  80. package/dist/index.js +12 -38
  81. package/dist/index.js.map +1 -1
  82. package/dist/lib/graphics-cache.d.ts.map +1 -1
  83. package/dist/lib/graphics-cache.js +2 -2
  84. package/dist/lib/graphics-cache.js.map +1 -1
  85. package/dist/lib/mcp-client.d.ts +53 -0
  86. package/dist/lib/mcp-client.d.ts.map +1 -0
  87. package/dist/lib/mcp-client.js +196 -0
  88. package/dist/lib/mcp-client.js.map +1 -0
  89. package/dist/lib/video-local-captions.d.ts +83 -0
  90. package/dist/lib/video-local-captions.d.ts.map +1 -0
  91. package/dist/lib/video-local-captions.js +261 -0
  92. package/dist/lib/video-local-captions.js.map +1 -0
  93. package/dist/lib/video-local-runtime.d.ts +8 -0
  94. package/dist/lib/video-local-runtime.d.ts.map +1 -0
  95. package/dist/lib/video-local-runtime.js +201 -0
  96. package/dist/lib/video-local-runtime.js.map +1 -0
  97. package/dist/lib/video-save-mcp.d.ts +9 -0
  98. package/dist/lib/video-save-mcp.d.ts.map +1 -0
  99. package/dist/lib/video-save-mcp.js +162 -0
  100. package/dist/lib/video-save-mcp.js.map +1 -0
  101. package/dist/lib/video-save.d.ts +77 -0
  102. package/dist/lib/video-save.d.ts.map +1 -0
  103. package/dist/lib/video-save.js +440 -0
  104. package/dist/lib/video-save.js.map +1 -0
  105. package/dist/program.d.ts +2 -0
  106. package/dist/program.d.ts.map +1 -0
  107. package/dist/program.js +56 -0
  108. package/dist/program.js.map +1 -0
  109. package/dist/skills/custom-video-skill.d.ts +3 -0
  110. package/dist/skills/custom-video-skill.d.ts.map +1 -0
  111. package/dist/skills/custom-video-skill.js +6 -0
  112. package/dist/skills/custom-video-skill.js.map +1 -0
  113. package/dist/skills/installer.d.ts +12 -6
  114. package/dist/skills/installer.d.ts.map +1 -1
  115. package/dist/skills/installer.js +82 -38
  116. package/dist/skills/installer.js.map +1 -1
  117. package/dist/skills/master-skill.d.ts +34 -28
  118. package/dist/skills/master-skill.d.ts.map +1 -1
  119. package/dist/skills/master-skill.js +2264 -858
  120. package/dist/skills/master-skill.js.map +1 -1
  121. package/dist/skills/package-freshness.d.ts +16 -0
  122. package/dist/skills/package-freshness.d.ts.map +1 -0
  123. package/dist/skills/package-freshness.js +36 -0
  124. package/dist/skills/package-freshness.js.map +1 -0
  125. package/dist/skills/releases.d.ts +12 -0
  126. package/dist/skills/releases.d.ts.map +1 -0
  127. package/dist/skills/releases.js +155 -0
  128. package/dist/skills/releases.js.map +1 -0
  129. package/dist/skills/routes.d.ts.map +1 -1
  130. package/dist/skills/routes.js +12 -6
  131. package/dist/skills/routes.js.map +1 -1
  132. package/dist/skills/staging-content.d.ts +3 -0
  133. package/dist/skills/staging-content.d.ts.map +1 -0
  134. package/dist/skills/staging-content.js +12 -0
  135. package/dist/skills/staging-content.js.map +1 -0
  136. package/dist/utils/browser-preflight.d.ts +29 -0
  137. package/dist/utils/browser-preflight.d.ts.map +1 -0
  138. package/dist/utils/browser-preflight.js +338 -0
  139. package/dist/utils/browser-preflight.js.map +1 -0
  140. package/dist/utils/http.d.ts +7 -1
  141. package/dist/utils/http.d.ts.map +1 -1
  142. package/dist/utils/http.js +5 -1
  143. package/dist/utils/http.js.map +1 -1
  144. package/package.json +11 -3
  145. package/skills/goose-ads/SKILL.md +509 -239
  146. package/skills/goose-product-photos/SKILL.md +161 -60
  147. package/skills/goose-video/SKILL.md +592 -259
  148. package/skills/goose-video-local/SKILL.md +1409 -236
  149. package/skills/gooseworks/SKILL.md +327 -34
  150. package/skills/make-custom-video/SKILL.md +735 -0
  151. package/skills/manifest.json +12 -0
  152. package/skills/routes.json +13 -6
  153. package/dist/skills/fetcher.d.ts +0 -18
  154. package/dist/skills/fetcher.d.ts.map +0 -1
  155. package/dist/skills/fetcher.js +0 -118
  156. package/dist/skills/fetcher.js.map +0 -1
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.McpError = exports.LOGIN_HINT = void 0;
4
+ exports.mcpEndpoint = mcpEndpoint;
5
+ exports.connectMcp = connectMcp;
6
+ const MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
7
+ const DEFAULT_TIMEOUT_MS = 5 * 60_000;
8
+ const PROTOCOL_VERSION = '2025-03-26';
9
+ exports.LOGIN_HINT = 'Run `npx gooseworks login` (cloud sandbox or SSH: `npx gooseworks login --device --no-wait`).';
10
+ class McpError extends Error {
11
+ status;
12
+ constructor(message, status) {
13
+ super(message);
14
+ this.status = status;
15
+ this.name = 'McpError';
16
+ }
17
+ }
18
+ exports.McpError = McpError;
19
+ /** `<mcp_server_url>/mcp`; HTTPS only, except a local dev server. */
20
+ function mcpEndpoint(mcpServerUrl) {
21
+ const url = new URL(mcpServerUrl);
22
+ const local = ['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname);
23
+ if (url.username || url.password || url.hash || url.search ||
24
+ (url.protocol !== 'https:' && !(url.protocol === 'http:' && local))) {
25
+ throw new McpError('The saved GooseWorks MCP address is not a plain HTTPS URL. ' + exports.LOGIN_HINT);
26
+ }
27
+ const path = url.pathname.replace(/\/+$/, '');
28
+ url.pathname = path.endsWith('/mcp') ? path : `${path}/mcp`;
29
+ return url;
30
+ }
31
+ async function readBounded(response) {
32
+ const length = Number(response.headers.get('content-length'));
33
+ if (length > MAX_RESPONSE_BYTES)
34
+ throw new McpError('The GooseWorks reply is too large (over 8 MB).');
35
+ if (!response.body)
36
+ return '';
37
+ const reader = response.body.getReader();
38
+ const chunks = [];
39
+ let size = 0;
40
+ try {
41
+ for (;;) {
42
+ const { value, done } = await reader.read();
43
+ if (done)
44
+ break;
45
+ size += value.length;
46
+ if (size > MAX_RESPONSE_BYTES)
47
+ throw new McpError('The GooseWorks reply is too large (over 8 MB).');
48
+ chunks.push(Buffer.from(value));
49
+ }
50
+ }
51
+ finally {
52
+ await reader.cancel().catch(() => undefined);
53
+ }
54
+ return Buffer.concat(chunks).toString('utf8');
55
+ }
56
+ /** The JSON-RPC message with `id` from a JSON or SSE (text/event-stream) body. */
57
+ function pickMessage(body, contentType, id) {
58
+ if (contentType?.includes('text/event-stream')) {
59
+ let found;
60
+ for (const event of body.split(/\r?\n\r?\n/)) {
61
+ const data = event.split(/\r?\n/)
62
+ .filter((line) => line.startsWith('data:'))
63
+ .map((line) => line.slice(5).trimStart())
64
+ .join('\n');
65
+ if (!data)
66
+ continue;
67
+ try {
68
+ const parsed = JSON.parse(data);
69
+ if (parsed?.id === id)
70
+ found = parsed;
71
+ }
72
+ catch {
73
+ // Ignore non-JSON keep-alive events.
74
+ }
75
+ }
76
+ return found;
77
+ }
78
+ try {
79
+ return JSON.parse(body);
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ async function connectMcp(creds, opts = {}) {
86
+ if (!creds.mcp_server_url) {
87
+ throw new McpError('This sign-in has no GooseWorks MCP address. ' + exports.LOGIN_HINT);
88
+ }
89
+ const endpoint = mcpEndpoint(creds.mcp_server_url);
90
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
91
+ let session;
92
+ let protocol = PROTOCOL_VERSION;
93
+ let sequence = 0;
94
+ const headers = () => ({
95
+ Authorization: `Bearer ${creds.api_key}`,
96
+ 'Content-Type': 'application/json',
97
+ Accept: 'application/json, text/event-stream',
98
+ 'MCP-Protocol-Version': protocol,
99
+ ...(session ? { 'Mcp-Session-Id': session } : {}),
100
+ });
101
+ const rpc = async (method, params, notification = false) => {
102
+ const id = ++sequence;
103
+ let response;
104
+ try {
105
+ response = await fetch(endpoint, {
106
+ method: 'POST',
107
+ redirect: 'error',
108
+ signal: AbortSignal.timeout(timeoutMs),
109
+ headers: headers(),
110
+ body: JSON.stringify({ jsonrpc: '2.0', ...(notification ? {} : { id }), method, params }),
111
+ });
112
+ }
113
+ catch (err) {
114
+ const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError');
115
+ throw new McpError(timedOut
116
+ ? `GooseWorks did not answer within ${Math.round(timeoutMs / 1000)} seconds. Try again, or pass --timeout.`
117
+ : `Could not reach GooseWorks at ${endpoint.origin}. Check the connection and try again.`);
118
+ }
119
+ if (response.status === 401 || response.status === 403) {
120
+ await response.body?.cancel();
121
+ throw new McpError('GooseWorks did not accept this sign-in. ' + exports.LOGIN_HINT, response.status);
122
+ }
123
+ if (!response.ok) {
124
+ await response.body?.cancel();
125
+ throw new McpError(`GooseWorks answered HTTP ${response.status}. Try again in a moment.`, response.status);
126
+ }
127
+ session = response.headers.get('mcp-session-id') ?? session;
128
+ if (notification) {
129
+ await response.body?.cancel();
130
+ return undefined;
131
+ }
132
+ const message = pickMessage(await readBounded(response), response.headers.get('content-type'), id);
133
+ if (!message || message.id !== id)
134
+ throw new McpError('GooseWorks sent an unexpected reply.');
135
+ if (message.error) {
136
+ const text = typeof message.error.message === 'string' ? message.error.message : 'unknown error';
137
+ throw new McpError(`GooseWorks refused the request: ${text}`);
138
+ }
139
+ return message.result;
140
+ };
141
+ const initialized = await rpc('initialize', {
142
+ protocolVersion: protocol,
143
+ capabilities: {},
144
+ clientInfo: { name: opts.clientName ?? 'gooseworks-cli', version: opts.version ?? '1' },
145
+ });
146
+ if (typeof initialized?.protocolVersion === 'string')
147
+ protocol = initialized.protocolVersion;
148
+ await rpc('notifications/initialized', {}, true);
149
+ const instructions = typeof initialized?.instructions === 'string' && initialized.instructions.trim()
150
+ ? initialized.instructions.trim()
151
+ : null;
152
+ return {
153
+ instructions,
154
+ async listTools() {
155
+ const tools = [];
156
+ const seen = new Set();
157
+ let cursor;
158
+ do {
159
+ const page = await rpc('tools/list', cursor ? { cursor } : {});
160
+ for (const tool of Array.isArray(page?.tools) ? page.tools : []) {
161
+ if (tool && typeof tool.name === 'string')
162
+ tools.push(tool);
163
+ }
164
+ const next = page?.nextCursor;
165
+ if (next !== undefined && next !== null && (typeof next !== 'string' || seen.has(next) || seen.size >= 100)) {
166
+ throw new McpError('GooseWorks sent an unexpected tool list.');
167
+ }
168
+ if (next)
169
+ seen.add(next);
170
+ cursor = next || undefined;
171
+ } while (cursor);
172
+ return tools;
173
+ },
174
+ async callTool(name, args) {
175
+ const result = await rpc('tools/call', { name, arguments: args });
176
+ return (result ?? {});
177
+ },
178
+ async close() {
179
+ if (!session)
180
+ return;
181
+ try {
182
+ const response = await fetch(endpoint, {
183
+ method: 'DELETE',
184
+ redirect: 'error',
185
+ signal: AbortSignal.timeout(10_000),
186
+ headers: headers(),
187
+ });
188
+ await response.body?.cancel();
189
+ }
190
+ catch {
191
+ // The server also cleans up idle sessions.
192
+ }
193
+ },
194
+ };
195
+ }
196
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/lib/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ export declare const MAX_CAPTION_SOURCE_BYTES: number;
2
+ export interface CaptionsPackage {
3
+ version: 1;
4
+ operation: 'captions';
5
+ source_video_url: string;
6
+ source_video_sha256: string;
7
+ ass_text: string;
8
+ edl: {
9
+ width: number;
10
+ height: number;
11
+ segments: Array<{
12
+ dur_s: number;
13
+ }>;
14
+ };
15
+ [key: string]: unknown;
16
+ }
17
+ export interface CaptionClaim {
18
+ claim_id: string;
19
+ lease_token: string;
20
+ lease_expires_at: string;
21
+ package_digest: string;
22
+ package: CaptionsPackage;
23
+ }
24
+ export interface CaptionTransport {
25
+ next(projectId: string, workerId: string): Promise<CaptionClaim | null>;
26
+ status(claimId: string, leaseToken: string): Promise<CaptionClaimStatus>;
27
+ heartbeat(claimId: string, leaseToken: string): Promise<void>;
28
+ complete(claimId: string, leaseToken: string, outputPath: string, sha256: string): Promise<void>;
29
+ }
30
+ export type CaptionClaimStatus = {
31
+ status: 'claimed';
32
+ package_digest: string;
33
+ package: CaptionsPackage;
34
+ lease_expires_at: string;
35
+ } | {
36
+ status: 'completed';
37
+ output_sha256: string;
38
+ output_url: string;
39
+ } | {
40
+ status: 'offered' | 'fallback';
41
+ };
42
+ export interface MediaProbe {
43
+ width: number;
44
+ height: number;
45
+ duration_s: number;
46
+ }
47
+ export interface CaptionRuntime {
48
+ download(url: string, target: string, expectedSha256?: string): Promise<string>;
49
+ preflight(): Promise<string>;
50
+ render(source: string, ass: string, output: string): Promise<void>;
51
+ probe(output: string): Promise<MediaProbe>;
52
+ }
53
+ export type CaptionPhase = 'claimed' | 'downloaded' | 'rendered' | 'completed';
54
+ export interface CaptionJournal {
55
+ claim_id: string;
56
+ project_id: string;
57
+ package_digest: string;
58
+ lease_token: string;
59
+ lease_expires_at: string;
60
+ ffmpeg_version: string;
61
+ phase: CaptionPhase;
62
+ source_sha256?: string;
63
+ output_sha256?: string;
64
+ }
65
+ export declare function validateCaptionClaim(claim: CaptionClaim): {
66
+ expectedDuration: number;
67
+ };
68
+ export declare function sha256File(filePath: string): Promise<string>;
69
+ /** Recover the prior lease/output before asking for new work. Never silently rerender an
70
+ * uncertain completion or let /next hide a still-active claim. */
71
+ export declare function executeNextCaptionClaim(args: {
72
+ projectId: string;
73
+ workerId: string;
74
+ workRoot: string;
75
+ transport: CaptionTransport;
76
+ runtime: CaptionRuntime;
77
+ heartbeatMs?: number;
78
+ }): Promise<{
79
+ claimId: string;
80
+ outputSha256: string;
81
+ journalPath: string;
82
+ } | null>;
83
+ //# sourceMappingURL=video-local-captions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-local-captions.d.ts","sourceRoot":"","sources":["../../src/lib/video-local-captions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MAX_CAPTION_SOURCE_BYTES = void 0;
37
+ exports.validateCaptionClaim = validateCaptionClaim;
38
+ exports.sha256File = sha256File;
39
+ exports.executeNextCaptionClaim = executeNextCaptionClaim;
40
+ /** One server-vetted local operation. This module never invokes a media provider. */
41
+ const crypto_1 = require("crypto");
42
+ const fs_1 = require("fs");
43
+ const promises_1 = require("fs/promises");
44
+ const path = __importStar(require("path"));
45
+ const SHA256 = /^[a-f0-9]{64}$/i;
46
+ const ID = /^[a-zA-Z0-9_-]{1,160}$/;
47
+ exports.MAX_CAPTION_SOURCE_BYTES = 150 * 1024 * 1024;
48
+ async function findPendingJournal(workRoot, projectId) {
49
+ let dirs;
50
+ try {
51
+ dirs = await (0, promises_1.readdir)(workRoot);
52
+ }
53
+ catch (error) {
54
+ if (error.code === 'ENOENT')
55
+ return null;
56
+ throw error;
57
+ }
58
+ const matches = [];
59
+ const unscoped = [];
60
+ for (const dir of dirs) {
61
+ if (!ID.test(dir))
62
+ continue;
63
+ const filePath = path.join(workRoot, dir, 'journal.json');
64
+ try {
65
+ const journal = JSON.parse(await (0, promises_1.readFile)(filePath, 'utf8'));
66
+ if (journal.project_id === projectId && journal.phase !== 'completed')
67
+ matches.push({ filePath, journal });
68
+ else if (!journal.project_id && journal.phase !== 'completed')
69
+ unscoped.push(filePath);
70
+ }
71
+ catch (error) {
72
+ if (error.code !== 'ENOENT')
73
+ throw error;
74
+ }
75
+ }
76
+ if (matches.length > 1)
77
+ throw new Error('Multiple unfinished caption claims exist; inspect the private journals before continuing');
78
+ if (unscoped.length)
79
+ throw new Error(`An older caption journal has no project binding; inspect it before requesting new work: ${unscoped[0]}`);
80
+ return matches[0] ?? null;
81
+ }
82
+ function validateCaptionClaim(claim) {
83
+ if (!claim || !ID.test(claim.claim_id) || !claim.lease_token ||
84
+ !SHA256.test(claim.package_digest) || !Number.isFinite(Date.parse(claim.lease_expires_at))) {
85
+ throw new Error('Invalid local caption claim identity or lease');
86
+ }
87
+ const pack = claim.package;
88
+ if (!pack || pack.version !== 1 || pack.operation !== 'captions' ||
89
+ typeof pack.source_video_url !== 'string' || !pack.source_video_url ||
90
+ typeof pack.ass_text !== 'string' || !pack.ass_text || pack.ass_text.length > 1024 * 1024 ||
91
+ !pack.ass_text.includes('[Script Info]') || !pack.ass_text.includes('[Events]')) {
92
+ throw new Error('Incomplete or unsupported local captions package');
93
+ }
94
+ const sourceUrl = new URL(pack.source_video_url);
95
+ if (sourceUrl.protocol !== 'https:' && !(sourceUrl.protocol === 'http:' &&
96
+ ['localhost', '127.0.0.1', '[::1]'].includes(sourceUrl.hostname))) {
97
+ throw new Error('Caption source must use HTTPS (or local development HTTP)');
98
+ }
99
+ if (!SHA256.test(pack.source_video_sha256)) {
100
+ throw new Error('Missing or invalid source checksum');
101
+ }
102
+ const edl = pack.edl;
103
+ if (!edl || !Number.isInteger(edl.width) || !Number.isInteger(edl.height) ||
104
+ edl.width < 16 || edl.height < 16 || edl.width > 8192 || edl.height > 8192 ||
105
+ !Array.isArray(edl.segments) || !edl.segments.length) {
106
+ throw new Error('Invalid expected caption dimensions or timeline');
107
+ }
108
+ const expectedDuration = edl.segments.reduce((sum, segment) => sum + segment.dur_s, 0);
109
+ if (!Number.isFinite(expectedDuration) || expectedDuration < 0.25 || expectedDuration > 70) {
110
+ throw new Error('Invalid expected caption duration');
111
+ }
112
+ return { expectedDuration };
113
+ }
114
+ async function sha256File(filePath) {
115
+ const hash = (0, crypto_1.createHash)('sha256');
116
+ for await (const chunk of (0, fs_1.createReadStream)(filePath))
117
+ hash.update(chunk);
118
+ return hash.digest('hex');
119
+ }
120
+ async function saveJournal(filePath, journal) {
121
+ const pending = `${filePath}.pending`;
122
+ await (0, promises_1.writeFile)(pending, JSON.stringify(journal, null, 2), { mode: 0o600 });
123
+ await (0, promises_1.rename)(pending, filePath);
124
+ }
125
+ /** Recover the prior lease/output before asking for new work. Never silently rerender an
126
+ * uncertain completion or let /next hide a still-active claim. */
127
+ async function executeNextCaptionClaim(args) {
128
+ if (!ID.test(args.projectId) || !ID.test(args.workerId))
129
+ throw new Error('Invalid project or worker ID');
130
+ const pending = await findPendingJournal(args.workRoot, args.projectId);
131
+ let claim;
132
+ let resumedJournal = null;
133
+ if (pending) {
134
+ const journal = pending.journal;
135
+ if (!ID.test(journal.claim_id) || !SHA256.test(journal.package_digest) || !journal.lease_token) {
136
+ throw new Error('Local caption recovery journal is invalid; inspect it before requesting new work');
137
+ }
138
+ let status;
139
+ try {
140
+ status = await args.transport.status(journal.claim_id, journal.lease_token);
141
+ }
142
+ catch (error) {
143
+ const reason = error instanceof Error ? error.message : String(error);
144
+ throw new Error(`Could not verify prior caption claim ${journal.claim_id} (${reason}). Do not request new work; retain the journal and rerun after server recovery: ${pending.filePath}`);
145
+ }
146
+ if (status.status === 'completed') {
147
+ if (!SHA256.test(status.output_sha256) ||
148
+ (journal.output_sha256 && journal.output_sha256 !== status.output_sha256)) {
149
+ throw new Error('Completed caption receipt does not match the recovery journal');
150
+ }
151
+ journal.output_sha256 = status.output_sha256;
152
+ journal.phase = 'completed';
153
+ await saveJournal(pending.filePath, journal);
154
+ return { claimId: journal.claim_id, outputSha256: status.output_sha256, journalPath: pending.filePath };
155
+ }
156
+ if (status.status === 'offered') {
157
+ const renewed = await args.transport.next(args.projectId, args.workerId);
158
+ if (!renewed)
159
+ throw new Error(`Caption claim ${journal.claim_id} is not reclaimable yet. Rerun after the server offers it. Recovery journal: ${pending.filePath}`);
160
+ if (renewed.claim_id !== journal.claim_id || renewed.package_digest !== journal.package_digest) {
161
+ throw new Error(`Server offered a different caption claim; inspect the old recovery journal: ${pending.filePath}`);
162
+ }
163
+ claim = renewed;
164
+ journal.lease_token = renewed.lease_token;
165
+ resumedJournal = journal;
166
+ }
167
+ else if (status.status === 'claimed') {
168
+ if (status.package_digest !== journal.package_digest ||
169
+ !Number.isFinite(Date.parse(status.lease_expires_at)) || Date.parse(status.lease_expires_at) <= Date.now()) {
170
+ throw new Error(`Caption claim ${journal.claim_id} changed or its lease expired; stop and inspect the recovery journal: ${pending.filePath}`);
171
+ }
172
+ await args.transport.heartbeat(journal.claim_id, journal.lease_token);
173
+ claim = { claim_id: journal.claim_id, lease_token: journal.lease_token,
174
+ lease_expires_at: status.lease_expires_at, package_digest: status.package_digest, package: status.package };
175
+ resumedJournal = journal;
176
+ }
177
+ else {
178
+ throw new Error(`Caption claim ${journal.claim_id} is in server fallback; no local upload is allowed. Recovery journal: ${pending.filePath}`);
179
+ }
180
+ }
181
+ else {
182
+ claim = await args.transport.next(args.projectId, args.workerId);
183
+ }
184
+ if (!claim)
185
+ return null;
186
+ const { expectedDuration } = validateCaptionClaim(claim);
187
+ const claimDir = path.join(args.workRoot, claim.claim_id);
188
+ await (0, promises_1.mkdir)(claimDir, { recursive: true, mode: 0o700 });
189
+ const journalPath = path.join(claimDir, 'journal.json');
190
+ try {
191
+ const existing = JSON.parse(await (0, promises_1.readFile)(journalPath, 'utf8'));
192
+ if (existing.package_digest !== claim.package_digest)
193
+ throw new Error('Claim package changed; refusing old local state');
194
+ }
195
+ catch (error) {
196
+ if (error.code !== 'ENOENT')
197
+ throw error;
198
+ }
199
+ const journal = resumedJournal ?? {
200
+ claim_id: claim.claim_id, project_id: args.projectId, package_digest: claim.package_digest,
201
+ lease_token: claim.lease_token, lease_expires_at: claim.lease_expires_at,
202
+ ffmpeg_version: 'pending preflight', phase: 'claimed',
203
+ };
204
+ journal.lease_expires_at = claim.lease_expires_at;
205
+ await saveJournal(journalPath, journal);
206
+ if (journal.phase !== 'rendered') {
207
+ journal.ffmpeg_version = await args.runtime.preflight();
208
+ await saveJournal(journalPath, journal);
209
+ }
210
+ let heartbeatError = null;
211
+ let heartbeatBusy = false;
212
+ const timer = setInterval(() => {
213
+ if (heartbeatBusy || heartbeatError)
214
+ return;
215
+ heartbeatBusy = true;
216
+ void args.transport.heartbeat(claim.claim_id, claim.lease_token)
217
+ .catch((error) => { heartbeatError = error instanceof Error ? error : new Error(String(error)); })
218
+ .finally(() => { heartbeatBusy = false; });
219
+ }, args.heartbeatMs ?? 60_000);
220
+ try {
221
+ const sourcePath = path.join(claimDir, 'source.mp4');
222
+ const assPath = path.join(claimDir, 'captions.ass');
223
+ const outputPath = path.join(claimDir, 'captioned.mp4');
224
+ if (journal.phase !== 'rendered') {
225
+ journal.source_sha256 = await args.runtime.download(claim.package.source_video_url, sourcePath, claim.package.source_video_sha256);
226
+ journal.phase = 'downloaded';
227
+ await saveJournal(journalPath, journal);
228
+ await (0, promises_1.writeFile)(assPath, claim.package.ass_text, { mode: 0o600 });
229
+ await args.runtime.render(sourcePath, assPath, outputPath);
230
+ }
231
+ else {
232
+ const info = await (0, promises_1.stat)(outputPath).catch(() => null);
233
+ if (!info?.isFile() || !journal.output_sha256 ||
234
+ await sha256File(outputPath) !== journal.output_sha256) {
235
+ throw new Error('Rendered caption output is missing or differs from its journal; refusing upload');
236
+ }
237
+ }
238
+ if (heartbeatError)
239
+ throw heartbeatError;
240
+ const probe = await args.runtime.probe(outputPath);
241
+ if (probe.width !== claim.package.edl.width || probe.height !== claim.package.edl.height ||
242
+ probe.duration_s < Math.max(0.25, expectedDuration - 1) ||
243
+ probe.duration_s > Math.min(70, expectedDuration + 2)) {
244
+ throw new Error('Caption output dimensions or duration do not match the server package');
245
+ }
246
+ journal.output_sha256 = await sha256File(outputPath);
247
+ journal.phase = 'rendered';
248
+ await saveJournal(journalPath, journal);
249
+ await args.transport.heartbeat(claim.claim_id, claim.lease_token);
250
+ if (heartbeatError)
251
+ throw heartbeatError;
252
+ await args.transport.complete(claim.claim_id, claim.lease_token, outputPath, journal.output_sha256);
253
+ journal.phase = 'completed';
254
+ await saveJournal(journalPath, journal);
255
+ return { claimId: claim.claim_id, outputSha256: journal.output_sha256, journalPath };
256
+ }
257
+ finally {
258
+ clearInterval(timer);
259
+ }
260
+ }
261
+ //# sourceMappingURL=video-local-captions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-local-captions.js","sourceRoot":"","sources":["../../src/lib/video-local-captions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { CaptionRuntime, CaptionTransport } from './video-local-captions';
2
+ export declare const LOCAL_UPLOAD_TIMEOUT_MS: number;
3
+ /** HTTP transport uses only the scoped, authenticated local-node route. */
4
+ export declare function createCaptionTransport(apiBase: string, apiKey: string): CaptionTransport;
5
+ /** Reviewed, fixed ffmpeg flags. Neither the server package nor the user supplies flags. */
6
+ export declare const ffmpegCaptionArgs: (sourceName?: string) => string[];
7
+ export declare function createCaptionRuntime(ffmpeg?: string, ffprobe?: string): CaptionRuntime;
8
+ //# sourceMappingURL=video-local-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-local-runtime.d.ts","sourceRoot":"","sources":["../../src/lib/video-local-runtime.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAoC,cAAc,EAAE,gBAAgB,EAAc,MAAM,wBAAwB,CAAC;AAwB7H,eAAO,MAAM,uBAAuB,QAAc,CAAC;AAcnD,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA6CxF;AAED,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,GAAI,mBAAyB,KAAG,MAAM,EAKnE,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,MAAM,SAAW,EAAE,OAAO,SAAY,GAAG,cAAc,CAyD3F"}