From d3f4fd50613710c8ddf81941db4350b55f8fbae9 Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Thu, 12 Mar 2026 14:48:21 -0700 Subject: [PATCH] fix: restore mainline CI on Windows and markdown lint (#415) * fix: restore ci compatibility on windows * fix: normalize hook path assertions on windows * fix: relax repo root assertion on windows * fix: keep hook root assertion strict on windows --- skills/videodb/SKILL.md | 3 +- skills/videodb/reference/api-reference.md | 2 +- skills/videodb/reference/capture-reference.md | 2 +- tests/hooks/hooks.test.js | 31 +++++++++++++++++-- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/skills/videodb/SKILL.md b/skills/videodb/SKILL.md index 5742e59d..fe3216d7 100644 --- a/skills/videodb/SKILL.md +++ b/skills/videodb/SKILL.md @@ -108,7 +108,7 @@ The user must set `VIDEO_DB_API_KEY` using **either** method: - **Export in terminal** (before starting Claude): `export VIDEO_DB_API_KEY=your-key` - **Project `.env` file**: Save `VIDEO_DB_API_KEY=your-key` in the project's `.env` file -Get a free API key at https://console.videodb.io (50 free uploads, no credit card). +Get a free API key at [console.videodb.io](https://console.videodb.io) (50 free uploads, no credit card). **Do NOT** read, write, or handle the API key yourself. Always let the user set it. @@ -354,7 +354,6 @@ Reference documentation is in the `reference/` directory adjacent to this SKILL. - [reference/capture-reference.md](reference/capture-reference.md) - Capture SDK and WebSocket events - [reference/use-cases.md](reference/use-cases.md) - Common video processing patterns and examples - **Do not use ffmpeg, moviepy, or local encoding tools** when VideoDB supports the operation. The following are all handled server-side by VideoDB — trimming, combining clips, overlaying audio or music, adding subtitles, text/image overlays, transcoding, resolution changes, aspect-ratio conversion, resizing for platform requirements, transcription, and media generation. Only fall back to local tools for operations listed under Limitations in reference/editor.md (transitions, speed changes, crop/zoom, colour grading, volume mixing). ### When to use what diff --git a/skills/videodb/reference/api-reference.md b/skills/videodb/reference/api-reference.md index 3c0f231c..5ca529ea 100644 --- a/skills/videodb/reference/api-reference.md +++ b/skills/videodb/reference/api-reference.md @@ -380,7 +380,7 @@ results = video.search( ``` > **Note:** `filter` is an explicit named parameter in `video.search()`. `scene_index_id` is passed through `**kwargs` to the API. - +> > **Important:** `video.search()` raises `InvalidRequestError` with message `"No results found"` when there are no matches. Always wrap search calls in try/except. For scene search, use `score_threshold=0.3` or higher to filter low-relevance noise. For scene search, use `search_type=SearchType.semantic` with `index_type=IndexType.scene`. Pass `scene_index_id` when targeting a specific scene index. See [search.md](search.md) for details. diff --git a/skills/videodb/reference/capture-reference.md b/skills/videodb/reference/capture-reference.md index 125653ea..b002c493 100644 --- a/skills/videodb/reference/capture-reference.md +++ b/skills/videodb/reference/capture-reference.md @@ -107,7 +107,7 @@ Use [scripts/ws_listener.py](../scripts/ws_listener.py) to connect and dump even } ``` -> For latest details, see https://docs.videodb.io/pages/ingest/capture-sdks/realtime-context.md +> For latest details, see [the realtime context docs](https://docs.videodb.io/pages/ingest/capture-sdks/realtime-context.md). --- diff --git a/tests/hooks/hooks.test.js b/tests/hooks/hooks.test.js index 540d5084..60aa91f1 100644 --- a/tests/hooks/hooks.test.js +++ b/tests/hooks/hooks.test.js @@ -98,6 +98,28 @@ function cleanupTestDir(testDir) { fs.rmSync(testDir, { recursive: true, force: true }); } +function normalizeComparablePath(targetPath) { + if (!targetPath) return ''; + + let normalizedPath = String(targetPath).trim().replace(/\\/g, '/'); + + if (/^\/[a-zA-Z]\//.test(normalizedPath)) { + normalizedPath = `${normalizedPath[1]}:/${normalizedPath.slice(3)}`; + } + + if (/^[a-zA-Z]:\//.test(normalizedPath)) { + normalizedPath = `${normalizedPath[0].toUpperCase()}:${normalizedPath.slice(2)}`; + } + + try { + normalizedPath = fs.realpathSync(normalizedPath); + } catch { + // Fall through to string normalization when the path cannot be resolved directly. + } + + return path.normalize(normalizedPath).replace(/\\/g, '/').replace(/^([a-z]):/, (_, drive) => `${drive.toUpperCase()}:`); +} + function createCommandShim(binDir, baseName, logFile) { fs.mkdirSync(binDir, { recursive: true }); @@ -2185,9 +2207,9 @@ async function runTests() { assert.strictEqual(code, 0, `detect-project should source cleanly, stderr: ${stderr}`); - const [projectId, projectDir] = stdout.trim().split(/\r?\n/); + const [projectId] = stdout.trim().split(/\r?\n/); const registryPath = path.join(homeDir, '.claude', 'homunculus', 'projects.json'); - const projectMetadataPath = path.join(projectDir, 'project.json'); + const projectMetadataPath = path.join(homeDir, '.claude', 'homunculus', 'projects', projectId, 'project.json'); assert.ok(projectId, 'detect-project should emit a project id'); assert.ok(fs.existsSync(registryPath), 'projects.json should be created'); @@ -2199,7 +2221,10 @@ async function runTests() { assert.ok(registry[projectId], 'registry should contain the detected project'); assert.strictEqual(metadata.id, projectId, 'project.json should include the detected id'); assert.strictEqual(metadata.name, path.basename(repoDir), 'project.json should include the repo name'); - assert.strictEqual(fs.realpathSync(metadata.root), fs.realpathSync(repoDir), 'project.json should include the repo root'); + const normalizedMetadataRoot = normalizeComparablePath(metadata.root); + const normalizedRepoDir = normalizeComparablePath(repoDir); + assert.ok(normalizedMetadataRoot, 'project.json should include a non-empty repo root'); + assert.strictEqual(normalizedMetadataRoot, normalizedRepoDir, 'project.json should include the repo root'); assert.strictEqual(metadata.remote, 'https://github.com/example/ecc-test.git', 'project.json should include the sanitized remote'); assert.ok(metadata.created_at, 'project.json should include created_at'); assert.ok(metadata.last_seen, 'project.json should include last_seen');