@proletariat/cli 0.3.57 → 0.3.59

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 (219) hide show
  1. package/dist/commands/{spec/view.d.ts → dashboard/index.d.ts} +4 -6
  2. package/dist/commands/dashboard/index.js +117 -0
  3. package/dist/commands/dashboard/index.js.map +1 -0
  4. package/dist/commands/execution/config.js +5 -4
  5. package/dist/commands/execution/config.js.map +1 -1
  6. package/dist/commands/execution/stop.js +4 -2
  7. package/dist/commands/execution/stop.js.map +1 -1
  8. package/dist/commands/execution/view.js +3 -0
  9. package/dist/commands/execution/view.js.map +1 -1
  10. package/dist/commands/init.d.ts +1 -0
  11. package/dist/commands/init.js +40 -3
  12. package/dist/commands/init.js.map +1 -1
  13. package/dist/commands/mcp-server.js +1 -2
  14. package/dist/commands/mcp-server.js.map +1 -1
  15. package/dist/commands/media/add.d.ts +19 -0
  16. package/dist/commands/media/add.js +94 -0
  17. package/dist/commands/media/add.js.map +1 -0
  18. package/dist/commands/{spec → media}/index.d.ts +1 -1
  19. package/dist/commands/media/index.js +85 -0
  20. package/dist/commands/media/index.js.map +1 -0
  21. package/dist/commands/{spec/link/remove.d.ts → media/list.d.ts} +3 -6
  22. package/dist/commands/media/list.js +89 -0
  23. package/dist/commands/media/list.js.map +1 -0
  24. package/dist/commands/media/preprocess.d.ts +19 -0
  25. package/dist/commands/media/preprocess.js +91 -0
  26. package/dist/commands/media/preprocess.js.map +1 -0
  27. package/dist/commands/{spec/delete.d.ts → media/remove.d.ts} +2 -2
  28. package/dist/commands/media/remove.js +101 -0
  29. package/dist/commands/media/remove.js.map +1 -0
  30. package/dist/commands/{spec/link/index.d.ts → media/show.d.ts} +3 -3
  31. package/dist/commands/media/show.js +122 -0
  32. package/dist/commands/media/show.js.map +1 -0
  33. package/dist/commands/orchestrator/start.js +5 -0
  34. package/dist/commands/orchestrator/start.js.map +1 -1
  35. package/dist/commands/session/exec.d.ts +19 -0
  36. package/dist/commands/session/exec.js +205 -0
  37. package/dist/commands/session/exec.js.map +1 -0
  38. package/dist/commands/session/index.js +12 -0
  39. package/dist/commands/session/index.js.map +1 -1
  40. package/dist/commands/{spec/link/depends.d.ts → session/inspect.d.ts} +4 -4
  41. package/dist/commands/session/inspect.js +316 -0
  42. package/dist/commands/session/inspect.js.map +1 -0
  43. package/dist/commands/session/peek.d.ts +15 -0
  44. package/dist/commands/session/peek.js +141 -8
  45. package/dist/commands/session/peek.js.map +1 -1
  46. package/dist/commands/session/poke.d.ts +4 -1
  47. package/dist/commands/session/poke.js +175 -20
  48. package/dist/commands/session/poke.js.map +1 -1
  49. package/dist/commands/session/restart.d.ts +20 -0
  50. package/dist/commands/session/restart.js +320 -0
  51. package/dist/commands/session/restart.js.map +1 -0
  52. package/dist/commands/tools/add.d.ts +20 -0
  53. package/dist/commands/tools/add.js +129 -0
  54. package/dist/commands/tools/add.js.map +1 -0
  55. package/dist/commands/tools/check.d.ts +10 -0
  56. package/dist/commands/tools/check.js +75 -0
  57. package/dist/commands/tools/check.js.map +1 -0
  58. package/dist/commands/tools/detect.d.ts +11 -0
  59. package/dist/commands/tools/detect.js +107 -0
  60. package/dist/commands/tools/detect.js.map +1 -0
  61. package/dist/commands/tools/index.d.ts +11 -0
  62. package/dist/commands/tools/index.js +87 -0
  63. package/dist/commands/tools/index.js.map +1 -0
  64. package/dist/commands/tools/remove.d.ts +13 -0
  65. package/dist/commands/tools/remove.js +55 -0
  66. package/dist/commands/tools/remove.js.map +1 -0
  67. package/dist/commands/trello/configure.d.ts +16 -0
  68. package/dist/commands/trello/configure.js +259 -0
  69. package/dist/commands/trello/configure.js.map +1 -0
  70. package/dist/commands/{spec/plan.d.ts → trello/import.d.ts} +3 -5
  71. package/dist/commands/trello/import.js +241 -0
  72. package/dist/commands/trello/import.js.map +1 -0
  73. package/dist/commands/{spec/ticket.d.ts → trello/sync.d.ts} +5 -6
  74. package/dist/commands/trello/sync.js +190 -0
  75. package/dist/commands/trello/sync.js.map +1 -0
  76. package/dist/commands/work/start.d.ts +2 -0
  77. package/dist/commands/work/start.js +27 -41
  78. package/dist/commands/work/start.js.map +1 -1
  79. package/dist/lib/dashboard/data.d.ts +64 -0
  80. package/dist/lib/dashboard/data.js +259 -0
  81. package/dist/lib/dashboard/data.js.map +1 -0
  82. package/dist/lib/dashboard/html.d.ts +7 -0
  83. package/dist/lib/dashboard/html.js +682 -0
  84. package/dist/lib/dashboard/html.js.map +1 -0
  85. package/dist/lib/dashboard/server.d.ts +20 -0
  86. package/dist/lib/dashboard/server.js +114 -0
  87. package/dist/lib/dashboard/server.js.map +1 -0
  88. package/dist/lib/database/index.d.ts +49 -1
  89. package/dist/lib/database/index.js +127 -0
  90. package/dist/lib/database/index.js.map +1 -1
  91. package/dist/lib/execution/config.d.ts +8 -0
  92. package/dist/lib/execution/config.js +83 -4
  93. package/dist/lib/execution/config.js.map +1 -1
  94. package/dist/lib/execution/runners.d.ts +60 -4
  95. package/dist/lib/execution/runners.js +398 -79
  96. package/dist/lib/execution/runners.js.map +1 -1
  97. package/dist/lib/execution/spawner.d.ts +4 -2
  98. package/dist/lib/execution/spawner.js +54 -47
  99. package/dist/lib/execution/spawner.js.map +1 -1
  100. package/dist/lib/execution/types.d.ts +27 -5
  101. package/dist/lib/execution/types.js +24 -0
  102. package/dist/lib/execution/types.js.map +1 -1
  103. package/dist/lib/external-issues/adapters.d.ts +17 -0
  104. package/dist/lib/external-issues/adapters.js +88 -0
  105. package/dist/lib/external-issues/adapters.js.map +1 -1
  106. package/dist/lib/external-issues/mapping-store.js +1 -1
  107. package/dist/lib/external-issues/shortcut.js +2 -1
  108. package/dist/lib/external-issues/shortcut.js.map +1 -1
  109. package/dist/lib/external-issues/trello.d.ts +80 -0
  110. package/dist/lib/external-issues/trello.js +266 -0
  111. package/dist/lib/external-issues/trello.js.map +1 -0
  112. package/dist/lib/external-issues/types.d.ts +3 -3
  113. package/dist/lib/external-issues/types.js +1 -1
  114. package/dist/lib/external-issues/types.js.map +1 -1
  115. package/dist/lib/linear/client.d.ts +4 -3
  116. package/dist/lib/linear/client.js +185 -122
  117. package/dist/lib/linear/client.js.map +1 -1
  118. package/dist/lib/mcp/tools/cli-passthrough.js +77 -0
  119. package/dist/lib/mcp/tools/cli-passthrough.js.map +1 -1
  120. package/dist/lib/mcp/tools/index.d.ts +0 -1
  121. package/dist/lib/mcp/tools/index.js +0 -1
  122. package/dist/lib/mcp/tools/index.js.map +1 -1
  123. package/dist/lib/media/index.d.ts +91 -0
  124. package/dist/lib/media/index.js +475 -0
  125. package/dist/lib/media/index.js.map +1 -0
  126. package/dist/lib/onboarding/detect-tools.d.ts +15 -0
  127. package/dist/lib/onboarding/detect-tools.js +44 -0
  128. package/dist/lib/onboarding/detect-tools.js.map +1 -0
  129. package/dist/lib/onboarding/index.d.ts +2 -0
  130. package/dist/lib/onboarding/index.js +3 -0
  131. package/dist/lib/onboarding/index.js.map +1 -0
  132. package/dist/lib/onboarding/wizard.d.ts +25 -0
  133. package/dist/lib/onboarding/wizard.js +156 -0
  134. package/dist/lib/onboarding/wizard.js.map +1 -0
  135. package/dist/lib/pmo/schema.d.ts +2 -1
  136. package/dist/lib/pmo/schema.js +3 -1
  137. package/dist/lib/pmo/schema.js.map +1 -1
  138. package/dist/lib/runners/claude-code-runner.js +6 -0
  139. package/dist/lib/runners/claude-code-runner.js.map +1 -1
  140. package/dist/lib/tool-registry/detect.d.ts +20 -0
  141. package/dist/lib/tool-registry/detect.js +95 -0
  142. package/dist/lib/tool-registry/detect.js.map +1 -0
  143. package/dist/lib/tool-registry/index.d.ts +10 -0
  144. package/dist/lib/tool-registry/index.js +13 -0
  145. package/dist/lib/tool-registry/index.js.map +1 -0
  146. package/dist/lib/tool-registry/policy.d.ts +32 -0
  147. package/dist/lib/tool-registry/policy.js +97 -0
  148. package/dist/lib/tool-registry/policy.js.map +1 -0
  149. package/dist/lib/tool-registry/registry.d.ts +42 -0
  150. package/dist/lib/tool-registry/registry.js +120 -0
  151. package/dist/lib/tool-registry/registry.js.map +1 -0
  152. package/dist/lib/tool-registry/spawn.d.ts +50 -0
  153. package/dist/lib/tool-registry/spawn.js +103 -0
  154. package/dist/lib/tool-registry/spawn.js.map +1 -0
  155. package/dist/lib/tool-registry/types.d.ts +56 -0
  156. package/dist/lib/tool-registry/types.js +109 -0
  157. package/dist/lib/tool-registry/types.js.map +1 -0
  158. package/dist/lib/trello/client.d.ts +23 -0
  159. package/dist/lib/trello/client.js +114 -0
  160. package/dist/lib/trello/client.js.map +1 -0
  161. package/dist/lib/trello/config.d.ts +55 -0
  162. package/dist/lib/trello/config.js +127 -0
  163. package/dist/lib/trello/config.js.map +1 -0
  164. package/dist/lib/trello/index.d.ts +5 -0
  165. package/dist/lib/trello/index.js +5 -0
  166. package/dist/lib/trello/index.js.map +1 -0
  167. package/dist/lib/trello/mapper.d.ts +13 -0
  168. package/dist/lib/trello/mapper.js +71 -0
  169. package/dist/lib/trello/mapper.js.map +1 -0
  170. package/dist/lib/trello/sync.d.ts +13 -0
  171. package/dist/lib/trello/sync.js +38 -0
  172. package/dist/lib/trello/sync.js.map +1 -0
  173. package/dist/lib/trello/types.d.ts +53 -0
  174. package/dist/lib/trello/types.js +2 -0
  175. package/dist/lib/trello/types.js.map +1 -0
  176. package/dist/lib/work-source/client.js +17 -0
  177. package/dist/lib/work-source/client.js.map +1 -1
  178. package/dist/lib/work-source/config.d.ts +6 -1
  179. package/dist/lib/work-source/config.js +30 -1
  180. package/dist/lib/work-source/config.js.map +1 -1
  181. package/dist/lib/work-source/index.d.ts +1 -1
  182. package/dist/lib/work-source/index.js +1 -1
  183. package/dist/lib/work-source/index.js.map +1 -1
  184. package/oclif.manifest.json +6524 -6171
  185. package/package.json +6 -2
  186. package/dist/commands/spec/create.d.ts +0 -20
  187. package/dist/commands/spec/create.js +0 -171
  188. package/dist/commands/spec/create.js.map +0 -1
  189. package/dist/commands/spec/delete.js +0 -112
  190. package/dist/commands/spec/delete.js.map +0 -1
  191. package/dist/commands/spec/edit.d.ts +0 -23
  192. package/dist/commands/spec/edit.js +0 -262
  193. package/dist/commands/spec/edit.js.map +0 -1
  194. package/dist/commands/spec/index.js +0 -88
  195. package/dist/commands/spec/index.js.map +0 -1
  196. package/dist/commands/spec/link/depends.js +0 -87
  197. package/dist/commands/spec/link/depends.js.map +0 -1
  198. package/dist/commands/spec/link/index.js +0 -93
  199. package/dist/commands/spec/link/index.js.map +0 -1
  200. package/dist/commands/spec/link/remove.js +0 -91
  201. package/dist/commands/spec/link/remove.js.map +0 -1
  202. package/dist/commands/spec/list.d.ts +0 -14
  203. package/dist/commands/spec/list.js +0 -101
  204. package/dist/commands/spec/list.js.map +0 -1
  205. package/dist/commands/spec/plan.js +0 -102
  206. package/dist/commands/spec/plan.js.map +0 -1
  207. package/dist/commands/spec/ticket.js +0 -144
  208. package/dist/commands/spec/ticket.js.map +0 -1
  209. package/dist/commands/spec/view.js +0 -202
  210. package/dist/commands/spec/view.js.map +0 -1
  211. package/dist/lib/mcp/tools/spec.d.ts +0 -6
  212. package/dist/lib/mcp/tools/spec.js +0 -197
  213. package/dist/lib/mcp/tools/spec.js.map +0 -1
  214. package/dist/lib/pmo/spec-parser.d.ts +0 -25
  215. package/dist/lib/pmo/spec-parser.js +0 -206
  216. package/dist/lib/pmo/spec-parser.js.map +0 -1
  217. package/dist/lib/pmo/spec-types.d.ts +0 -43
  218. package/dist/lib/pmo/spec-types.js +0 -8
  219. package/dist/lib/pmo/spec-types.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Media Library
3
+ *
4
+ * Manages media files (videos, audio) in HQ workspaces.
5
+ * Preprocesses media into frames + transcripts for agent consumption.
6
+ */
7
+ import { type MediaItem } from '../database/index.js';
8
+ export type { MediaItem } from '../database/index.js';
9
+ /**
10
+ * Check if ffmpeg is installed
11
+ */
12
+ export declare function isFfmpegInstalled(): boolean;
13
+ /**
14
+ * Check if whisper (or whisper.cpp) is available for transcription
15
+ */
16
+ export declare function isWhisperInstalled(): boolean;
17
+ /**
18
+ * Detect if a file is video or audio based on extension
19
+ */
20
+ export declare function detectMediaType(filePath: string): 'video' | 'audio' | null;
21
+ /**
22
+ * Get the media directory path within the HQ
23
+ */
24
+ export declare function getMediaDir(hqPath: string): string;
25
+ /**
26
+ * Add a media file to the HQ
27
+ */
28
+ export declare function addMedia(hqPath: string, sourcePath: string, options?: {
29
+ interval?: number;
30
+ transcribe?: boolean;
31
+ }): Promise<{
32
+ success: boolean;
33
+ name: string;
34
+ error?: string;
35
+ }>;
36
+ /**
37
+ * Remove a media item from the HQ
38
+ */
39
+ export declare function removeMedia(hqPath: string, name: string): {
40
+ success: boolean;
41
+ error?: string;
42
+ };
43
+ /**
44
+ * List all media items in the workspace
45
+ */
46
+ export declare function listMedia(hqPath: string): MediaItem[];
47
+ /**
48
+ * Get details for a specific media item
49
+ */
50
+ export declare function showMedia(hqPath: string, name: string): MediaItem | null;
51
+ /**
52
+ * Preprocess a media file: extract frames and generate transcript
53
+ */
54
+ export declare function preprocessMedia(hqPath: string, name: string, options?: {
55
+ interval?: number;
56
+ transcribe?: boolean;
57
+ }): Promise<{
58
+ success: boolean;
59
+ error?: string;
60
+ }>;
61
+ export interface MediaInfo {
62
+ name: string;
63
+ mediaType: 'video' | 'audio';
64
+ status: 'pending' | 'processing' | 'ready' | 'error';
65
+ frameCount: number;
66
+ hasTranscript: boolean;
67
+ durationSeconds: number | null;
68
+ resolution: string | null;
69
+ addedAt: string;
70
+ }
71
+ /**
72
+ * Get workspace media information
73
+ */
74
+ export declare function getWorkspaceMediaInfo(): {
75
+ hqPath: string;
76
+ mediaPath: string;
77
+ media: MediaInfo[];
78
+ };
79
+ /**
80
+ * Copy preprocessed media assets into an agent's workspace directory.
81
+ * Only copies lightweight preprocessed assets (frames/, transcript.md, manifest.json).
82
+ * Does NOT copy the raw source video (too large).
83
+ *
84
+ * @param hqPath - The HQ root path
85
+ * @param agentDir - The agent's working directory (e.g., agents/temp/thick-spiegel)
86
+ */
87
+ export declare function copyMediaToAgentWorkspace(hqPath: string, agentDir: string): void;
88
+ /**
89
+ * Format duration in seconds to human-readable string
90
+ */
91
+ export declare function formatDuration(seconds: number): string;
@@ -0,0 +1,475 @@
1
+ /**
2
+ * Media Library
3
+ *
4
+ * Manages media files (videos, audio) in HQ workspaces.
5
+ * Preprocesses media into frames + transcripts for agent consumption.
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { execSync } from 'node:child_process';
10
+ import chalk from 'chalk';
11
+ import { styles } from '../styles.js';
12
+ import { findHQRoot } from '../workspace.js';
13
+ import { addMediaItemToDatabase, updateMediaItemStatus, getWorkspaceMediaItems, getMediaItem, removeMediaItemFromDatabase, } from '../database/index.js';
14
+ // =============================================================================
15
+ // Dependency Detection
16
+ // =============================================================================
17
+ /**
18
+ * Check if ffmpeg is installed
19
+ */
20
+ export function isFfmpegInstalled() {
21
+ try {
22
+ execSync('ffmpeg -version', { stdio: 'pipe' });
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ /**
30
+ * Check if whisper (or whisper.cpp) is available for transcription
31
+ */
32
+ export function isWhisperInstalled() {
33
+ try {
34
+ execSync('whisper --help', { stdio: 'pipe' });
35
+ return true;
36
+ }
37
+ catch {
38
+ try {
39
+ execSync('whisper-cpp --help', { stdio: 'pipe' });
40
+ return true;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ }
47
+ /**
48
+ * Get the whisper command name (whisper or whisper-cpp)
49
+ */
50
+ function getWhisperCommand() {
51
+ try {
52
+ execSync('whisper --help', { stdio: 'pipe' });
53
+ return 'whisper';
54
+ }
55
+ catch {
56
+ try {
57
+ execSync('whisper-cpp --help', { stdio: 'pipe' });
58
+ return 'whisper-cpp';
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ }
65
+ /**
66
+ * Probe a media file to get its metadata using ffprobe
67
+ */
68
+ function probeMedia(filePath) {
69
+ const result = {
70
+ duration: null,
71
+ width: null,
72
+ height: null,
73
+ hasAudio: false,
74
+ hasVideo: false,
75
+ };
76
+ try {
77
+ const output = execSync(`ffprobe -v quiet -print_format json -show_format -show_streams "${filePath}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
78
+ const data = JSON.parse(output);
79
+ if (data.format?.duration) {
80
+ result.duration = parseFloat(data.format.duration);
81
+ }
82
+ for (const stream of data.streams || []) {
83
+ if (stream.codec_type === 'video') {
84
+ result.hasVideo = true;
85
+ result.width = stream.width;
86
+ result.height = stream.height;
87
+ }
88
+ if (stream.codec_type === 'audio') {
89
+ result.hasAudio = true;
90
+ }
91
+ }
92
+ }
93
+ catch {
94
+ // ffprobe failed - file might not be a valid media file
95
+ }
96
+ return result;
97
+ }
98
+ // =============================================================================
99
+ // Media CRUD Operations
100
+ // =============================================================================
101
+ /**
102
+ * Supported media file extensions
103
+ */
104
+ const VIDEO_EXTENSIONS = new Set(['.mp4', '.mkv', '.avi', '.mov', '.webm', '.flv', '.wmv']);
105
+ const AUDIO_EXTENSIONS = new Set(['.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a', '.wma']);
106
+ /**
107
+ * Detect if a file is video or audio based on extension
108
+ */
109
+ export function detectMediaType(filePath) {
110
+ const ext = path.extname(filePath).toLowerCase();
111
+ if (VIDEO_EXTENSIONS.has(ext))
112
+ return 'video';
113
+ if (AUDIO_EXTENSIONS.has(ext))
114
+ return 'audio';
115
+ return null;
116
+ }
117
+ /**
118
+ * Get the media directory path within the HQ
119
+ */
120
+ export function getMediaDir(hqPath) {
121
+ return path.join(hqPath, 'media');
122
+ }
123
+ /**
124
+ * Add a media file to the HQ
125
+ */
126
+ export async function addMedia(hqPath, sourcePath, options = {}) {
127
+ const resolvedSource = path.resolve(sourcePath);
128
+ if (!fs.existsSync(resolvedSource)) {
129
+ return { success: false, name: '', error: `File not found: ${resolvedSource}` };
130
+ }
131
+ const mediaType = detectMediaType(resolvedSource);
132
+ if (!mediaType) {
133
+ return { success: false, name: '', error: `Unsupported file type: ${path.extname(resolvedSource)}` };
134
+ }
135
+ if (!isFfmpegInstalled()) {
136
+ return { success: false, name: '', error: 'ffmpeg is not installed. Install it with: brew install ffmpeg' };
137
+ }
138
+ const baseName = path.basename(resolvedSource, path.extname(resolvedSource));
139
+ // Sanitize name: lowercase, replace spaces/special chars with hyphens
140
+ const name = baseName.toLowerCase().replace(/[^a-z0-9-_]/g, '-').replace(/-+/g, '-');
141
+ const mediaDir = getMediaDir(hqPath);
142
+ const itemDir = path.join(mediaDir, name);
143
+ if (fs.existsSync(itemDir)) {
144
+ return { success: false, name, error: `Media "${name}" already exists. Remove it first or use a different name.` };
145
+ }
146
+ // Create directory structure
147
+ fs.mkdirSync(itemDir, { recursive: true });
148
+ fs.mkdirSync(path.join(itemDir, 'frames'), { recursive: true });
149
+ // Copy source file
150
+ const ext = path.extname(resolvedSource);
151
+ const destFile = path.join(itemDir, `source${ext}`);
152
+ console.log(styles.muted(`Copying ${resolvedSource} to media/${name}/...`));
153
+ fs.copyFileSync(resolvedSource, destFile);
154
+ // Add to database
155
+ addMediaItemToDatabase(hqPath, {
156
+ name,
157
+ path: `media/${name}`,
158
+ source_path: resolvedSource,
159
+ media_type: mediaType,
160
+ frame_interval: options.interval || 30,
161
+ });
162
+ // Run preprocessing
163
+ console.log(styles.muted('Starting preprocessing...'));
164
+ const preprocessResult = await preprocessMedia(hqPath, name, {
165
+ interval: options.interval || 30,
166
+ transcribe: options.transcribe ?? true,
167
+ });
168
+ if (!preprocessResult.success) {
169
+ console.log(chalk.yellow(`Warning: Preprocessing had issues: ${preprocessResult.error}`));
170
+ console.log(chalk.yellow('You can retry with: prlt media preprocess ' + name));
171
+ }
172
+ return { success: true, name };
173
+ }
174
+ /**
175
+ * Remove a media item from the HQ
176
+ */
177
+ export function removeMedia(hqPath, name) {
178
+ const itemDir = path.join(getMediaDir(hqPath), name);
179
+ // Remove from file system
180
+ if (fs.existsSync(itemDir)) {
181
+ fs.rmSync(itemDir, { recursive: true, force: true });
182
+ }
183
+ // Remove from database
184
+ removeMediaItemFromDatabase(hqPath, name);
185
+ return { success: true };
186
+ }
187
+ /**
188
+ * List all media items in the workspace
189
+ */
190
+ export function listMedia(hqPath) {
191
+ return getWorkspaceMediaItems(hqPath);
192
+ }
193
+ /**
194
+ * Get details for a specific media item
195
+ */
196
+ export function showMedia(hqPath, name) {
197
+ return getMediaItem(hqPath, name);
198
+ }
199
+ // =============================================================================
200
+ // Preprocessing Pipeline
201
+ // =============================================================================
202
+ /**
203
+ * Format seconds into a timestamp string (e.g., "01m30s")
204
+ */
205
+ function formatTimestamp(seconds) {
206
+ const m = Math.floor(seconds / 60);
207
+ const s = Math.floor(seconds % 60);
208
+ return `${String(m).padStart(2, '0')}m${String(s).padStart(2, '0')}s`;
209
+ }
210
+ /**
211
+ * Preprocess a media file: extract frames and generate transcript
212
+ */
213
+ export async function preprocessMedia(hqPath, name, options = {}) {
214
+ const interval = options.interval || 30;
215
+ const transcribe = options.transcribe ?? true;
216
+ const item = getMediaItem(hqPath, name);
217
+ if (!item) {
218
+ return { success: false, error: `Media "${name}" not found` };
219
+ }
220
+ const itemDir = path.join(getMediaDir(hqPath), name);
221
+ if (!fs.existsSync(itemDir)) {
222
+ return { success: false, error: `Media directory not found: ${itemDir}` };
223
+ }
224
+ // Find source file
225
+ const sourceFile = findSourceFile(itemDir);
226
+ if (!sourceFile) {
227
+ return { success: false, error: 'Source media file not found in media directory' };
228
+ }
229
+ // Mark as processing
230
+ updateMediaItemStatus(hqPath, name, { status: 'processing' });
231
+ // Probe media info
232
+ const probe = probeMedia(sourceFile);
233
+ const resolution = probe.width && probe.height ? `${probe.width}x${probe.height}` : undefined;
234
+ // Clean previous frames
235
+ const framesDir = path.join(itemDir, 'frames');
236
+ if (fs.existsSync(framesDir)) {
237
+ fs.rmSync(framesDir, { recursive: true });
238
+ }
239
+ fs.mkdirSync(framesDir, { recursive: true });
240
+ let frameCount = 0;
241
+ let hasTranscript = false;
242
+ const errors = [];
243
+ // Extract frames (only for video)
244
+ if (probe.hasVideo) {
245
+ try {
246
+ console.log(styles.muted(`Extracting frames every ${interval}s...`));
247
+ // Use ffmpeg to extract frames at the specified interval
248
+ // Output as frame_NNNN_XXmYYs.jpg for easy reference
249
+ execSync(`ffmpeg -i "${sourceFile}" -vf "fps=1/${interval}" -q:v 2 "${path.join(framesDir, 'frame_%04d.jpg')}" -y`, { stdio: 'pipe' });
250
+ // Rename frames with timestamps
251
+ const frameFiles = fs.readdirSync(framesDir).filter(f => f.endsWith('.jpg')).sort();
252
+ for (let i = 0; i < frameFiles.length; i++) {
253
+ const oldPath = path.join(framesDir, frameFiles[i]);
254
+ const timestamp = formatTimestamp(i * interval);
255
+ const newName = `frame_${String(i).padStart(4, '0')}_${timestamp}.jpg`;
256
+ const newPath = path.join(framesDir, newName);
257
+ fs.renameSync(oldPath, newPath);
258
+ }
259
+ frameCount = frameFiles.length;
260
+ console.log(styles.muted(`Extracted ${frameCount} frames`));
261
+ }
262
+ catch (error) {
263
+ const msg = error instanceof Error ? error.message : String(error);
264
+ errors.push(`Frame extraction failed: ${msg}`);
265
+ console.log(chalk.yellow(`Warning: Frame extraction failed: ${msg}`));
266
+ }
267
+ }
268
+ // Generate transcript
269
+ if (transcribe && probe.hasAudio) {
270
+ const whisperCmd = getWhisperCommand();
271
+ if (whisperCmd) {
272
+ try {
273
+ console.log(styles.muted('Generating transcript...'));
274
+ // Extract audio to WAV for whisper compatibility
275
+ const wavPath = path.join(itemDir, 'audio.wav');
276
+ execSync(`ffmpeg -i "${sourceFile}" -ar 16000 -ac 1 -c:a pcm_s16le "${wavPath}" -y`, { stdio: 'pipe' });
277
+ // Run whisper
278
+ execSync(`${whisperCmd} "${wavPath}" --output_format txt,json --output_dir "${itemDir}"`, { stdio: 'pipe', timeout: 600000 } // 10 min timeout
279
+ );
280
+ // Clean up WAV
281
+ if (fs.existsSync(wavPath)) {
282
+ fs.unlinkSync(wavPath);
283
+ }
284
+ // Look for generated transcript files and rename them
285
+ const txtFiles = fs.readdirSync(itemDir).filter(f => f.endsWith('.txt') && f !== 'transcript.md');
286
+ const jsonFiles = fs.readdirSync(itemDir).filter(f => f.endsWith('.json') && f !== 'manifest.json');
287
+ if (txtFiles.length > 0) {
288
+ const txtContent = fs.readFileSync(path.join(itemDir, txtFiles[0]), 'utf-8');
289
+ fs.writeFileSync(path.join(itemDir, 'transcript.md'), `# Transcript: ${name}\n\n${txtContent}`);
290
+ // Clean up original
291
+ fs.unlinkSync(path.join(itemDir, txtFiles[0]));
292
+ hasTranscript = true;
293
+ }
294
+ if (jsonFiles.length > 0) {
295
+ fs.renameSync(path.join(itemDir, jsonFiles[0]), path.join(itemDir, 'transcript.json'));
296
+ }
297
+ console.log(styles.muted('Transcript generated'));
298
+ }
299
+ catch (error) {
300
+ const msg = error instanceof Error ? error.message : String(error);
301
+ errors.push(`Transcription failed: ${msg}`);
302
+ console.log(chalk.yellow(`Warning: Transcription failed: ${msg}`));
303
+ }
304
+ }
305
+ else {
306
+ console.log(chalk.yellow('Whisper not installed. Skipping transcription.'));
307
+ console.log(chalk.yellow('Install with: pip install openai-whisper'));
308
+ }
309
+ }
310
+ else if (transcribe && !probe.hasAudio) {
311
+ console.log(styles.muted('No audio stream found. Skipping transcription.'));
312
+ }
313
+ // Generate manifest
314
+ const manifest = generateManifest(name, itemDir, probe, frameCount, hasTranscript, interval);
315
+ fs.writeFileSync(path.join(itemDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
316
+ // Update database
317
+ const status = errors.length > 0 ? 'error' : 'ready';
318
+ updateMediaItemStatus(hqPath, name, {
319
+ status,
320
+ duration_seconds: probe.duration ?? undefined,
321
+ resolution,
322
+ frame_count: frameCount,
323
+ has_transcript: hasTranscript,
324
+ error_message: errors.length > 0 ? errors.join('; ') : undefined,
325
+ });
326
+ if (errors.length > 0) {
327
+ return { success: false, error: errors.join('; ') };
328
+ }
329
+ return { success: true };
330
+ }
331
+ /**
332
+ * Generate a manifest.json with metadata about the preprocessed media
333
+ */
334
+ function generateManifest(name, itemDir, probe, frameCount, hasTranscript, interval) {
335
+ const framesDir = path.join(itemDir, 'frames');
336
+ const frameFiles = fs.existsSync(framesDir)
337
+ ? fs.readdirSync(framesDir).filter(f => f.endsWith('.jpg')).sort()
338
+ : [];
339
+ return {
340
+ name,
341
+ media_type: probe.hasVideo ? 'video' : 'audio',
342
+ duration_seconds: probe.duration,
343
+ resolution: probe.width && probe.height ? `${probe.width}x${probe.height}` : null,
344
+ frame_interval_seconds: interval,
345
+ frame_count: frameCount,
346
+ has_transcript: hasTranscript,
347
+ frames: frameFiles.map((filename, i) => ({
348
+ filename,
349
+ timestamp_seconds: i * interval,
350
+ timestamp_display: formatTimestamp(i * interval),
351
+ })),
352
+ transcript_file: hasTranscript ? 'transcript.md' : null,
353
+ transcript_json_file: fs.existsSync(path.join(itemDir, 'transcript.json')) ? 'transcript.json' : null,
354
+ processed_at: new Date().toISOString(),
355
+ };
356
+ }
357
+ /**
358
+ * Get workspace media information
359
+ */
360
+ export function getWorkspaceMediaInfo() {
361
+ const hqPath = findHQRoot();
362
+ if (!hqPath) {
363
+ throw new Error('Not in an HQ directory. Run "prlt new" first.');
364
+ }
365
+ const mediaPath = getMediaDir(hqPath);
366
+ const items = getWorkspaceMediaItems(hqPath);
367
+ const media = items.map(item => ({
368
+ name: item.name,
369
+ mediaType: item.media_type,
370
+ status: item.status,
371
+ frameCount: item.frame_count,
372
+ hasTranscript: item.has_transcript,
373
+ durationSeconds: item.duration_seconds,
374
+ resolution: item.resolution,
375
+ addedAt: item.added_at,
376
+ }));
377
+ return { hqPath, mediaPath, media };
378
+ }
379
+ // =============================================================================
380
+ // Agent Workspace Mounting (TKT-077)
381
+ // =============================================================================
382
+ /**
383
+ * Copy preprocessed media assets into an agent's workspace directory.
384
+ * Only copies lightweight preprocessed assets (frames/, transcript.md, manifest.json).
385
+ * Does NOT copy the raw source video (too large).
386
+ *
387
+ * @param hqPath - The HQ root path
388
+ * @param agentDir - The agent's working directory (e.g., agents/temp/thick-spiegel)
389
+ */
390
+ export function copyMediaToAgentWorkspace(hqPath, agentDir) {
391
+ const mediaDir = getMediaDir(hqPath);
392
+ if (!fs.existsSync(mediaDir)) {
393
+ return;
394
+ }
395
+ const items = getWorkspaceMediaItems(hqPath);
396
+ const readyItems = items.filter(item => item.status === 'ready');
397
+ if (readyItems.length === 0) {
398
+ return;
399
+ }
400
+ const agentMediaDir = path.join(agentDir, 'media');
401
+ fs.mkdirSync(agentMediaDir, { recursive: true });
402
+ for (const item of readyItems) {
403
+ const sourceItemDir = path.join(hqPath, item.path);
404
+ const destItemDir = path.join(agentMediaDir, item.name);
405
+ if (!fs.existsSync(sourceItemDir)) {
406
+ continue;
407
+ }
408
+ fs.mkdirSync(destItemDir, { recursive: true });
409
+ // Copy manifest.json
410
+ const manifestSrc = path.join(sourceItemDir, 'manifest.json');
411
+ if (fs.existsSync(manifestSrc)) {
412
+ fs.copyFileSync(manifestSrc, path.join(destItemDir, 'manifest.json'));
413
+ }
414
+ // Copy transcript.md
415
+ const transcriptSrc = path.join(sourceItemDir, 'transcript.md');
416
+ if (fs.existsSync(transcriptSrc)) {
417
+ fs.copyFileSync(transcriptSrc, path.join(destItemDir, 'transcript.md'));
418
+ }
419
+ // Copy transcript.json
420
+ const transcriptJsonSrc = path.join(sourceItemDir, 'transcript.json');
421
+ if (fs.existsSync(transcriptJsonSrc)) {
422
+ fs.copyFileSync(transcriptJsonSrc, path.join(destItemDir, 'transcript.json'));
423
+ }
424
+ // Copy frames directory
425
+ const framesSrc = path.join(sourceItemDir, 'frames');
426
+ if (fs.existsSync(framesSrc)) {
427
+ const framesDest = path.join(destItemDir, 'frames');
428
+ fs.mkdirSync(framesDest, { recursive: true });
429
+ const frameFiles = fs.readdirSync(framesSrc);
430
+ for (const file of frameFiles) {
431
+ fs.copyFileSync(path.join(framesSrc, file), path.join(framesDest, file));
432
+ }
433
+ }
434
+ }
435
+ }
436
+ // =============================================================================
437
+ // Utility
438
+ // =============================================================================
439
+ /**
440
+ * Find the source media file in a media item directory
441
+ */
442
+ function findSourceFile(itemDir) {
443
+ const allExtensions = [...VIDEO_EXTENSIONS, ...AUDIO_EXTENSIONS];
444
+ for (const ext of allExtensions) {
445
+ const sourceFile = path.join(itemDir, `source${ext}`);
446
+ if (fs.existsSync(sourceFile)) {
447
+ return sourceFile;
448
+ }
449
+ }
450
+ // Also check for files with 'source' prefix or just any media file
451
+ const files = fs.readdirSync(itemDir);
452
+ for (const file of files) {
453
+ const ext = path.extname(file).toLowerCase();
454
+ if (allExtensions.includes(ext)) {
455
+ return path.join(itemDir, file);
456
+ }
457
+ }
458
+ return null;
459
+ }
460
+ /**
461
+ * Format duration in seconds to human-readable string
462
+ */
463
+ export function formatDuration(seconds) {
464
+ const h = Math.floor(seconds / 3600);
465
+ const m = Math.floor((seconds % 3600) / 60);
466
+ const s = Math.floor(seconds % 60);
467
+ if (h > 0) {
468
+ return `${h}h ${m}m ${s}s`;
469
+ }
470
+ if (m > 0) {
471
+ return `${m}m ${s}s`;
472
+ }
473
+ return `${s}s`;
474
+ }
475
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/media/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface DetectedTool {
2
+ name: string;
3
+ command: string;
4
+ path: string;
5
+ displayName: string;
6
+ }
7
+ export interface ToolDetectionResult {
8
+ tools: DetectedTool[];
9
+ hasClaudeCode: boolean;
10
+ hasCodex: boolean;
11
+ }
12
+ /**
13
+ * Detect which AI tools are installed on the system.
14
+ */
15
+ export declare function detectAITools(): ToolDetectionResult;
@@ -0,0 +1,44 @@
1
+ import { execSync } from 'node:child_process';
2
+ const TOOLS_TO_DETECT = [
3
+ { name: 'claude-code', command: 'claude', displayName: 'Claude Code' },
4
+ { name: 'codex', command: 'codex', displayName: 'Codex' },
5
+ ];
6
+ /**
7
+ * Check if a command is available on the system PATH.
8
+ * Returns the resolved path or null if not found.
9
+ */
10
+ function whichCommand(command) {
11
+ try {
12
+ const result = execSync(`which ${command}`, {
13
+ encoding: 'utf-8',
14
+ stdio: ['pipe', 'pipe', 'pipe'],
15
+ }).trim();
16
+ return result || null;
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ /**
23
+ * Detect which AI tools are installed on the system.
24
+ */
25
+ export function detectAITools() {
26
+ const tools = [];
27
+ for (const tool of TOOLS_TO_DETECT) {
28
+ const toolPath = whichCommand(tool.command);
29
+ if (toolPath) {
30
+ tools.push({
31
+ name: tool.name,
32
+ command: tool.command,
33
+ path: toolPath,
34
+ displayName: tool.displayName,
35
+ });
36
+ }
37
+ }
38
+ return {
39
+ tools,
40
+ hasClaudeCode: tools.some(t => t.name === 'claude-code'),
41
+ hasCodex: tools.some(t => t.name === 'codex'),
42
+ };
43
+ }
44
+ //# sourceMappingURL=detect-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-tools.js","sourceRoot":"","sources":["../../../src/lib/onboarding/detect-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAe9C,MAAM,eAAe,GAAG;IACtB,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE;IACtE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE;CACjD,CAAC;AAEX;;;GAGG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,OAAO,EAAE,EAAE;YAC1C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,MAAM,IAAI,IAAI,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK;QACL,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC;QACxD,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;KAC9C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { detectAITools, type DetectedTool, type ToolDetectionResult } from './detect-tools.js';
2
+ export { runOnboardingWizard, runOnboardingJsonMode, isFirstTimeUser, type OnboardingResult, } from './wizard.js';
@@ -0,0 +1,3 @@
1
+ export { detectAITools } from './detect-tools.js';
2
+ export { runOnboardingWizard, runOnboardingJsonMode, isFirstTimeUser, } from './wizard.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/onboarding/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA+C,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,GAEhB,MAAM,aAAa,CAAC"}