Repository navigation
feat: hand off video turns to local watch-skill #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
| import { videoReferences } from "./watch-skill.ts"; | ||
| describe("watch-skill handoff", () => { | ||
| it("recognizes supported video URLs but ignores normal links", () => expect(videoReferences("see https://youtu.be/demo https://example.com/a https://cdn.x/demo.webm")).toEqual(["https://youtu.be/demo", "https://cdn.x/demo.webm"])); | ||
| it("does not treat prose as a video reference", () => expect(videoReferences("please explain this recording")).toEqual([])); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { execFileSync } from "node:child_process"; | ||
|
|
||
| const VIDEO_URL = /https?:\/\/[^\s<>()]+/gi; | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| const VIDEO_HOST = /(^|\.)(youtube\.com|youtu\.be|vimeo\.com|twitch\.tv|loom\.com)$/i; | ||
| const VIDEO_FILE = /\.(mp4|mov|mkv|webm|avi|m4v)(?:[?#].*)?$/i; | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| /** Conservative detection: ordinary links do not start a video workflow. */ | ||
| export function videoReferences(text: string): string[] { | ||
| return (text.match(VIDEO_URL) ?? []).filter((raw) => { | ||
| try { const url = new URL(raw); return VIDEO_HOST.test(url.hostname) || VIDEO_FILE.test(url.pathname); } catch { return false; } | ||
| }); | ||
| } | ||
|
|
||
| /** No install/fetch side effect. Users opt in by installing watch-skill locally. */ | ||
| export function hasWatchSkill(command = "watch-skill"): boolean { | ||
| try { execFileSync(command, ["--version"], { stdio: "ignore", timeout: 2_000, windowsHide: true }); return true; } catch { return false; } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(watch-skill|server)(\\.|/)' | head -100
printf '%s\n' '--- target file ---'
if [ -f server/watch-skill.ts ]; then
cat -n server/watch-skill.ts
else
printf '%s\n' 'server/watch-skill.ts not found'
fi
printf '%s\n' '--- callers and symbol references ---'
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' \
'hasWatchSkill|watch-skill' .Repository: milind-soni/OpenMausBot Length of output: 3423 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- index outline ---'
ast-grep outline server/index.ts --lang typescript
printf '%s\n' '--- call-site context ---'
sed -n '360,445p' server/index.ts
printf '%s\n' '--- async and request-handler declarations ---'
rg -n -C 3 --glob 'server/index.ts' \
'async |function |const .*=>|app\\.|serve|fetch|request|message|turn|videos' server/index.ts | sed -n '1,240p'Repository: milind-soni/OpenMausBot Length of output: 18129 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- startTurn and dispatch ---'
sed -n '300,485p' server/index.ts
printf '%s\n' '--- HTTP handler and startTurn call sites ---'
sed -n '645,850p' server/index.ts
rg -n -C 5 --glob 'server/index.ts' 'startTurn\\(' server/index.ts
printf '%s\n' '--- package and TypeScript configuration ---'
for f in package.json tsconfig.json; do
if [ -f "$f" ]; then
printf '%s\n' "--- $f ---"
cat "$f"
fi
doneRepository: milind-soni/OpenMausBot Length of output: 17851 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- package and TypeScript configuration ---'
for f in package.json tsconfig.json; do
if [ -f "$f" ]; then
printf '%s\n' "--- $f ---"
cat "$f"
fi
done
printf '%s\n' '--- exact startTurn references ---'
rg -n -F -C 4 'startTurn(' server/index.ts
printf '%s\n' '--- standalone event-loop probe ---'
node - <<'JS'
const { execFileSync } = require("node:child_process");
const start = Date.now();
let timerDelay;
const timer = setTimeout(() => {
timerDelay = Date.now() - start;
}, 25);
try {
execFileSync(process.execPath, ["-e", "setTimeout(() => {}, 150)"], {
stdio: "ignore",
timeout: 2_000,
});
} catch {}
setImmediate(() => {
clearTimeout(timer);
console.log(JSON.stringify({
synchronousCallElapsedMs: Date.now() - start,
timerDelayMs: timerDelay ?? null,
timerWasDelayedUntilAfterProbe: timerDelay !== undefined,
}));
});
JSRepository: milind-soni/OpenMausBot Length of output: 4214 Use an asynchronous
🧰 Tools🪛 ast-grep (0.45.1)[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec. (detect-child-process-typescript) 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| export function watchSkillIntegration(command = "watch-skill") { return { command, args: ["serve"], env: {} as Record<string, string> }; } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: milind-soni/OpenMausBot
Length of output: 14509
🏁 Script executed:
Repository: milind-soni/OpenMausBot
Length of output: 50379
🏁 Script executed:
Repository: milind-soni/OpenMausBot
Length of output: 40461
🏁 Script executed:
Repository: milind-soni/OpenMausBot
Length of output: 506
Forward
watchSkill.envin ACP server configuration.The current producer returns an empty environment, so this is not a current runtime failure. The contract allows non-empty
watchSkill.env, but the ACP adapter drops it. Convert it to ACP’s{ name, value }[]format and add a regression test.🤖 Prompt for AI Agents