Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions memory-bank/progress.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
# Project Progress

## 🎬 **VIDEO-022: CLI VIDEO ARGUMENT PROCESSING** (2026-03-22)

### **🏆 LATEST ACHIEVEMENT: COMPLETE VIDEO CLI INTEGRATION**

**Objective**: Process video arguments in CLI commands to integrate with the SDK's video processing pipeline
**Achievement**: Implemented comprehensive video file validation and processing in CLI commands
**Impact**: Users can now analyze video files from CLI with proper error handling and validation
**Ticket**: VIDEO-022

**Core Implementation**:
- ✅ **Video File Validation**: Added `validateVideoFiles()` with existence, extension, and permission checks
- ✅ **Supported Formats**: `.mp4, .webm, .mov, .avi, .mkv, .m4v, .wmv, .flv`
- ✅ **URL Bypass**: HTTP(S), file://, and data: URIs skip local validation (handled by SDK)
- ✅ **Descriptive Errors**: Clear error messages with resolved paths for debugging
- ✅ **Integration Tests**: 29 comprehensive tests in `test/cli/video-cli.test.ts`

**Video Options Passed to SDK**:
```typescript
videoOptions: {
frames: argv.videoFrames, // Number of frames to extract (default: 8)
quality: argv.videoQuality, // Frame quality 0-100 (default: 85)
format: argv.videoFormat, // jpeg or png (default: jpeg)
transcribeAudio: argv.transcribeAudio // Audio transcription (default: false)
}
```
Comment on lines +19 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank lines around fenced code blocks to satisfy MD031.

The new section has fenced blocks without surrounding blank lines, which markdownlint flags.

📝 Proposed fix
 **Video Options Passed to SDK**:
+
 ```typescript
 videoOptions: {
   frames: argv.videoFrames,      // Number of frames to extract (default: 8)
   quality: argv.videoQuality,    // Frame quality 0-100 (default: 85)
   format: argv.videoFormat,      // jpeg or png (default: jpeg)
   transcribeAudio: argv.transcribeAudio  // Audio transcription (default: false)
 }

Error Handling:
@@
Example Commands:
+

# Basic video analysis
neurolink generate "Describe this video" --video path/to/video.mp4
@@
# With audio transcription
neurolink generate "Transcribe" --video video.mp4 --transcribe-audio
</details>


Also applies to: 39-49

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>

[warning] 20-20: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @memory-bank/progress.md around lines 19 - 27, The fenced TypeScript and Bash
code blocks (e.g., the "videoOptions" block and the later example block around
lines 39-49) lack surrounding blank lines and violate MD031; insert a single
blank line immediately before and after each fenced code block so there is an
empty line above the opening and an empty line below the closing for
both the videoOptions block and the example commands block.


</details>

<!-- fingerprinting:phantom:poseidon:hawk:7bfad6d8-1e59-4b6e-8437-60b2321fa157 -->

<!-- This is an auto-generated comment by CodeRabbit -->


**Error Handling**:
- **Missing file**: Clear message with resolved path
- **Unsupported format**: Lists all supported extensions
- **Permission denied**: Suggests checking file permissions

**Files Modified**:
- `src/cli/factories/commandFactory.ts` - Added validation and processing
- `test/cli/video-cli.test.ts` - 29 integration tests (NEW)
- `memory-bank/cli/VIDEO-CLI-FLAGS-IMPLEMENTATION.md` - Updated documentation

**Example Commands**:
```bash
# Basic video analysis
neurolink generate "Describe this video" --video path/to/video.mp4

# Custom frame extraction
neurolink stream "Analyze" --video video.mp4 --video-frames 10 --video-quality 90

# With audio transcription
neurolink generate "Transcribe" --video video.mp4 --transcribe-audio
```

**Dependencies**: VIDEO-021 (flag definitions), VIDEO-013 (SDK processing)
**Enables**: VIDEO-028, VIDEO-029 (video analysis workflows)

---

## 🚀 **ENTERPRISE IMAGE CACHING SYSTEM IMPLEMENTED** (2026-01-30)

### **🏆 LATEST ACHIEVEMENT: INTELLIGENT IMAGE CACHE WITH LRU & DEDUPLICATION**
Expand Down
79 changes: 78 additions & 1 deletion src/cli/factories/commandFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,91 @@ export class CLICommandFactory {
return resolveFilePaths(paths);
}

// Helper method to process CLI video files
// Supported video file extensions for CLI validation
private static readonly SUPPORTED_VIDEO_EXTENSIONS = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extension list is too small.

".mp4",
".webm",
".mov",
".avi",
".mkv",
".m4v",
".wmv",
".flv",
];

/**
* Check if a string is a URL (http, https, file, or data URI)
*/
private static isURL(str: string): boolean {
const lower = str.toLowerCase();
return (
lower.startsWith("http://") ||
lower.startsWith("https://") ||
lower.startsWith("file://") ||
lower.startsWith("data:")
);
}

/**
* Validate video file paths and throw descriptive errors for invalid files
*
* @param filePaths - Array of file paths to validate
* @throws Error if a file doesn't exist or has an unsupported extension
*/
private static validateVideoFiles(filePaths: string[]): void {
for (const filePath of filePaths) {
// Skip URL validation - URLs are handled by the SDK
if (CLICommandFactory.isURL(filePath)) {
continue;
}

// Resolve relative paths to absolute
const absolutePath = path.resolve(process.cwd(), filePath);

// Check file exists
if (!fs.existsSync(absolutePath)) {
throw new Error(
`Video file not found: ${filePath}\n` +
` Resolved path: ${absolutePath}\n` +
` Please check the file path and try again.`,
);
}

// Check file extension
const ext = path.extname(absolutePath).toLowerCase();
if (!CLICommandFactory.SUPPORTED_VIDEO_EXTENSIONS.includes(ext)) {
throw new Error(
`Unsupported video format: ${ext}\n` +
` File: ${filePath}\n` +
` Supported formats: ${CLICommandFactory.SUPPORTED_VIDEO_EXTENSIONS.join(", ")}`,
);
}

// Check file is readable
try {
fs.accessSync(absolutePath, fs.constants.R_OK);
} catch {
throw new Error(
`Cannot read video file: ${filePath}\n` +
` Resolved path: ${absolutePath}\n` +
` Please check file permissions.`,
);
}
}
}

// Helper method to process CLI video files with validation
private static processCliVideoFiles(
videoFiles?: string | string[],
): Array<Buffer | string> | undefined {
if (!videoFiles) {
return undefined;
}
const paths = Array.isArray(videoFiles) ? videoFiles : [videoFiles];

// Validate video files before resolving paths
CLICommandFactory.validateVideoFiles(paths);

// Resolve relative paths to absolute paths before returning
// URLs are preserved as-is by resolveFilePaths
return resolveFilePaths(paths);
Expand Down
Loading
Loading