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
This commit is contained in:
Affaan Mustafa
2026-03-12 14:48:21 -07:00
committed by GitHub
parent bfc73866c9
commit d3f4fd5061
4 changed files with 31 additions and 7 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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).
---

View File

@@ -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');