feat(skill/gemini-image-web): unify image flow with music/video skills

This commit is contained in:
2026-03-04 13:54:27 +08:00
parent 787a3334b6
commit b9153c70c7
4 changed files with 364 additions and 35 deletions
@@ -58,8 +58,8 @@ def parse_args() -> argparse.Namespace:
)
parser.add_argument(
"--prefix",
default="gemini",
help="Filename prefix for collected files. Default: gemini",
default="gemini-image",
help="Filename prefix for collected files. Default: gemini-image",
)
parser.add_argument(
"--batch-id",
@@ -107,7 +107,7 @@ def collect_candidates(source: Path, since_ts: float, allowed_ext: set[str]) ->
files: list[Path] = []
if not source.exists():
return files
for path in source.iterdir():
for path in source.rglob("*"):
if not path.is_file():
continue
ext = path.suffix.lower().lstrip(".")
@@ -125,7 +125,10 @@ def collect_candidates(source: Path, since_ts: float, allowed_ext: set[str]) ->
def discover_playwright_sources() -> list[Path]:
globs = (
"/var/folders/*/*/T/playwright-mcp-output/*",
"/private/var/folders/*/*/T/playwright-mcp-output/*",
"/var/folders/*/*/*/T/playwright-mcp-output/*",
"/private/var/folders/*/*/*/T/playwright-mcp-output/*",
"/tmp/playwright-mcp-output/*",
)
candidates: list[Path] = []
@@ -147,6 +150,8 @@ def resolve_sources(raw_sources: list[str] | None) -> list[Path]:
if raw_sources:
return [Path(item).expanduser().resolve() for item in raw_sources]
auto_sources = discover_playwright_sources()
auto_sources.append((Path.cwd() / ".playwright-cli").resolve())
auto_sources.append((Path(__file__).resolve().parents[3] / ".playwright-cli").resolve())
auto_sources.append((Path.home() / "Downloads").resolve())
result: list[Path] = []
seen: set[Path] = set()
@@ -214,16 +219,23 @@ def iso_ts(ts: float) -> str:
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
def select_source_candidates(
def collect_candidates_all_sources(
sources: list[Path], since_ts: float, allowed_ext: set[str]
) -> tuple[Path | None, list[Path], list[dict[str, object]]]:
) -> tuple[list[Path], list[dict[str, object]]]:
tried: list[dict[str, object]] = []
merged: list[Path] = []
seen: set[Path] = set()
for source in sources:
files = collect_candidates(source, since_ts, allowed_ext)
tried.append({"source": str(source), "matches": len(files)})
if files:
return source, files, tried
return None, [], tried
for file_path in files:
resolved = file_path.resolve()
if resolved in seen:
continue
seen.add(resolved)
merged.append(file_path)
merged.sort(key=lambda p: p.stat().st_mtime, reverse=True)
return merged, tried
def collect_existing_hashes(target: Path, allowed_ext: set[str]) -> set[str]:
@@ -269,9 +281,7 @@ def main() -> int:
return 2
sources = resolve_sources(args.source)
selected_source, candidates, tried_sources = select_source_candidates(
sources, args.since, allowed_ext
)
candidates, tried_sources = collect_candidates_all_sources(sources, args.since, allowed_ext)
if not candidates:
payload = {
"status": "no_matching_files",
@@ -345,7 +355,6 @@ def main() -> int:
"batch_id": batch_id,
"prompt": args.prompt,
"target_dir": str(target),
"source_dir": str(selected_source) if selected_source else None,
"sources_tried": tried_sources,
"since_ts": args.since,
"limit": args.limit,