{"id":"a2816653-02d5-4474-b78b-4680d6eb5af1","entityType":"agent","slug":"clawhub-lumen01-agent-subtitle-translator","name":"Agent Subtitle Translator","canonicalUrl":"https://www.xpersona.co/agent/clawhub-lumen01-agent-subtitle-translator","canonicalPath":"/agent/clawhub-lumen01-agent-subtitle-translator","generatedAt":"2026-10-10T07:40:20.446Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":null},"description":"Translate SRT, VTT, and ASS subtitles safely Skill: Agent Subtitle Translator Owner: lumen01 Summary: Translate SRT, VTT, and ASS subtitles safely Tags: latest:1.0.9 Version history: v1.0.9 | 2026-09-04T10:42:18.665Z | auto - Added full project structure including scripts, assets, web UI, agents, and tests directories - Integrated optional local loopback-only visualizer with secure, display-only web interface - Introduced fixtures and validation tests for SRT,","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17dv4tf5j8ta3eh6hph7m1hns8a6ts5:agent-subtitle-translator","sourceUrl":"https://clawhub.ai/lumen01/agent-subtitle-translator","homepage":"https://clawhub.ai/lumen01/skills/agent-subtitle-translator","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/lumen01/agent-subtitle-translator","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/lumen01/skills/agent-subtitle-translator","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":66,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Translate SRT, VTT, and ASS subtitles safely Skill: Agent Subtitle Translator Owner: lumen01 Summary: Translate SRT, VTT, and ASS subtitles safely Tags: latest:"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":null},"stars":null,"forks":null,"downloads":1968,"packageName":null,"latestVersion":"1.0.9","tractionLabel":"2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T21:43:21.251Z","lastCrawledAt":"2026-10-09T21:43:21.251Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T21:43:21.251Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.9","createdAt":"2026-09-04T10:42:18.665Z","changelog":"- Added full project structure including scripts, assets, web UI, agents, and tests directories - Integrated optional local loopback-only visualizer with secure, display-only web interface - Introduced fixtures and validation tests for SRT, VTT, and ASS subtitle handling - Updated documentation to reflect new setup, runtime boundaries, and visualizer workflow - Removed legacy file: skill-card.md","fileCount":42,"zipByteSize":624243},{"version":"1.0.8","createdAt":"2026-09-04T10:34:36.210Z","changelog":"- Major repository cleanup, removing scripts, tests, assets, source, and workflow directories. - Documentation updates to README.md and README.zh-CN.md. - No workflow or feature changes to the skill's functionality. - Project now includes only documentation and metadata; all code and testing files have been pruned.","fileCount":23,"zipByteSize":77134},{"version":"1.0.7","createdAt":"2026-08-04T07:35:37.711Z","changelog":"agent-subtitle-translator 1.0.7 - Initial release with core subtitle translation workflow and strict local validation. - Supports SRT, WebVTT/VTT, and ASS formats, preserving structure, styles, and timelines. - Provides deterministic batching, validation, and safe output composition with no external translation provider contact. - Includes optional local-only subtitle visualizer web service for progress observation. - Adds extensive documentation, fixtures for multiple formats, and foundational test directory.","fileCount":42,"zipByteSize":624567},{"version":"1.0.6","createdAt":"2026-08-04T07:32:52.987Z","changelog":"agent-subtitle-translator v1.0.6 - Visualizer workflow is now optional; core CLI translation can run independently from the local display service. - Visualizer limited to loopback only (127.0.0.1), with no browser auto-launch or remote access. - Web interface is strictly display-only; no file uploads or translation control from browsers. - Expanded runtime boundaries and clarified local storage/endpoint behavior. - Improved and clarified documentation on agent workflow, prerequisites, and safety checks. - Removed obsolete skill-card.md. Added Openclaw metadata with homepage and required binaries.","fileCount":23,"zipByteSize":77649},{"version":"1.0.5","createdAt":"2026-08-03T08:02:36.190Z","changelog":"**Major update introducing a local visualizer and stricter agent gating process.** - Added a new mandatory Agent visualizer gate: Agents must verify the environment, start the local Web visualizer service, and confirm browser access before processing subtitle tasks. - Introduced a Node.js/TypeScript-powered visualizer web app with task history stored locally, providing a display-only interface for translation progress and validation. - Updated CLI and SKILL documentation to clearly separate visualizer workflow from direct CLI usage, outlining new browser opening rules and service health checks. - Replaced and reorganized project files: new TypeScript sources, build tools, configs, and Web resources added; previous legacy assets, test fixtures, and scripts removed or consolidated. - Changed the report location and clarified output behaviors: batch composition now writes the report adjacent to the output subtitle file. - Enforced that all Agent workflows must pass the visualizer gate before creating subtitle translation tasks; direct CLI usage remains available for deterministic workflows outside Agent sessions.","fileCount":23,"zipByteSize":77542},{"version":"1.0.4","createdAt":"2026-08-01T16:22:22.807Z","changelog":"Initial public release of agent-subtitle-translator. - Added deterministic subtitle file translation for SRT, WebVTT/VTT, and ASS formats with strict local parsing and mapping. - Implemented batch-based translation workflow with robust response validation, error handling, and timeline preservation. - Supported karaoke degradation detection, inline semantic style preservation, and safe output composition. - Included scripts for file preparation, batch processing, response validation, and final subtitle composition. - Provided safety features to protect structure, data integrity, and prevent accidental overwrites. - Included tests and sample subtitle fixtures for validation.","fileCount":24,"zipByteSize":572366},{"version":"1.0.3","createdAt":"2026-08-01T16:01:31.612Z","changelog":"- Added AGENTS.md documenting agent integration details. - Updated configuration in agents/openai.yaml. - Improved and updated README files. - Removed legacy scripts, assets, and all test/fixtures directories. - Streamlined repository by deleting deprecated files and folders.","fileCount":10,"zipByteSize":28065},{"version":"1.0.2","createdAt":"2026-08-01T03:48:41.525Z","changelog":"- Added comprehensive documentation in multiple languages and improved workflow instructions. - Introduced initial test fixtures for SRT, VTT, and ASS subtitle formats. - Enhanced project organization with new scripts, agents, assets, and GitHub Actions workflow. - Removed outdated skill-card documentation. - No changes to subtitle translation algorithms or core workflow logic.","fileCount":23,"zipByteSize":40056}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17dv4tf5j8ta3eh6hph7m1hns8a6ts5:agent-subtitle-translator","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T07:40:20.442Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-lumen01-agent-subtitle-translator/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":null},"readme":"Skill: Agent Subtitle Translator\n\nOwner: lumen01\n\nSummary: Translate SRT, VTT, and ASS subtitles safely\n\nTags: latest:1.0.9\n\nVersion history:\n\nv1.0.9 | 2026-09-04T10:42:18.665Z | auto\n\n- Added full project structure including scripts, assets, web UI, agents, and tests directories\n- Integrated optional local loopback-only visualizer with secure, display-only web interface\n- Introduced fixtures and validation tests for SRT, VTT, and ASS subtitle handling\n- Updated documentation to reflect new setup, runtime boundaries, and visualizer workflow\n- Removed legacy file: skill-card.md\n\nv1.0.8 | 2026-09-04T10:34:36.210Z | auto\n\n- Major repository cleanup, removing scripts, tests, assets, source, and workflow directories.\n- Documentation updates to README.md and README.zh-CN.md.\n- No workflow or feature changes to the skill's functionality.\n- Project now includes only documentation and metadata; all code and testing files have been pruned.\n\nv1.0.7 | 2026-08-04T07:35:37.711Z | auto\n\nagent-subtitle-translator 1.0.7\n\n- Initial release with core subtitle translation workflow and strict local validation.\n- Supports SRT, WebVTT/VTT, and ASS formats, preserving structure, styles, and timelines.\n- Provides deterministic batching, validation, and safe output composition with no external translation provider contact.\n- Includes optional local-only subtitle visualizer web service for progress observation.\n- Adds extensive documentation, fixtures for multiple formats, and foundational test directory.\n\nv1.0.6 | 2026-08-04T07:32:52.987Z | auto\n\nagent-subtitle-translator v1.0.6\n\n- Visualizer workflow is now optional; core CLI translation can run independently from the local display service.\n- Visualizer limited to loopback only (127.0.0.1), with no browser auto-launch or remote access.\n- Web interface is strictly display-only; no file uploads or translation control from browsers.\n- Expanded runtime boundaries and clarified local storage/endpoint behavior.\n- Improved and clarified documentation on agent workflow, prerequisites, and safety checks.\n- Removed obsolete skill-card.md. Added Openclaw metadata with homepage and required binaries.\n\nv1.0.5 | 2026-08-03T08:02:36.190Z | auto\n\n**Major update introducing a local visualizer and stricter agent gating process.**\n\n- Added a new mandatory Agent visualizer gate: Agents must verify the environment, start the local Web visualizer service, and confirm browser access before processing subtitle tasks.\n- Introduced a Node.js/TypeScript-powered visualizer web app with task history stored locally, providing a display-only interface for translation progress and validation.\n- Updated CLI and SKILL documentation to clearly separate visualizer workflow from direct CLI usage, outlining new browser opening rules and service health checks.\n- Replaced and reorganized project files: new TypeScript sources, build tools, configs, and Web resources added; previous legacy assets, test fixtures, and scripts removed or consolidated.\n- Changed the report location and clarified output behaviors: batch composition now writes the report adjacent to the output subtitle file.\n- Enforced that all Agent workflows must pass the visualizer gate before creating subtitle translation tasks; direct CLI usage remains available for deterministic workflows outside Agent sessions.\n\nv1.0.4 | 2026-08-01T16:22:22.807Z | auto\n\nInitial public release of agent-subtitle-translator.\n\n- Added deterministic subtitle file translation for SRT, WebVTT/VTT, and ASS formats with strict local parsing and mapping.\n- Implemented batch-based translation workflow with robust response validation, error handling, and timeline preservation.\n- Supported karaoke degradation detection, inline semantic style preservation, and safe output composition.\n- Included scripts for file preparation, batch processing, response validation, and final subtitle composition.\n- Provided safety features to protect structure, data integrity, and prevent accidental overwrites.\n- Included tests and sample subtitle fixtures for validation.\n\nv1.0.3 | 2026-08-01T16:01:31.612Z | auto\n\n- Added AGENTS.md documenting agent integration details.\n- Updated configuration in agents/openai.yaml.\n- Improved and updated README files.\n- Removed legacy scripts, assets, and all test/fixtures directories.\n- Streamlined repository by deleting deprecated files and folders.\n\nv1.0.2 | 2026-08-01T03:48:41.525Z | auto\n\n- Added comprehensive documentation in multiple languages and improved workflow instructions.\n- Introduced initial test fixtures for SRT, VTT, and ASS subtitle formats.\n- Enhanced project organization with new scripts, agents, assets, and GitHub Actions workflow.\n- Removed outdated skill-card documentation.\n- No changes to subtitle translation algorithms or core workflow logic.\n\nv1.0.1 | 2026-07-17T12:42:50.980Z | auto\n\n- Updated documentation in English and Chinese README files for improved clarity and guidance.\n- Removed the obsolete skill-card.md file.\n- No functional changes to code or workflow; documentation only.\n\nv1.0.0 | 2026-07-16T08:22:34.545Z | auto\n\n- Initial release of agent-subtitle-translator.\n- Deterministic local subtitle parsing with timeline preservation and strict batch mapping.\n- Supports SRT, WebVTT/VTT (normalized to SRT), and ASS subtitle files.\n- Preserves ASS sections, event fields, inline semantic styling, and hard line breaks; karaoke entries are tracked for degradation.\n- Comprehensive validation workflow for LLM subtitle translations, with safe output composition and detailed reporting.\n- Ensures strict safety: exact file processing, prevents silent data loss, and prohibits unsafe overwrites.\n\nArchive index:\n\nArchive v1.0.9: 42 files, 624243 bytes\n\nFiles: .clawhubignore (186b), .github (0b), .github/workflows (0b), .github/workflows/clawhub-publish.yml (699b), .gitignore (30b), .impeccable.md (1301b), agents (0b), AGENTS.md (64b), agents/openai.yaml (367b), assets (0b), assets/icon-large.png (271934b), assets/icon-small.png (271934b), package-lock.json (1460b), package.json (606b), README.md (12040b), README.zh-CN.md (11719b), requirements.txt (27b), scripts (0b), scripts/subtitle_tool.py (43893b), skill-card.md (2496b), SKILL.md (12834b), src (0b), src/agent-bridge.ts (6312b), src/common.ts (4164b), src/python-cli.ts (4121b), src/server.ts (10566b), src/task-manager.ts (25862b), tests (0b), tests/fixtures (0b), tests/fixtures/basic.srt (91b), tests/fixtures/basic.vtt (101b), tests/fixtures/karaoke.ass (626b), tests/fixtures/styled.ass (969b), tests/test_subtitle_tool.py (18431b), tests/visualizer.test.ts (24794b), tsconfig.json (455b), web (0b), web/app.ts (32501b), web/icons.ts (6681b), web/index.html (8668b), web/styles.css (33572b), _meta.json (144b)\n\nFile v1.0.9:SKILL.md\n\n---\nname: agent-subtitle-translator\ndescription: Translate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer. Use when an agent needs to translate SRT, WebVTT/VTT, or ASS subtitles; preserve ASS sections, event fields, inline semantic styling, or hard line breaks; normalize VTT to SRT; detect karaoke degradation; or validate an LLM subtitle translation before writing it.\nmetadata:\n  author: \"Lumen\"\n  openclaw:\n    requires:\n      bins:\n        - node\n        - npm\n        - python3\n    homepage: \"https://github.com/Lumen01/agent-subtitle-translator\"\n---\n\n# Agent Subtitle Translator\n\nTranslate only subtitle text with an available translation model. Delegate decoding, parsing, batching, marker validation, timeline mapping, and output writing to `scripts/subtitle_tool.py`. Never send timestamps or original ASS override tags to the model.\n\n## Prerequisite\n\nRun commands from this skill directory. The script uses only the standard library for UTF inputs; legacy encodings require `charset-normalizer`:\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help\n```\n\nDo not request or configure an external LLM API key for the script. Use the translation capability already available to the executing agent.\n\n### Runtime boundary\n\n- The core workflow reads the one subtitle file selected by the user, writes its work package and final output, and never contacts a translation provider.\n- The optional visualizer is a local display service. It binds only to `127.0.0.1`, stores task history under `~/.agent-subtitle-translator/visualizer`, and accepts bridge requests only through that local service.\n- The bridge does not accept remote URLs, the service never launches a browser subprocess, and visualizer output is confined to the current task's private `output` directory.\n- The Agent or user opens the visualizer URL explicitly. The visualizer is display-only and does not receive subtitle uploads or translation controls from the browser.\n\n## Workflow\n\n### Optional Agent visualizer workflow\n\nThe deterministic CLI workflow can run without a Web service. When the Agent or user chooses to observe progress in the visualizer, complete these steps before using the bridge:\n\n1. **Check the environment.** Run from the Skill directory. Install or verify the Python dependency from `requirements.txt`, confirm Python can run `scripts/subtitle_tool.py --help`, confirm Node.js satisfies the package requirement (Node 20 or newer), install Node dependencies once with `npm install`, and run `npm run build` successfully.\n2. **Check the Web service.** Request `http://127.0.0.1:4317/api/health`. Reuse the service only when the response is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict, then record the printed URL.\n3. **Open the Web page when requested.** Navigate the selected browser to the printed local URL and report whether it loaded. Browser access is an observation step and does not grant the page task-input or translation permissions.\n4. **Run the visualizer workflow.** Run `identify`, then create the task, start batches, submit and validate responses, and compose through `visualizer:bridge`. Keep reporting each meaningful operation in the Agent response.\n\nThe commands in the sections below describe the direct deterministic CLI workflow and the safety rules implemented by the bridge. During an Agent visualizer run, use the equivalent bridge commands after the local service is healthy. Do not compose the same task and output path through both workflows.\n\n### 1. Prepare one file\n\nRequire a target BCP 47 tag. Accept an optional source tag; omit it to let the translation model detect the source language.\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n```\n\nUse `--work-dir` to choose the package location. The command otherwise creates a hidden sibling directory. Do not use `--overwrite-work` unless replacing that package is intentional.\n\nInspect the JSON report. Stop on decoding, empty-body, invalid-timeline, or structural errors. Note any out-of-order input and ASS karaoke IDs. Preparation creates:\n\n- `manifest.json`: local structure, mapping, and validation facts; do not send it to the model.\n- `batches/batch-NNNN.txt`: ready-to-send prompts containing stable IDs and text, never timelines.\n- `validated/`: destination for verified batch results.\n\nEach batch contains at most 32 entries. Do not increase that ceiling. Dispatch batches serially or concurrently using the agent's available scheduling; this skill imposes no concurrency limit.\n\n### 2. Translate batches\n\nSend each complete `batch-NNNN.txt` prompt to the translation model without rewriting its fixed instructions. Save the raw response as UTF-8 text.\n\nDo not promise cross-batch consistency for names or terminology. The prompt supplies only the local batch context.\n\n### 3. Validate every response\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n```\n\nOn any count, ID, order, wrapper, hard-break, fixed-structure, or style-marker error, resend that batch with the original prompt and the validator error as a correction request. Never fill a missing translation from a neighboring entry.\n\nIf the retried response still has a count, ID, wrapper, `BR`, or `F` mismatch, stop the entire job. Reliable timeline mapping is impossible.\n\nIf only ASS `S` style markers remain invalid after a retry, validate with `--allow-style-fallback`. This removes inline style markers only for the affected entries and records their IDs. Do not use this option before a retry.\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001-retry.txt \\\n  --allow-style-fallback\n```\n\nUse `--overwrite` only to replace the prior validated JSON for that batch.\n\n### 4. Compose after all batches validate\n\n```bash\npython3 scripts/subtitle_tool.py compose --manifest /path/work/manifest.json\n```\n\nThe script merges validated data by stable subtitle ID, independent of completion order. It refuses missing, duplicate, or extra IDs and refuses to overwrite output by default. If the output already exists, choose a new `--output` path or pass `--overwrite` only when replacing that exact output is intentional.\n\nThe final report is written next to the subtitle as `<output-path>.report.json`, not at the work directory root. For example, `SPS.ja.srt` has the report `SPS.ja.srt.report.json`.\n\nRead the final report and tell the user:\n\n- output path, format, encoding, entry count, and time range;\n- count and IDs of karaoke degradations;\n- count and IDs of inline-style fallbacks.\n\n## Local visualizer workflow\n\nThe local visualizer is optional. Direct CLI-only use remains available when an Agent is invoking the deterministic tool without a visualizer session. The Web interface is display-only: it never accepts subtitle files, target languages, or translation controls. The Agent remains the only task input and execution surface.\n\nThe visualizer listens on `127.0.0.1` by default and stores task history outside the repository under `~/.agent-subtitle-translator/visualizer`.\n\nInstall the service once, then check for a reusable instance before starting it:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n# Run this only when the health check fails:\n# npm run visualizer:start\n```\n\nReuse the existing instance when `/api/health` returns HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when the visualizer is requested and skip `npm run visualizer:start`. If the health request fails or reports an incompatible version, start the service only after addressing the occupied port. If the port responds with another service, report the conflict and use a different port or resolve it deliberately; do not terminate an unknown process automatically.\n\nThe visualizer does not call a translation model and keeps the deterministic safety contract; all task inputs and real translation stages come from the Agent through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send the complete batches/batch-0001.txt prompt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to overwrite an existing subtitle or report by default. Use a new `--output` path for a separate result, or pass `--overwrite` only when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report path returned by bridge composition is `<output-path>.report.json`, alongside the generated subtitle.\n\nIf validation fails, report the failure in the Web task, retry with the original prompt and the validator error, then submit the retried response. Use `retry-batch --task TASK_ID --batch 1` before sending the retry. Use `--allow-style-fallback` only after the required retry and only when the remaining problem is an ASS `S` marker mismatch.\n\nRun identify at the beginning of the visualizer session. The session line shows the reported Agent, each task card shows the model recorded for that task, and the program metadata line separately shows the shared program and Skill version read from package.json. Pass the complete model identifier in `--model` whenever the Agent knows it, such as `GPT-5.6 Luna Hight`; pass `--model-version`, `--model-series`, and `--reasoning-strength` when those fields exist, such as `GPT` + `5.6` + `Sol` + `high`. Older or other models may omit any optional field, and the Web page omits missing fields. Never invent a version, series, or reasoning value that the Agent cannot verify. Keep reporting the same progress in the Agent response after every meaningful bridge operation.\n\nThe Web interface supports multiple Agent-created tasks at once. The left queue shows each task and its overall status; the selected task shows batch progress, per-task and per-batch duration, visible subtitle text, validation/retry/degradation warnings, and the live event stream. The interface never displays the manifest, accepts task input, or sends timestamps and raw ASS override tags to the model.\n\n### Agent-side progress output\n\nThe Agent must continue reporting progress in its own response while the Web page is open. Web events do not replace Agent output. At minimum, report:\n\n- the visualizer URL and whether it was opened in the selected browser;\n- task creation and subtitle preparation, including entry and batch counts;\n- each batch start, validation result, retry, and degradation;\n- final composition, output path, format, duration, and any warnings.\n\nKeep these updates concise and synchronized with the bridge calls so the user can follow the same run in the Agent and in the Web page.\n\n## Format behavior\n\n- Write SRT input as UTF-8-BOM SRT.\n- Normalize VTT input locally and write UTF-8-BOM SRT.\n- Keep ASS as UTF-8-BOM ASS. Preserve non-dialogue sections, styles, comments, pure drawings, event order, timestamps, Layer, Style, Name, margins, Effect, and other event fields.\n- Translate only visible ASS Dialogue text. Convert inline style scopes to paired neutral markers and `\\N`/`\\n` to movable `BR` markers, then restore validated structure.\n- Degrade karaoke entries containing `\\k`, `\\K`, `\\kf`, or `\\ko` individually to static text. Preserve the base Style/event fields and safe whole-line positioning while removing syllable timing and inapplicable animation.\n- Name default output `<stem>.<normalized-BCP47>.<ext>`, such as `movie.zh-Hans.srt` or `movie.pt-BR.ass`.\n\n## Safety invariants\n\n- Process exactly one input file per run.\n- Never expose `manifest.json`, timestamps, or raw ASS override tags to the translation model.\n- Never infer mapping from proximity, text similarity, or character positions.\n- Never silently discard marker failures or degradations.\n- Never overwrite a work package, validated result, subtitle, or report without the matching explicit overwrite flag.\n\nFile v1.0.9:README.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator logo\" width=\"180\">\n</p>\n\n[简体中文](README.zh-CN.md)\n\nTranslate one SRT, VTT, or ASS subtitle file with local timeline handling, strict ID validation, and safe ASS structure preservation.\n\nThis repository is a Skill first. The bundled CLI performs deterministic decoding, parsing, batching, validation, and composition; the executing Agent uses its available translation model, so the CLI needs no external LLM API key.\n\n> ⭐ If this Skill helps you, please [star the repository](https://github.com/Lumen01/agent-subtitle-translator). It helps more people discover the project and supports continued improvements.\n\n## Install the Skill\n\n### Ask an Agent to install it\n\nCopy this prompt to an Agent with terminal access:\n\n```text\nInstall this Skill following the instructions at https://github.com/Lumen01/agent-subtitle-translator and confirm that the current Agent can use it. If it conflicts with an existing installation, let me know before proceeding.\n```\n\n### Install manually\n\n#### Shared by multiple Agents\n\nInstall one shared copy for Codex, Claude, OpenCode, and other compatible runtimes:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\nPoint each runtime at the shared copy if it requires its own skills directory:\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\nInspect each destination first; do not replace an existing file, directory, or link blindly.\n\n#### One runtime only\n\nClone directly into that runtime's documented skills directory. For example:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\nThe installed skill root must contain a discoverable `SKILL.md`.\n\n## Prompt an Agent to use it\n\nName the skill, one input file, and the required target language. The source language is optional.\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/movie.en.srt to Simplified Chinese (zh-Hans). Keep the original timing, do not overwrite existing output, and report any degradation.\n```\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/signs.ass from English to Brazilian Portuguese (pt-BR). Preserve ASS styles and event metadata wherever safe.\n```\n\nThe Agent prepares batches of at most 32 entries, translates them using its available model, retries invalid batch structures, validates stable IDs and markers, and composes only after every batch maps safely. The Skill does not impose a concurrency cap; completed batches are merged by stable ID, not completion order.\n\n## Supported formats and output\n\n| Input | Output | Behavior |\n| --- | --- | --- |\n| SRT | SRT | Preserve timing; normalize indices and timeline order. |\n| VTT/WebVTT | SRT | Convert locally to normalized SRT. |\n| ASS | ASS | Preserve the document and event structure; replace only visible Dialogue text. |\n\nDefault output is `<stem>.<normalized-BCP47>.<ext>`, for example `movie.zh-Hans.srt` or `movie.pt-BR.ass`. Existing work directories, validated responses, subtitle outputs, and reports are not overwritten unless the corresponding explicit overwrite flag is used. SRT and ASS outputs use UTF-8 BOM.\n\nThe CLI recognizes UTF BOMs and UTF-8 directly. It uses `charset-normalizer` for common legacy encodings and stops when the result is too ambiguous to map safely. Preparation reports entry counts, time range, ordering, empty text, format conversion, and ASS-specific preservation facts.\n\n## ASS style preservation and karaoke degradation\n\nOriginal ASS tags never go to the translation model. Inline style ranges become paired neutral markers such as `⟦S1⟧...⟦/S1⟧`; the markers can move with their meaning in the target language. Hard line breaks become unique movable `BR` markers. After translation, the CLI validates marker count, identity, closure, and nesting before restoring the original tags.\n\nFor example, this source:\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\ncan safely become:\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\nIf an inline-style response still cannot be restored after a retry, the Agent may explicitly downgrade only that subtitle entry to static text and must report its ID. Count, ID, wrapper, hard-break, or fixed-structure mismatches remain fatal; the Skill never borrows adjacent translations or guesses character positions.\n\nEntries containing `\\k`, `\\K`, `\\kf`, or `\\ko` karaoke timing are intentionally downgraded one entry at a time. The output keeps the event timeline, base Style, fields, and safe whole-line positioning, but removes syllable timing and no-longer-applicable character animation. This is reported as a degradation, not a translation failure. Other ordinary ASS entries in the same file retain their supported styling.\n\n## Agent execution order\n\nWhen an Agent uses this Skill, the deterministic CLI workflow may run directly. Use the following local visualizer steps only when the Agent or user wants live progress:\n\n1. Check the environment from the Skill directory: install or verify the Python dependency from `requirements.txt`, verify Python can run `scripts/subtitle_tool.py --help`, verify Node.js is 20 or newer, install Node dependencies with `npm install` when needed, and run `npm run build` successfully.\n2. Check `http://127.0.0.1:4317/api/health`. Reuse the service only when it is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict.\n3. When visual progress is requested, open the printed loopback URL in the selected browser and report whether it loaded.\n4. Run `visualizer:bridge -- identify`, then create the task, translate batches, validate responses, and compose through bridge.\n\nThe CLI block below is the deterministic core reference. Do not mix CLI composition with bridge composition for the same task and output path.\n\n## Deterministic CLI reference\n\nThe Agent normally runs these commands from the installed skill directory:\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\nSee `python3 scripts/subtitle_tool.py --help` and each subcommand's `--help` for collision and retry flags. The generated batch prompts contain text and stable IDs but no timelines or raw ASS override tags.\nThe final composition report is written alongside the subtitle as `<output-path>.report.json`; for example, `SPS.ja.srt` produces `SPS.ja.srt.report.json`. If the output already exists, choose a new path or pass the explicit overwrite flag only when replacement is intentional.\n\n## Local translation visualizer\n\nThis Skill includes an optional local, display-only Web workspace. It presents the Agent-created task queue on the left and the selected task's batches, validation, retries, degradations, timing, subtitle preview, and event stream on the right. Subtitle files, target languages, and translation controls remain in the Agent; the Web page does not accept task input. The original Python CLI remains the deterministic processing core.\n\nFor an Agent visualizer run, use the bridge as the single task execution path. The direct CLI commands above remain available for CLI-only use; do not compose the same task and output path through both paths.\n\nRun or reuse the local service from the Skill directory:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\nReuse the instance when the health response is HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when visual progress is requested and skip starting another process. If the request fails or reports an incompatible version, address the occupied port before starting the current release. If the port is occupied by another service, report the conflict and choose a different port or resolve it deliberately. The service binds only to `127.0.0.1` and persists local task history under `~/.agent-subtitle-translator/visualizer`. The Agent opens the printed URL explicitly when needed. The Agent continues reporting the same task progress in its own response. The visualizer does not call a translation provider or require an API key. The Agent sends real execution updates through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send batches/batch-0001.txt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to replace an existing subtitle or report by default. The bridge accepts `--output` only as a filename inside the current task's private output directory. Use a fresh filename for a separate result, or add `--overwrite` when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report is stored beside the output as `<output-path>.report.json`.\n\nThe Web page displays the reported Agent in the session line, records the reported model on each task card, and separately displays the shared program and Skill version from package.json. Pass the complete model identifier in `--model` whenever it is known, such as `GPT-5.6 Luna Hight`. `--model-version`, `--model-series`, and `--reasoning-strength` are optional, so older or other models can omit them and the Web page leaves those fields out. Do not invent values that the Agent cannot verify. Run identify at the beginning of each visualizer session. The Web page only displays tasks created and controlled by the Agent. Direct CLI-only workflows can run without the Web service; when the visualizer is active, keep task creation, validation, and composition on the bridge path.\n\n## Automatic ClawHub Publishing\n\nThe GitHub Actions workflow at `.github/workflows/clawhub-publish.yml` publishes\nthis skill whenever relevant files are pushed to `main`. It uses ClawHub's\nofficial reusable workflow, which skips unchanged content and automatically\ncreates the next patch version when the skill changed.\n\nBefore the first run, add a repository Actions secret named `CLAWHUB_TOKEN`:\n\n1. Create a ClawHub API token from the ClawHub web UI while signed in as the\n   owner of this skill.\n2. In GitHub, open **Settings → Secrets and variables → Actions** for this\n   repository and create the `CLAWHUB_TOKEN` secret with that value.\n3. Run **Publish Subtitle Translator to ClawHub** once from the Actions tab, or\n   push a relevant change to `main`.\n\nThe token is only passed to the publishing workflow and must never be committed\nto this repository.\n\n## Develop and test\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.9:_meta.json\n\n{\n  \"ownerId\": \"kn78ge2mfb4vyz0qn9xpnne8v58a732j\",\n  \"slug\": \"agent-subtitle-translator\",\n  \"version\": \"1.0.9\",\n  \"publishedAt\": 1788518538665\n}\n\nFile v1.0.9:.impeccable.md\n\n## Design Context\n\n### Users\n\n普通用户通过 Agent 同时发起一个或多个字幕翻译任务。他们希望不用理解命令行、批次文件或内部实现，也能看到每个任务当前进展、翻译耗时、校验结果、重试原因、降级提示和最终输出。\n\n### Brand Personality\n\n清晰、可靠、从容。界面要让用户始终知道系统正在做什么、已经完成什么，以及是否需要关注某个问题。\n\n### Aesthetic Direction\n\n面向普通用户的翻译工作台：左侧是可切换的任务队列，右侧是选中任务的过程详情。提供深色与浅色主题切换，使用明确的状态色、时间信息和事件流形成可读的过程叙事。动效用于表达任务状态变化、批次推进和结果完成，按当前需求保持开启，不提供减弱动效设置。\n\n### Design Principles\n\n1. 先让用户看懂任务全局，再逐步展开批次和单条字幕细节。\n2. 每个状态都给出可读的中文说明、时间和下一步结果。\n3. 错误、重试和降级需要显眼且可追溯，不能被装饰性视觉弱化。\n4. 多任务并行时保持左侧列表稳定，右侧详情切换不打断后台任务。\n5. 视觉风格应具备工具感和秩序感，同时保持普通用户可理解的语言与操作。\n\nFile v1.0.9:AGENTS.md\n\n# Repository Instructions\n\n- 在 `dev` 分支中研发迭代。\n\nFile v1.0.9:README.zh-CN.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator Logo\" width=\"180\">\n</p>\n\n[English](README.md)\n\n安全翻译单个 SRT、VTT 或 ASS 字幕文件：时间轴在本地处理，字幕 ID 严格校验，并尽可能完整保留 ASS 结构。\n\n本仓库首先是一个 Skill。内置 CLI 负责确定性的解码、解析、分批、校验和合成；执行 Agent 使用自身可用的翻译模型，因此 CLI 不需要外部 LLM API Key。\n\n> ⭐ 如果这个 Skill 对你有帮助，请为[本仓库点一个 Star](https://github.com/Lumen01/agent-subtitle-translator)。你的支持能让更多人发现这个项目，也会鼓励项目持续改进。\n\n## 安装 Skill\n\n### 让 Agent 执行安装\n\n将下面这段 Prompt 交给有终端权限的 Agent：\n\n```text\n请按照 https://github.com/Lumen01/agent-subtitle-translator 的安装说明安装此 Skill，并确认当前 Agent 能够使用。若与现有安装冲突，请先告知我。\n```\n\n### 手工安装\n\n#### 多 Agent 共用\n\n为 Codex、Claude、OpenCode 等兼容运行时安装一份共享副本：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\n如果运行时要求使用自己的 Skill 目录，将其指向共享副本：\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\n执行前先检查每个目标位置；不要盲目替换已有文件、目录或链接。\n\n#### 仅供一个运行时使用\n\n直接克隆到该运行时文档约定的 Skill 目录。例如：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\n安装后的 Skill 根目录必须包含可发现的 `SKILL.md`。\n\n## 提示 Agent 使用\n\n在 Prompt 中写明 Skill、一个输入文件和必填的目标语言；源语言可省略。\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/movie.en.srt 翻译为简体中文（zh-Hans）。保留原时间轴，不覆盖已有输出，并报告所有降级项。\n```\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/signs.ass 从英语翻译为巴西葡萄牙语（pt-BR）。尽可能保留 ASS 样式和事件元数据。\n```\n\nAgent 会以每批最多 32 条字幕准备任务，使用自身可用模型翻译，重试结构无效的批次，严格校验稳定 ID 和标记，并只在全部批次都能安全映射后合成。Skill 不设置并发上限；批次结果按稳定 ID 合并，不按完成先后合并。\n\n## 支持格式与输出\n\n| 输入 | 输出 | 行为 |\n| --- | --- | --- |\n| SRT | SRT | 保留时间轴；规范化编号和时间顺序。 |\n| VTT/WebVTT | SRT | 在本地转换为规范化 SRT。 |\n| ASS | ASS | 保留文档和事件结构，只替换 Dialogue 的可见正文。 |\n\n默认输出名为 `<stem>.<规范化-BCP47>.<ext>`，例如 `movie.zh-Hans.srt` 或 `movie.pt-BR.ass`。除非使用对应的显式覆盖参数，否则不会覆盖已有工作目录、已校验响应、字幕输出或报告。SRT 与 ASS 输出使用 UTF-8 BOM。\n\nCLI 可直接识别 UTF BOM 和 UTF-8，并通过 `charset-normalizer` 检测常见旧编码；检测结果过于含糊时会停止，以免错误映射。准备报告会列出条目数、时间范围、排序、空正文、格式转换和 ASS 专属保留信息。\n\n## ASS 样式保持与卡拉 OK 降级\n\n原始 ASS 标签不会提交给翻译模型。行内样式范围会转换为 `⟦S1⟧...⟦/S1⟧` 这类成对中性标记，标记可随对应语义在目标语言中移动。硬换行会转换为唯一、可移动的 `BR` 标记。翻译完成后，CLI 会校验标记数量、身份、闭合和嵌套，再恢复原标签。\n\n例如，以下原文：\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\n可以安全得到：\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\n如果重试后仍无法恢复某条字幕的行内样式，Agent 可显式地只把该条降级为静态文本，并必须报告其 ID。条数、ID、外层结构、硬换行或固定结构不匹配仍是致命错误；Skill 绝不会借用相邻译文，也不会根据字符位置猜测样式。\n\n含 `\\k`、`\\K`、`\\kf` 或 `\\ko` 卡拉 OK 计时的条目会按条明确降级。输出保留事件时间轴、基础 Style、其他字段和安全的整行位置，但移除逐音节计时和不再适用的字符动画。该情况会作为降级报告，而不是翻译失败。同一文件中的其他普通 ASS 条目仍保留受支持的样式。\n\n## Agent 执行顺序\n\nAgent 使用本 Skill 时，可以直接运行确定性 CLI。需要观察实时进度时，再按以下步骤启用本地 visualizer：\n\n1. 在 Skill 目录检查环境：安装或确认 `requirements.txt` 中的 Python 依赖，确认 Python 能运行 `scripts/subtitle_tool.py --help`，确认 Node.js 为 20 或更高版本；需要时运行 `npm install`，并确认 `npm run build` 成功。\n2. 检查 `http://127.0.0.1:4317/api/health`。只有健康状态正确、服务标识为 `subtitle-visualizer` 且 Skill 版本兼容时才复用；否则先处理端口占用，再启动服务。\n3. 需要观察实时进度时，在指定浏览器中打开服务打印的本机 URL，并报告页面是否加载成功。\n4. 运行 `visualizer:bridge -- identify`，然后创建任务、翻译批次、校验响应，并通过 bridge compose。\n\n下面的 CLI 代码块是确定性核心能力参考。同一任务和输出路径不要混用 CLI compose 与 bridge compose。\n\n## 确定性 CLI 参考\n\nAgent 通常在已安装的 Skill 目录运行以下命令：\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\n运行 `python3 scripts/subtitle_tool.py --help` 及各子命令的 `--help` 可查看碰撞与重试参数。生成的批次 Prompt 只包含正文和稳定 ID，不包含时间轴或原始 ASS override 标签。最终报告与字幕位于同一目录，路径为 `<output-path>.report.json`；例如 `SPS.ja.srt` 对应 `SPS.ja.srt.report.json`。如果输出已存在，请选择新路径；只有明确要替换原结果时才使用显式覆盖参数。\n\n## 本地翻译过程可视化\n\n本 Skill 提供一个可选的、只负责展示的本地 Web 工作台，适合普通用户同时观察多个由 Agent 创建的字幕翻译任务。左侧显示任务队列，点击任务后，右侧会展示批次进度、校验、重试、降级、翻译耗时、字幕明细和实时事件流。字幕文件、目标语言和翻译控制全部在 Agent 中完成，Web 页面不接受任务输入。原有 Python CLI 继续负责确定性的字幕处理核心。\n\nAgent 使用 visualizer 时，bridge 是唯一的任务执行入口。上面的 CLI 命令仍可用于纯 CLI 调用；同一任务和输出路径不要先后通过两套入口重复 compose。\n\n在 Skill 目录启动或复用本地服务：\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\n当健康接口返回 HTTP 200，且 JSON 中 `status` 为 `\"ok\"`、`service` 为 `\"subtitle-visualizer\"`，版本与当前 Skill 兼容（本版为 `1.1.1`）时，复用现有实例并仅在需要观察实时进度时打开其 URL，跳过第二次启动。请求失败或版本不兼容时，先处理占用端口，再启动当前版本。如果端口被其他服务占用，应报告冲突并选择其他端口或有意处理，不要自动终止未知进程。服务只监听 `127.0.0.1`，任务历史保存在仓库外的 `~/.agent-subtitle-translator/visualizer`。Agent 需要观察进度时显式打开打印出的本机 URL。Agent 端同时继续输出任务创建、字幕准备、批次处理、校验、重试、降级和最终生成状态。服务不会调用翻译服务，也不要求配置 API Key；Agent 通过桥接命令上报真实执行过程：\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent 名称\" \\\n  --model \"模型名称\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# 将 batches/batch-0001.txt 完整发送给当前可用的翻译模型。\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nbridge 默认拒绝覆盖已有字幕或报告。`--output` 只能指定当前任务私有 output 目录中的文件名。需要生成另一份结果时，请传入新的文件名；明确替换同一结果时，才追加 `--overwrite`：\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\n报告位于输出字幕旁边，路径为 `<output-path>.report.json`。\n\n如果校验失败，先在 Web 任务中记录失败，再使用原始 Prompt 和校验错误重试；发送重试前运行 `retry-batch --task TASK_ID --batch 1`。只有完成规定重试且剩余问题为 ASS `S` 样式标记不匹配时，才可以使用 `--allow-style-fallback`。\n\n运行 identify 后，Web 页面会在会话行显示 Agent，并在每个任务卡片内显示该任务记录的翻译模型；下方程序元数据显示共用的程序与 Skill 版本，该版本统一从 package.json 读取。Agent 知道完整模型标识时，应将它作为 `--model` 传入，例如 `GPT-5.6 Luna Hight`；也可以通过 `--model-version`、`--model-series` 和 `--reasoning-strength` 传入 `GPT`、`5.6`、`Sol`、`high` 这类结构化信息。旧模型或其他模型缺少可选字段时，Web 页面会自动省略对应字段；Agent 无法确认的值不应自行补全。建议在每次可视化会话开始时先执行一次 identify。Web 页面只展示 Agent 创建和控制的任务。纯 CLI 流程可以不启动 Web 服务；visualizer 启用后，任务创建、校验和 compose 都应保持在 bridge 入口。\n\n## 自动发布到 ClawHub\n\n`.github/workflows/clawhub-publish.yml` 会在相关文件推送到 `main` 时自动发布本技能。它使用 ClawHub 官方可复用工作流：未变更内容会被跳过；技能有变更时会自动发布下一个 patch 版本。\n\n首次运行前，请添加名为 `CLAWHUB_TOKEN` 的仓库 Actions Secret：\n\n1. 以该技能所有者身份登录 ClawHub，在网页中创建 ClawHub API token。\n2. 在 GitHub 仓库打开 **Settings → Secrets and variables → Actions**，新建名为 `CLAWHUB_TOKEN` 的 Secret，并填入该 token。\n3. 在 Actions 页面手动运行一次 **Publish Subtitle Translator to ClawHub**，或向 `main` 推送相关改动。\n\n该 token 只会传给发布工作流，绝不能提交到仓库。\n\n## 开发与测试\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.9:skill-card.md\n\n## Description:\n\nTranslates one SRT, VTT, or ASS subtitle file at a time while preserving timelines, validating batch mappings, and optionally showing local loopback visual progress.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[lumen01](https://clawhub.ai/user/lumen01)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, agents, and subtitle editors use this skill to translate individual subtitle files while preserving timing and supported ASS structure. It supports agent-led workflows that need deterministic preparation, batch validation, safe composition, and optional local progress visualization.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The optional local visualizer exposes unauthenticated task APIs that can read, persist, disclose, and change subtitle task data on the same machine.\n\nMitigation: Prefer the CLI-only workflow unless visual progress is needed; run the visualizer only on a trusted single-user machine and stop it when finished.\n\nRisk: Visualizer task history may contain subtitle contents and task details under ~/.agent-subtitle-translator/visualizer.\n\nMitigation: Treat the visualizer history directory as sensitive local data and add cleanup controls before broader release.\n\nRisk: The safer release guidance identifies missing per-session API tokens, Host/Origin validation, tighter file-path scoping, and pinned Python dependencies.\n\nMitigation: Add those controls before relying on the visualizer for higher-trust or shared-machine workflows.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/lumen01/skills/agent-subtitle-translator)\n- [Server-resolved source repository](https://github.com/Lumen01/agent-subtitle-translator)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance, files]\n\n**Output Format:** [Translated subtitle files with companion JSON reports, plus Markdown guidance and shell commands for agent execution]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Processes one subtitle file per run and composes output only after batch validation succeeds.]\n\n## Skill Version(s):\n\n1.0.9 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.9:package-lock.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"agent-subtitle-translator\",\n      \"version\": \"1.1.1\",\n      \"devDependencies\": {\n        \"@types/node\": \"^22.15.0\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.20.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz\",\n      \"integrity\": \"sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"undici-types\": \"~6.21.0\"\n      }\n    },\n    \"node_modules/typescript\": {\n      \"version\": \"5.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n      \"dev\": true,\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=14.17\"\n      }\n    },\n    \"node_modules/undici-types\": {\n      \"version\": \"6.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    }\n  }\n}\n\nFile v1.0.9:package.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"private\": true,\n  \"description\": \"Local subtitle translation workflow with an optional loopback-only visualizer for Agent runs.\",\n  \"type\": \"module\",\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc -p tsconfig.json\",\n    \"test\": \"npm run build && node --test dist/tests/*.test.js\",\n    \"visualizer:start\": \"npm run build && node dist/src/server.js\",\n    \"visualizer:bridge\": \"npm run build && node dist/src/agent-bridge.js\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.15.0\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n\nFile v1.0.9:tsconfig.json\n\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"rootDir\": \".\",\n    \"outDir\": \"dist\",\n    \"strict\": true,\n    \"noImplicitOverride\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noEmitOnError\": true,\n    \"sourceMap\": true,\n    \"skipLibCheck\": true,\n    \"lib\": [\"ES2022\", \"DOM\"]\n  },\n  \"include\": [\"src/**/*.ts\", \"web/**/*.ts\", \"tests/**/*.ts\"],\n  \"exclude\": [\"dist\", \"node_modules\"]\n}\n\nFile v1.0.9:.github/workflows/clawhub-publish.yml\n\nname: Publish Subtitle Translator to ClawHub\n\non:\n  push:\n    branches: [main]\n    paths:\n      - SKILL.md\n      - scripts/**\n      - src/**\n      - web/**\n      - requirements.txt\n      - package.json\n      - package-lock.json\n      - tsconfig.json\n      - agents/**\n      - assets/**\n      - README.md\n      - README.zh-CN.md\n      - .clawhubignore\n      - .github/workflows/clawhub-publish.yml\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  id-token: write\n\njobs:\n  publish:\n    uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v0.23.1\n    with:\n      skill_path: .\n      dry_run: false\n      ref: ${{ github.sha }}\n    secrets:\n      clawhub_token: ${{ secrets.CLAWHUB_TOKEN }}\n\nFile v1.0.9:agents/openai.yaml\n\ninterface:\n  display_name: \"Agent Subtitle Translator\"\n  short_description: \"Translate SRT, VTT, and ASS subtitles safely\"\n  icon_small: \"./assets/icon-small.png\"\n  icon_large: \"./assets/icon-large.png\"\n  brand_color: \"#FF9940\"\n  default_prompt: \"Use $agent-subtitle-translator to translate one subtitle file while preserving its timing and supported ASS structure.\"\n\nArchive v1.0.8: 23 files, 77134 bytes\n\nFiles: AGENTS.md (64b), agents/openai.yaml (367b), package-lock.json (1460b), package.json (606b), README.md (12040b), README.zh-CN.md (11719b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2114b), SKILL.md (12834b), src/agent-bridge.ts (6312b), src/common.ts (4164b), src/python-cli.ts (4121b), src/server.ts (10566b), src/task-manager.ts (25862b), tests/test_subtitle_tool.py (18431b), tests/visualizer.test.ts (24794b), tsconfig.json (455b), web/app.ts (32501b), web/icons.ts (6681b), web/index.html (8668b), web/styles.css (33572b), _meta.json (144b)\n\nFile v1.0.8:SKILL.md\n\n---\nname: agent-subtitle-translator\ndescription: Translate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer. Use when an agent needs to translate SRT, WebVTT/VTT, or ASS subtitles; preserve ASS sections, event fields, inline semantic styling, or hard line breaks; normalize VTT to SRT; detect karaoke degradation; or validate an LLM subtitle translation before writing it.\nmetadata:\n  author: \"Lumen\"\n  openclaw:\n    requires:\n      bins:\n        - node\n        - npm\n        - python3\n    homepage: \"https://github.com/Lumen01/agent-subtitle-translator\"\n---\n\n# Agent Subtitle Translator\n\nTranslate only subtitle text with an available translation model. Delegate decoding, parsing, batching, marker validation, timeline mapping, and output writing to `scripts/subtitle_tool.py`. Never send timestamps or original ASS override tags to the model.\n\n## Prerequisite\n\nRun commands from this skill directory. The script uses only the standard library for UTF inputs; legacy encodings require `charset-normalizer`:\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help\n```\n\nDo not request or configure an external LLM API key for the script. Use the translation capability already available to the executing agent.\n\n### Runtime boundary\n\n- The core workflow reads the one subtitle file selected by the user, writes its work package and final output, and never contacts a translation provider.\n- The optional visualizer is a local display service. It binds only to `127.0.0.1`, stores task history under `~/.agent-subtitle-translator/visualizer`, and accepts bridge requests only through that local service.\n- The bridge does not accept remote URLs, the service never launches a browser subprocess, and visualizer output is confined to the current task's private `output` directory.\n- The Agent or user opens the visualizer URL explicitly. The visualizer is display-only and does not receive subtitle uploads or translation controls from the browser.\n\n## Workflow\n\n### Optional Agent visualizer workflow\n\nThe deterministic CLI workflow can run without a Web service. When the Agent or user chooses to observe progress in the visualizer, complete these steps before using the bridge:\n\n1. **Check the environment.** Run from the Skill directory. Install or verify the Python dependency from `requirements.txt`, confirm Python can run `scripts/subtitle_tool.py --help`, confirm Node.js satisfies the package requirement (Node 20 or newer), install Node dependencies once with `npm install`, and run `npm run build` successfully.\n2. **Check the Web service.** Request `http://127.0.0.1:4317/api/health`. Reuse the service only when the response is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict, then record the printed URL.\n3. **Open the Web page when requested.** Navigate the selected browser to the printed local URL and report whether it loaded. Browser access is an observation step and does not grant the page task-input or translation permissions.\n4. **Run the visualizer workflow.** Run `identify`, then create the task, start batches, submit and validate responses, and compose through `visualizer:bridge`. Keep reporting each meaningful operation in the Agent response.\n\nThe commands in the sections below describe the direct deterministic CLI workflow and the safety rules implemented by the bridge. During an Agent visualizer run, use the equivalent bridge commands after the local service is healthy. Do not compose the same task and output path through both workflows.\n\n### 1. Prepare one file\n\nRequire a target BCP 47 tag. Accept an optional source tag; omit it to let the translation model detect the source language.\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n```\n\nUse `--work-dir` to choose the package location. The command otherwise creates a hidden sibling directory. Do not use `--overwrite-work` unless replacing that package is intentional.\n\nInspect the JSON report. Stop on decoding, empty-body, invalid-timeline, or structural errors. Note any out-of-order input and ASS karaoke IDs. Preparation creates:\n\n- `manifest.json`: local structure, mapping, and validation facts; do not send it to the model.\n- `batches/batch-NNNN.txt`: ready-to-send prompts containing stable IDs and text, never timelines.\n- `validated/`: destination for verified batch results.\n\nEach batch contains at most 32 entries. Do not increase that ceiling. Dispatch batches serially or concurrently using the agent's available scheduling; this skill imposes no concurrency limit.\n\n### 2. Translate batches\n\nSend each complete `batch-NNNN.txt` prompt to the translation model without rewriting its fixed instructions. Save the raw response as UTF-8 text.\n\nDo not promise cross-batch consistency for names or terminology. The prompt supplies only the local batch context.\n\n### 3. Validate every response\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n```\n\nOn any count, ID, order, wrapper, hard-break, fixed-structure, or style-marker error, resend that batch with the original prompt and the validator error as a correction request. Never fill a missing translation from a neighboring entry.\n\nIf the retried response still has a count, ID, wrapper, `BR`, or `F` mismatch, stop the entire job. Reliable timeline mapping is impossible.\n\nIf only ASS `S` style markers remain invalid after a retry, validate with `--allow-style-fallback`. This removes inline style markers only for the affected entries and records their IDs. Do not use this option before a retry.\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001-retry.txt \\\n  --allow-style-fallback\n```\n\nUse `--overwrite` only to replace the prior validated JSON for that batch.\n\n### 4. Compose after all batches validate\n\n```bash\npython3 scripts/subtitle_tool.py compose --manifest /path/work/manifest.json\n```\n\nThe script merges validated data by stable subtitle ID, independent of completion order. It refuses missing, duplicate, or extra IDs and refuses to overwrite output by default. If the output already exists, choose a new `--output` path or pass `--overwrite` only when replacing that exact output is intentional.\n\nThe final report is written next to the subtitle as `<output-path>.report.json`, not at the work directory root. For example, `SPS.ja.srt` has the report `SPS.ja.srt.report.json`.\n\nRead the final report and tell the user:\n\n- output path, format, encoding, entry count, and time range;\n- count and IDs of karaoke degradations;\n- count and IDs of inline-style fallbacks.\n\n## Local visualizer workflow\n\nThe local visualizer is optional. Direct CLI-only use remains available when an Agent is invoking the deterministic tool without a visualizer session. The Web interface is display-only: it never accepts subtitle files, target languages, or translation controls. The Agent remains the only task input and execution surface.\n\nThe visualizer listens on `127.0.0.1` by default and stores task history outside the repository under `~/.agent-subtitle-translator/visualizer`.\n\nInstall the service once, then check for a reusable instance before starting it:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n# Run this only when the health check fails:\n# npm run visualizer:start\n```\n\nReuse the existing instance when `/api/health` returns HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when the visualizer is requested and skip `npm run visualizer:start`. If the health request fails or reports an incompatible version, start the service only after addressing the occupied port. If the port responds with another service, report the conflict and use a different port or resolve it deliberately; do not terminate an unknown process automatically.\n\nThe visualizer does not call a translation model and keeps the deterministic safety contract; all task inputs and real translation stages come from the Agent through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send the complete batches/batch-0001.txt prompt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to overwrite an existing subtitle or report by default. Use a new `--output` path for a separate result, or pass `--overwrite` only when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report path returned by bridge composition is `<output-path>.report.json`, alongside the generated subtitle.\n\nIf validation fails, report the failure in the Web task, retry with the original prompt and the validator error, then submit the retried response. Use `retry-batch --task TASK_ID --batch 1` before sending the retry. Use `--allow-style-fallback` only after the required retry and only when the remaining problem is an ASS `S` marker mismatch.\n\nRun identify at the beginning of the visualizer session. The session line shows the reported Agent, each task card shows the model recorded for that task, and the program metadata line separately shows the shared program and Skill version read from package.json. Pass the complete model identifier in `--model` whenever the Agent knows it, such as `GPT-5.6 Luna Hight`; pass `--model-version`, `--model-series`, and `--reasoning-strength` when those fields exist, such as `GPT` + `5.6` + `Sol` + `high`. Older or other models may omit any optional field, and the Web page omits missing fields. Never invent a version, series, or reasoning value that the Agent cannot verify. Keep reporting the same progress in the Agent response after every meaningful bridge operation.\n\nThe Web interface supports multiple Agent-created tasks at once. The left queue shows each task and its overall status; the selected task shows batch progress, per-task and per-batch duration, visible subtitle text, validation/retry/degradation warnings, and the live event stream. The interface never displays the manifest, accepts task input, or sends timestamps and raw ASS override tags to the model.\n\n### Agent-side progress output\n\nThe Agent must continue reporting progress in its own response while the Web page is open. Web events do not replace Agent output. At minimum, report:\n\n- the visualizer URL and whether it was opened in the selected browser;\n- task creation and subtitle preparation, including entry and batch counts;\n- each batch start, validation result, retry, and degradation;\n- final composition, output path, format, duration, and any warnings.\n\nKeep these updates concise and synchronized with the bridge calls so the user can follow the same run in the Agent and in the Web page.\n\n## Format behavior\n\n- Write SRT input as UTF-8-BOM SRT.\n- Normalize VTT input locally and write UTF-8-BOM SRT.\n- Keep ASS as UTF-8-BOM ASS. Preserve non-dialogue sections, styles, comments, pure drawings, event order, timestamps, Layer, Style, Name, margins, Effect, and other event fields.\n- Translate only visible ASS Dialogue text. Convert inline style scopes to paired neutral markers and `\\N`/`\\n` to movable `BR` markers, then restore validated structure.\n- Degrade karaoke entries containing `\\k`, `\\K`, `\\kf`, or `\\ko` individually to static text. Preserve the base Style/event fields and safe whole-line positioning while removing syllable timing and inapplicable animation.\n- Name default output `<stem>.<normalized-BCP47>.<ext>`, such as `movie.zh-Hans.srt` or `movie.pt-BR.ass`.\n\n## Safety invariants\n\n- Process exactly one input file per run.\n- Never expose `manifest.json`, timestamps, or raw ASS override tags to the translation model.\n- Never infer mapping from proximity, text similarity, or character positions.\n- Never silently discard marker failures or degradations.\n- Never overwrite a work package, validated result, subtitle, or report without the matching explicit overwrite flag.\n\nFile v1.0.8:README.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator logo\" width=\"180\">\n</p>\n\n[简体中文](README.zh-CN.md)\n\nTranslate one SRT, VTT, or ASS subtitle file with local timeline handling, strict ID validation, and safe ASS structure preservation.\n\nThis repository is a Skill first. The bundled CLI performs deterministic decoding, parsing, batching, validation, and composition; the executing Agent uses its available translation model, so the CLI needs no external LLM API key.\n\n> ⭐ If this Skill helps you, please [star the repository](https://github.com/Lumen01/agent-subtitle-translator). It helps more people discover the project and supports continued improvements.\n\n## Install the Skill\n\n### Ask an Agent to install it\n\nCopy this prompt to an Agent with terminal access:\n\n```text\nInstall this Skill following the instructions at https://github.com/Lumen01/agent-subtitle-translator and confirm that the current Agent can use it. If it conflicts with an existing installation, let me know before proceeding.\n```\n\n### Install manually\n\n#### Shared by multiple Agents\n\nInstall one shared copy for Codex, Claude, OpenCode, and other compatible runtimes:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\nPoint each runtime at the shared copy if it requires its own skills directory:\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\nInspect each destination first; do not replace an existing file, directory, or link blindly.\n\n#### One runtime only\n\nClone directly into that runtime's documented skills directory. For example:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\nThe installed skill root must contain a discoverable `SKILL.md`.\n\n## Prompt an Agent to use it\n\nName the skill, one input file, and the required target language. The source language is optional.\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/movie.en.srt to Simplified Chinese (zh-Hans). Keep the original timing, do not overwrite existing output, and report any degradation.\n```\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/signs.ass from English to Brazilian Portuguese (pt-BR). Preserve ASS styles and event metadata wherever safe.\n```\n\nThe Agent prepares batches of at most 32 entries, translates them using its available model, retries invalid batch structures, validates stable IDs and markers, and composes only after every batch maps safely. The Skill does not impose a concurrency cap; completed batches are merged by stable ID, not completion order.\n\n## Supported formats and output\n\n| Input | Output | Behavior |\n| --- | --- | --- |\n| SRT | SRT | Preserve timing; normalize indices and timeline order. |\n| VTT/WebVTT | SRT | Convert locally to normalized SRT. |\n| ASS | ASS | Preserve the document and event structure; replace only visible Dialogue text. |\n\nDefault output is `<stem>.<normalized-BCP47>.<ext>`, for example `movie.zh-Hans.srt` or `movie.pt-BR.ass`. Existing work directories, validated responses, subtitle outputs, and reports are not overwritten unless the corresponding explicit overwrite flag is used. SRT and ASS outputs use UTF-8 BOM.\n\nThe CLI recognizes UTF BOMs and UTF-8 directly. It uses `charset-normalizer` for common legacy encodings and stops when the result is too ambiguous to map safely. Preparation reports entry counts, time range, ordering, empty text, format conversion, and ASS-specific preservation facts.\n\n## ASS style preservation and karaoke degradation\n\nOriginal ASS tags never go to the translation model. Inline style ranges become paired neutral markers such as `⟦S1⟧...⟦/S1⟧`; the markers can move with their meaning in the target language. Hard line breaks become unique movable `BR` markers. After translation, the CLI validates marker count, identity, closure, and nesting before restoring the original tags.\n\nFor example, this source:\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\ncan safely become:\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\nIf an inline-style response still cannot be restored after a retry, the Agent may explicitly downgrade only that subtitle entry to static text and must report its ID. Count, ID, wrapper, hard-break, or fixed-structure mismatches remain fatal; the Skill never borrows adjacent translations or guesses character positions.\n\nEntries containing `\\k`, `\\K`, `\\kf`, or `\\ko` karaoke timing are intentionally downgraded one entry at a time. The output keeps the event timeline, base Style, fields, and safe whole-line positioning, but removes syllable timing and no-longer-applicable character animation. This is reported as a degradation, not a translation failure. Other ordinary ASS entries in the same file retain their supported styling.\n\n## Agent execution order\n\nWhen an Agent uses this Skill, the deterministic CLI workflow may run directly. Use the following local visualizer steps only when the Agent or user wants live progress:\n\n1. Check the environment from the Skill directory: install or verify the Python dependency from `requirements.txt`, verify Python can run `scripts/subtitle_tool.py --help`, verify Node.js is 20 or newer, install Node dependencies with `npm install` when needed, and run `npm run build` successfully.\n2. Check `http://127.0.0.1:4317/api/health`. Reuse the service only when it is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict.\n3. When visual progress is requested, open the printed loopback URL in the selected browser and report whether it loaded.\n4. Run `visualizer:bridge -- identify`, then create the task, translate batches, validate responses, and compose through bridge.\n\nThe CLI block below is the deterministic core reference. Do not mix CLI composition with bridge composition for the same task and output path.\n\n## Deterministic CLI reference\n\nThe Agent normally runs these commands from the installed skill directory:\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\nSee `python3 scripts/subtitle_tool.py --help` and each subcommand's `--help` for collision and retry flags. The generated batch prompts contain text and stable IDs but no timelines or raw ASS override tags.\nThe final composition report is written alongside the subtitle as `<output-path>.report.json`; for example, `SPS.ja.srt` produces `SPS.ja.srt.report.json`. If the output already exists, choose a new path or pass the explicit overwrite flag only when replacement is intentional.\n\n## Local translation visualizer\n\nThis Skill includes an optional local, display-only Web workspace. It presents the Agent-created task queue on the left and the selected task's batches, validation, retries, degradations, timing, subtitle preview, and event stream on the right. Subtitle files, target languages, and translation controls remain in the Agent; the Web page does not accept task input. The original Python CLI remains the deterministic processing core.\n\nFor an Agent visualizer run, use the bridge as the single task execution path. The direct CLI commands above remain available for CLI-only use; do not compose the same task and output path through both paths.\n\nRun or reuse the local service from the Skill directory:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\nReuse the instance when the health response is HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when visual progress is requested and skip starting another process. If the request fails or reports an incompatible version, address the occupied port before starting the current release. If the port is occupied by another service, report the conflict and choose a different port or resolve it deliberately. The service binds only to `127.0.0.1` and persists local task history under `~/.agent-subtitle-translator/visualizer`. The Agent opens the printed URL explicitly when needed. The Agent continues reporting the same task progress in its own response. The visualizer does not call a translation provider or require an API key. The Agent sends real execution updates through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send batches/batch-0001.txt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to replace an existing subtitle or report by default. The bridge accepts `--output` only as a filename inside the current task's private output directory. Use a fresh filename for a separate result, or add `--overwrite` when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report is stored beside the output as `<output-path>.report.json`.\n\nThe Web page displays the reported Agent in the session line, records the reported model on each task card, and separately displays the shared program and Skill version from package.json. Pass the complete model identifier in `--model` whenever it is known, such as `GPT-5.6 Luna Hight`. `--model-version`, `--model-series`, and `--reasoning-strength` are optional, so older or other models can omit them and the Web page leaves those fields out. Do not invent values that the Agent cannot verify. Run identify at the beginning of each visualizer session. The Web page only displays tasks created and controlled by the Agent. Direct CLI-only workflows can run without the Web service; when the visualizer is active, keep task creation, validation, and composition on the bridge path.\n\n## Automatic ClawHub Publishing\n\nThe GitHub Actions workflow at `.github/workflows/clawhub-publish.yml` publishes\nthis skill whenever relevant files are pushed to `main`. It uses ClawHub's\nofficial reusable workflow, which skips unchanged content and automatically\ncreates the next patch version when the skill changed.\n\nBefore the first run, add a repository Actions secret named `CLAWHUB_TOKEN`:\n\n1. Create a ClawHub API token from the ClawHub web UI while signed in as the\n   owner of this skill.\n2. In GitHub, open **Settings → Secrets and variables → Actions** for this\n   repository and create the `CLAWHUB_TOKEN` secret with that value.\n3. Run **Publish Subtitle Translator to ClawHub** once from the Actions tab, or\n   push a relevant change to `main`.\n\nThe token is only passed to the publishing workflow and must never be committed\nto this repository.\n\n## Develop and test\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.8:_meta.json\n\n{\n  \"ownerId\": \"kn78ge2mfb4vyz0qn9xpnne8v58a732j\",\n  \"slug\": \"agent-subtitle-translator\",\n  \"version\": \"1.0.8\",\n  \"publishedAt\": 1788518076210\n}\n\nFile v1.0.8:AGENTS.md\n\n# Repository Instructions\n\n- 在 `dev` 分支中研发迭代。\n\nFile v1.0.8:README.zh-CN.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator Logo\" width=\"180\">\n</p>\n\n[English](README.md)\n\n安全翻译单个 SRT、VTT 或 ASS 字幕文件：时间轴在本地处理，字幕 ID 严格校验，并尽可能完整保留 ASS 结构。\n\n本仓库首先是一个 Skill。内置 CLI 负责确定性的解码、解析、分批、校验和合成；执行 Agent 使用自身可用的翻译模型，因此 CLI 不需要外部 LLM API Key。\n\n> ⭐ 如果这个 Skill 对你有帮助，请为[本仓库点一个 Star](https://github.com/Lumen01/agent-subtitle-translator)。你的支持能让更多人发现这个项目，也会鼓励项目持续改进。\n\n## 安装 Skill\n\n### 让 Agent 执行安装\n\n将下面这段 Prompt 交给有终端权限的 Agent：\n\n```text\n请按照 https://github.com/Lumen01/agent-subtitle-translator 的安装说明安装此 Skill，并确认当前 Agent 能够使用。若与现有安装冲突，请先告知我。\n```\n\n### 手工安装\n\n#### 多 Agent 共用\n\n为 Codex、Claude、OpenCode 等兼容运行时安装一份共享副本：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\n如果运行时要求使用自己的 Skill 目录，将其指向共享副本：\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\n执行前先检查每个目标位置；不要盲目替换已有文件、目录或链接。\n\n#### 仅供一个运行时使用\n\n直接克隆到该运行时文档约定的 Skill 目录。例如：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\n安装后的 Skill 根目录必须包含可发现的 `SKILL.md`。\n\n## 提示 Agent 使用\n\n在 Prompt 中写明 Skill、一个输入文件和必填的目标语言；源语言可省略。\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/movie.en.srt 翻译为简体中文（zh-Hans）。保留原时间轴，不覆盖已有输出，并报告所有降级项。\n```\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/signs.ass 从英语翻译为巴西葡萄牙语（pt-BR）。尽可能保留 ASS 样式和事件元数据。\n```\n\nAgent 会以每批最多 32 条字幕准备任务，使用自身可用模型翻译，重试结构无效的批次，严格校验稳定 ID 和标记，并只在全部批次都能安全映射后合成。Skill 不设置并发上限；批次结果按稳定 ID 合并，不按完成先后合并。\n\n## 支持格式与输出\n\n| 输入 | 输出 | 行为 |\n| --- | --- | --- |\n| SRT | SRT | 保留时间轴；规范化编号和时间顺序。 |\n| VTT/WebVTT | SRT | 在本地转换为规范化 SRT。 |\n| ASS | ASS | 保留文档和事件结构，只替换 Dialogue 的可见正文。 |\n\n默认输出名为 `<stem>.<规范化-BCP47>.<ext>`，例如 `movie.zh-Hans.srt` 或 `movie.pt-BR.ass`。除非使用对应的显式覆盖参数，否则不会覆盖已有工作目录、已校验响应、字幕输出或报告。SRT 与 ASS 输出使用 UTF-8 BOM。\n\nCLI 可直接识别 UTF BOM 和 UTF-8，并通过 `charset-normalizer` 检测常见旧编码；检测结果过于含糊时会停止，以免错误映射。准备报告会列出条目数、时间范围、排序、空正文、格式转换和 ASS 专属保留信息。\n\n## ASS 样式保持与卡拉 OK 降级\n\n原始 ASS 标签不会提交给翻译模型。行内样式范围会转换为 `⟦S1⟧...⟦/S1⟧` 这类成对中性标记，标记可随对应语义在目标语言中移动。硬换行会转换为唯一、可移动的 `BR` 标记。翻译完成后，CLI 会校验标记数量、身份、闭合和嵌套，再恢复原标签。\n\n例如，以下原文：\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\n可以安全得到：\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\n如果重试后仍无法恢复某条字幕的行内样式，Agent 可显式地只把该条降级为静态文本，并必须报告其 ID。条数、ID、外层结构、硬换行或固定结构不匹配仍是致命错误；Skill 绝不会借用相邻译文，也不会根据字符位置猜测样式。\n\n含 `\\k`、`\\K`、`\\kf` 或 `\\ko` 卡拉 OK 计时的条目会按条明确降级。输出保留事件时间轴、基础 Style、其他字段和安全的整行位置，但移除逐音节计时和不再适用的字符动画。该情况会作为降级报告，而不是翻译失败。同一文件中的其他普通 ASS 条目仍保留受支持的样式。\n\n## Agent 执行顺序\n\nAgent 使用本 Skill 时，可以直接运行确定性 CLI。需要观察实时进度时，再按以下步骤启用本地 visualizer：\n\n1. 在 Skill 目录检查环境：安装或确认 `requirements.txt` 中的 Python 依赖，确认 Python 能运行 `scripts/subtitle_tool.py --help`，确认 Node.js 为 20 或更高版本；需要时运行 `npm install`，并确认 `npm run build` 成功。\n2. 检查 `http://127.0.0.1:4317/api/health`。只有健康状态正确、服务标识为 `subtitle-visualizer` 且 Skill 版本兼容时才复用；否则先处理端口占用，再启动服务。\n3. 需要观察实时进度时，在指定浏览器中打开服务打印的本机 URL，并报告页面是否加载成功。\n4. 运行 `visualizer:bridge -- identify`，然后创建任务、翻译批次、校验响应，并通过 bridge compose。\n\n下面的 CLI 代码块是确定性核心能力参考。同一任务和输出路径不要混用 CLI compose 与 bridge compose。\n\n## 确定性 CLI 参考\n\nAgent 通常在已安装的 Skill 目录运行以下命令：\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\n运行 `python3 scripts/subtitle_tool.py --help` 及各子命令的 `--help` 可查看碰撞与重试参数。生成的批次 Prompt 只包含正文和稳定 ID，不包含时间轴或原始 ASS override 标签。最终报告与字幕位于同一目录，路径为 `<output-path>.report.json`；例如 `SPS.ja.srt` 对应 `SPS.ja.srt.report.json`。如果输出已存在，请选择新路径；只有明确要替换原结果时才使用显式覆盖参数。\n\n## 本地翻译过程可视化\n\n本 Skill 提供一个可选的、只负责展示的本地 Web 工作台，适合普通用户同时观察多个由 Agent 创建的字幕翻译任务。左侧显示任务队列，点击任务后，右侧会展示批次进度、校验、重试、降级、翻译耗时、字幕明细和实时事件流。字幕文件、目标语言和翻译控制全部在 Agent 中完成，Web 页面不接受任务输入。原有 Python CLI 继续负责确定性的字幕处理核心。\n\nAgent 使用 visualizer 时，bridge 是唯一的任务执行入口。上面的 CLI 命令仍可用于纯 CLI 调用；同一任务和输出路径不要先后通过两套入口重复 compose。\n\n在 Skill 目录启动或复用本地服务：\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\n当健康接口返回 HTTP 200，且 JSON 中 `status` 为 `\"ok\"`、`service` 为 `\"subtitle-visualizer\"`，版本与当前 Skill 兼容（本版为 `1.1.1`）时，复用现有实例并仅在需要观察实时进度时打开其 URL，跳过第二次启动。请求失败或版本不兼容时，先处理占用端口，再启动当前版本。如果端口被其他服务占用，应报告冲突并选择其他端口或有意处理，不要自动终止未知进程。服务只监听 `127.0.0.1`，任务历史保存在仓库外的 `~/.agent-subtitle-translator/visualizer`。Agent 需要观察进度时显式打开打印出的本机 URL。Agent 端同时继续输出任务创建、字幕准备、批次处理、校验、重试、降级和最终生成状态。服务不会调用翻译服务，也不要求配置 API Key；Agent 通过桥接命令上报真实执行过程：\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent 名称\" \\\n  --model \"模型名称\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# 将 batches/batch-0001.txt 完整发送给当前可用的翻译模型。\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nbridge 默认拒绝覆盖已有字幕或报告。`--output` 只能指定当前任务私有 output 目录中的文件名。需要生成另一份结果时，请传入新的文件名；明确替换同一结果时，才追加 `--overwrite`：\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\n报告位于输出字幕旁边，路径为 `<output-path>.report.json`。\n\n如果校验失败，先在 Web 任务中记录失败，再使用原始 Prompt 和校验错误重试；发送重试前运行 `retry-batch --task TASK_ID --batch 1`。只有完成规定重试且剩余问题为 ASS `S` 样式标记不匹配时，才可以使用 `--allow-style-fallback`。\n\n运行 identify 后，Web 页面会在会话行显示 Agent，并在每个任务卡片内显示该任务记录的翻译模型；下方程序元数据显示共用的程序与 Skill 版本，该版本统一从 package.json 读取。Agent 知道完整模型标识时，应将它作为 `--model` 传入，例如 `GPT-5.6 Luna Hight`；也可以通过 `--model-version`、`--model-series` 和 `--reasoning-strength` 传入 `GPT`、`5.6`、`Sol`、`high` 这类结构化信息。旧模型或其他模型缺少可选字段时，Web 页面会自动省略对应字段；Agent 无法确认的值不应自行补全。建议在每次可视化会话开始时先执行一次 identify。Web 页面只展示 Agent 创建和控制的任务。纯 CLI 流程可以不启动 Web 服务；visualizer 启用后，任务创建、校验和 compose 都应保持在 bridge 入口。\n\n## 自动发布到 ClawHub\n\n`.github/workflows/clawhub-publish.yml` 会在相关文件推送到 `main` 时自动发布本技能。它使用 ClawHub 官方可复用工作流：未变更内容会被跳过；技能有变更时会自动发布下一个 patch 版本。\n\n首次运行前，请添加名为 `CLAWHUB_TOKEN` 的仓库 Actions Secret：\n\n1. 以该技能所有者身份登录 ClawHub，在网页中创建 ClawHub API token。\n2. 在 GitHub 仓库打开 **Settings → Secrets and variables → Actions**，新建名为 `CLAWHUB_TOKEN` 的 Secret，并填入该 token。\n3. 在 Actions 页面手动运行一次 **Publish Subtitle Translator to ClawHub**，或向 `main` 推送相关改动。\n\n该 token 只会传给发布工作流，绝不能提交到仓库。\n\n## 开发与测试\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.8:skill-card.md\n\n## Description:\n\nTranslate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[lumen01](https://clawhub.ai/user/lumen01)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and subtitle localization agents use this skill to translate SRT, WebVTT/VTT, or ASS subtitle files while preserving timing and validating stable subtitle mappings before output is written.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The optional visualizer stores local task history and agent/model labels under ~/.agent-subtitle-translator/visualizer, which may retain private subtitle text.\n\nMitigation: Use the visualizer only when local progress display is needed and remove stored task history when subtitle content should not persist.\n\nRisk: Overwrite flags can replace generated work packages, validated responses, subtitles, or reports.\n\nMitigation: Use overwrite flags only when intentionally replacing the exact generated artifact.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/lumen01/skills/agent-subtitle-translator)\n- [Project Homepage](https://github.com/Lumen01/agent-subtitle-translator)\n- [README](README.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with command examples and generated subtitle/report files]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces one translated subtitle output and an adjacent report after validation; optional visualizer output is confined to the current task output directory.]\n\n## Skill Version(s):\n\n1.0.8 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.8:package-lock.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"agent-subtitle-translator\",\n      \"version\": \"1.1.1\",\n      \"devDependencies\": {\n        \"@types/node\": \"^22.15.0\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.20.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz\",\n      \"integrity\": \"sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"undici-types\": \"~6.21.0\"\n      }\n    },\n    \"node_modules/typescript\": {\n      \"version\": \"5.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n      \"dev\": true,\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=14.17\"\n      }\n    },\n    \"node_modules/undici-types\": {\n      \"version\": \"6.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    }\n  }\n}\n\nFile v1.0.8:package.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"private\": true,\n  \"description\": \"Local subtitle translation workflow with an optional loopback-only visualizer for Agent runs.\",\n  \"type\": \"module\",\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc -p tsconfig.json\",\n    \"test\": \"npm run build && node --test dist/tests/*.test.js\",\n    \"visualizer:start\": \"npm run build && node dist/src/server.js\",\n    \"visualizer:bridge\": \"npm run build && node dist/src/agent-bridge.js\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.15.0\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n\nFile v1.0.8:tsconfig.json\n\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"rootDir\": \".\",\n    \"outDir\": \"dist\",\n    \"strict\": true,\n    \"noImplicitOverride\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noEmitOnError\": true,\n    \"sourceMap\": true,\n    \"skipLibCheck\": true,\n    \"lib\": [\"ES2022\", \"DOM\"]\n  },\n  \"include\": [\"src/**/*.ts\", \"web/**/*.ts\", \"tests/**/*.ts\"],\n  \"exclude\": [\"dist\", \"node_modules\"]\n}\n\nFile v1.0.8:agents/openai.yaml\n\ninterface:\n  display_name: \"Agent Subtitle Translator\"\n  short_description: \"Translate SRT, VTT, and ASS subtitles safely\"\n  icon_small: \"./assets/icon-small.png\"\n  icon_large: \"./assets/icon-large.png\"\n  brand_color: \"#FF9940\"\n  default_prompt: \"Use $agent-subtitle-translator to translate one subtitle file while preserving its timing and supported ASS structure.\"\n\nFile v1.0.8:requirements.txt\n\ncharset-normalizer>=3.3,<4\n\nArchive v1.0.7: 42 files, 624567 bytes\n\nFiles: .clawhubignore (186b), .github (0b), .github/workflows (0b), .github/workflows/clawhub-publish.yml (699b), .gitignore (30b), .impeccable.md (1301b), agents (0b), AGENTS.md (64b), agents/openai.yaml (367b), assets (0b), assets/icon-large.png (271934b), assets/icon-small.png (271934b), package-lock.json (1460b), package.json (606b), README.md (12524b), README.zh-CN.md (12178b), requirements.txt (27b), scripts (0b), scripts/subtitle_tool.py (43893b), skill-card.md (2409b), SKILL.md (12834b), src (0b), src/agent-bridge.ts (6312b), src/common.ts (4164b), src/python-cli.ts (4121b), src/server.ts (10566b), src/task-manager.ts (25862b), tests (0b), tests/fixtures (0b), tests/fixtures/basic.srt (91b), tests/fixtures/basic.vtt (101b), tests/fixtures/karaoke.ass (626b), tests/fixtures/styled.ass (969b), tests/test_subtitle_tool.py (18431b), tests/visualizer.test.ts (24794b), tsconfig.json (455b), web (0b), web/app.ts (32501b), web/icons.ts (6681b), web/index.html (8668b), web/styles.css (33572b), _meta.json (144b)\n\nFile v1.0.7:SKILL.md\n\n---\nname: agent-subtitle-translator\ndescription: Translate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer. Use when an agent needs to translate SRT, WebVTT/VTT, or ASS subtitles; preserve ASS sections, event fields, inline semantic styling, or hard line breaks; normalize VTT to SRT; detect karaoke degradation; or validate an LLM subtitle translation before writing it.\nmetadata:\n  author: \"Lumen\"\n  openclaw:\n    requires:\n      bins:\n        - node\n        - npm\n        - python3\n    homepage: \"https://github.com/Lumen01/agent-subtitle-translator\"\n---\n\n# Agent Subtitle Translator\n\nTranslate only subtitle text with an available translation model. Delegate decoding, parsing, batching, marker validation, timeline mapping, and output writing to `scripts/subtitle_tool.py`. Never send timestamps or original ASS override tags to the model.\n\n## Prerequisite\n\nRun commands from this skill directory. The script uses only the standard library for UTF inputs; legacy encodings require `charset-normalizer`:\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help\n```\n\nDo not request or configure an external LLM API key for the script. Use the translation capability already available to the executing agent.\n\n### Runtime boundary\n\n- The core workflow reads the one subtitle file selected by the user, writes its work package and final output, and never contacts a translation provider.\n- The optional visualizer is a local display service. It binds only to `127.0.0.1`, stores task history under `~/.agent-subtitle-translator/visualizer`, and accepts bridge requests only through that local service.\n- The bridge does not accept remote URLs, the service never launches a browser subprocess, and visualizer output is confined to the current task's private `output` directory.\n- The Agent or user opens the visualizer URL explicitly. The visualizer is display-only and does not receive subtitle uploads or translation controls from the browser.\n\n## Workflow\n\n### Optional Agent visualizer workflow\n\nThe deterministic CLI workflow can run without a Web service. When the Agent or user chooses to observe progress in the visualizer, complete these steps before using the bridge:\n\n1. **Check the environment.** Run from the Skill directory. Install or verify the Python dependency from `requirements.txt`, confirm Python can run `scripts/subtitle_tool.py --help`, confirm Node.js satisfies the package requirement (Node 20 or newer), install Node dependencies once with `npm install`, and run `npm run build` successfully.\n2. **Check the Web service.** Request `http://127.0.0.1:4317/api/health`. Reuse the service only when the response is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict, then record the printed URL.\n3. **Open the Web page when requested.** Navigate the selected browser to the printed local URL and report whether it loaded. Browser access is an observation step and does not grant the page task-input or translation permissions.\n4. **Run the visualizer workflow.** Run `identify`, then create the task, start batches, submit and validate responses, and compose through `visualizer:bridge`. Keep reporting each meaningful operation in the Agent response.\n\nThe commands in the sections below describe the direct deterministic CLI workflow and the safety rules implemented by the bridge. During an Agent visualizer run, use the equivalent bridge commands after the local service is healthy. Do not compose the same task and output path through both workflows.\n\n### 1. Prepare one file\n\nRequire a target BCP 47 tag. Accept an optional source tag; omit it to let the translation model detect the source language.\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n```\n\nUse `--work-dir` to choose the package location. The command otherwise creates a hidden sibling directory. Do not use `--overwrite-work` unless replacing that package is intentional.\n\nInspect the JSON report. Stop on decoding, empty-body, invalid-timeline, or structural errors. Note any out-of-order input and ASS karaoke IDs. Preparation creates:\n\n- `manifest.json`: local structure, mapping, and validation facts; do not send it to the model.\n- `batches/batch-NNNN.txt`: ready-to-send prompts containing stable IDs and text, never timelines.\n- `validated/`: destination for verified batch results.\n\nEach batch contains at most 32 entries. Do not increase that ceiling. Dispatch batches serially or concurrently using the agent's available scheduling; this skill imposes no concurrency limit.\n\n### 2. Translate batches\n\nSend each complete `batch-NNNN.txt` prompt to the translation model without rewriting its fixed instructions. Save the raw response as UTF-8 text.\n\nDo not promise cross-batch consistency for names or terminology. The prompt supplies only the local batch context.\n\n### 3. Validate every response\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n```\n\nOn any count, ID, order, wrapper, hard-break, fixed-structure, or style-marker error, resend that batch with the original prompt and the validator error as a correction request. Never fill a missing translation from a neighboring entry.\n\nIf the retried response still has a count, ID, wrapper, `BR`, or `F` mismatch, stop the entire job. Reliable timeline mapping is impossible.\n\nIf only ASS `S` style markers remain invalid after a retry, validate with `--allow-style-fallback`. This removes inline style markers only for the affected entries and records their IDs. Do not use this option before a retry.\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001-retry.txt \\\n  --allow-style-fallback\n```\n\nUse `--overwrite` only to replace the prior validated JSON for that batch.\n\n### 4. Compose after all batches validate\n\n```bash\npython3 scripts/subtitle_tool.py compose --manifest /path/work/manifest.json\n```\n\nThe script merges validated data by stable subtitle ID, independent of completion order. It refuses missing, duplicate, or extra IDs and refuses to overwrite output by default. If the output already exists, choose a new `--output` path or pass `--overwrite` only when replacing that exact output is intentional.\n\nThe final report is written next to the subtitle as `<output-path>.report.json`, not at the work directory root. For example, `SPS.ja.srt` has the report `SPS.ja.srt.report.json`.\n\nRead the final report and tell the user:\n\n- output path, format, encoding, entry count, and time range;\n- count and IDs of karaoke degradations;\n- count and IDs of inline-style fallbacks.\n\n## Local visualizer workflow\n\nThe local visualizer is optional. Direct CLI-only use remains available when an Agent is invoking the deterministic tool without a visualizer session. The Web interface is display-only: it never accepts subtitle files, target languages, or translation controls. The Agent remains the only task input and execution surface.\n\nThe visualizer listens on `127.0.0.1` by default and stores task history outside the repository under `~/.agent-subtitle-translator/visualizer`.\n\nInstall the service once, then check for a reusable instance before starting it:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n# Run this only when the health check fails:\n# npm run visualizer:start\n```\n\nReuse the existing instance when `/api/health` returns HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when the visualizer is requested and skip `npm run visualizer:start`. If the health request fails or reports an incompatible version, start the service only after addressing the occupied port. If the port responds with another service, report the conflict and use a different port or resolve it deliberately; do not terminate an unknown process automatically.\n\nThe visualizer does not call a translation model and keeps the deterministic safety contract; all task inputs and real translation stages come from the Agent through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send the complete batches/batch-0001.txt prompt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to overwrite an existing subtitle or report by default. Use a new `--output` path for a separate result, or pass `--overwrite` only when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report path returned by bridge composition is `<output-path>.report.json`, alongside the generated subtitle.\n\nIf validation fails, report the failure in the Web task, retry with the original prompt and the validator error, then submit the retried response. Use `retry-batch --task TASK_ID --batch 1` before sending the retry. Use `--allow-style-fallback` only after the required retry and only when the remaining problem is an ASS `S` marker mismatch.\n\nRun identify at the beginning of the visualizer session. The session line shows the reported Agent, each task card shows the model recorded for that task, and the program metadata line separately shows the shared program and Skill version read from package.json. Pass the complete model identifier in `--model` whenever the Agent knows it, such as `GPT-5.6 Luna Hight`; pass `--model-version`, `--model-series`, and `--reasoning-strength` when those fields exist, such as `GPT` + `5.6` + `Sol` + `high`. Older or other models may omit any optional field, and the Web page omits missing fields. Never invent a version, series, or reasoning value that the Agent cannot verify. Keep reporting the same progress in the Agent response after every meaningful bridge operation.\n\nThe Web interface supports multiple Agent-created tasks at once. The left queue shows each task and its overall status; the selected task shows batch progress, per-task and per-batch duration, visible subtitle text, validation/retry/degradation warnings, and the live event stream. The interface never displays the manifest, accepts task input, or sends timestamps and raw ASS override tags to the model.\n\n### Agent-side progress output\n\nThe Agent must continue reporting progress in its own response while the Web page is open. Web events do not replace Agent output. At minimum, report:\n\n- the visualizer URL and whether it was opened in the selected browser;\n- task creation and subtitle preparation, including entry and batch counts;\n- each batch start, validation result, retry, and degradation;\n- final composition, output path, format, duration, and any warnings.\n\nKeep these updates concise and synchronized with the bridge calls so the user can follow the same run in the Agent and in the Web page.\n\n## Format behavior\n\n- Write SRT input as UTF-8-BOM SRT.\n- Normalize VTT input locally and write UTF-8-BOM SRT.\n- Keep ASS as UTF-8-BOM ASS. Preserve non-dialogue sections, styles, comments, pure drawings, event order, timestamps, Layer, Style, Name, margins, Effect, and other event fields.\n- Translate only visible ASS Dialogue text. Convert inline style scopes to paired neutral markers and `\\N`/`\\n` to movable `BR` markers, then restore validated structure.\n- Degrade karaoke entries containing `\\k`, `\\K`, `\\kf`, or `\\ko` individually to static text. Preserve the base Style/event fields and safe whole-line positioning while removing syllable timing and inapplicable animation.\n- Name default output `<stem>.<normalized-BCP47>.<ext>`, such as `movie.zh-Hans.srt` or `movie.pt-BR.ass`.\n\n## Safety invariants\n\n- Process exactly one input file per run.\n- Never expose `manifest.json`, timestamps, or raw ASS override tags to the translation model.\n- Never infer mapping from proximity, text similarity, or character positions.\n- Never silently discard marker failures or degradations.\n- Never overwrite a work package, validated result, subtitle, or report without the matching explicit overwrite flag.\n\nFile v1.0.7:README.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator logo\" width=\"180\">\n</p>\n\n[简体中文](README.zh-CN.md)\n\nTranslate one SRT, VTT, or ASS subtitle file with local timeline handling, strict ID validation, and safe ASS structure preservation.\n\nThis repository is a Skill first. The bundled CLI performs deterministic decoding, parsing, batching, validation, and composition; the executing Agent uses its available translation model, so the CLI needs no external LLM API key.\n\n> ⭐ If this Skill helps you, please [star the repository](https://github.com/Lumen01/agent-subtitle-translator). It helps more people discover the project and supports continued improvements.\n\n## Install the Skill\n\n### Ask an Agent to install it\n\nCopy this prompt to an Agent with terminal access:\n\n```text\nRead https://github.com/Lumen01/agent-subtitle-translator/blob/main/README.md and install the Agent Subtitle Translator Skill according to its “Install Manually” section. Before changing anything, inspect existing installations and preserve unrelated files. Unless I explicitly request one runtime only, prefer one shared multi-Agent installation under ~/.agents/skills and expose it to each requested runtime without creating conflicting copies. Install the declared Python dependency in an appropriate user or managed environment, then confirm that the runtime can discover the installed SKILL.md. Do not overwrite or delete an existing installation without first comparing it and reporting the conflict.\n```\n\n### Install manually\n\n#### Shared by multiple Agents\n\nInstall one shared copy for Codex, Claude, OpenCode, and other compatible runtimes:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\nPoint each runtime at the shared copy if it requires its own skills directory:\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\nInspect each destination first; do not replace an existing file, directory, or link blindly.\n\n#### One runtime only\n\nClone directly into that runtime's documented skills directory. For example:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\nThe installed skill root must contain a discoverable `SKILL.md`.\n\n## Prompt an Agent to use it\n\nName the skill, one input file, and the required target language. The source language is optional.\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/movie.en.srt to Simplified Chinese (zh-Hans). Keep the original timing, do not overwrite existing output, and report any degradation.\n```\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/signs.ass from English to Brazilian Portuguese (pt-BR). Preserve ASS styles and event metadata wherever safe.\n```\n\nThe Agent prepares batches of at most 32 entries, translates them using its available model, retries invalid batch structures, validates stable IDs and markers, and composes only after every batch maps safely. The Skill does not impose a concurrency cap; completed batches are merged by stable ID, not completion order.\n\n## Supported formats and output\n\n| Input | Output | Behavior |\n| --- | --- | --- |\n| SRT | SRT | Preserve timing; normalize indices and timeline order. |\n| VTT/WebVTT | SRT | Convert locally to normalized SRT. |\n| ASS | ASS | Preserve the document and event structure; replace only visible Dialogue text. |\n\nDefault output is `<stem>.<normalized-BCP47>.<ext>`, for example `movie.zh-Hans.srt` or `movie.pt-BR.ass`. Existing work directories, validated responses, subtitle outputs, and reports are not overwritten unless the corresponding explicit overwrite flag is used. SRT and ASS outputs use UTF-8 BOM.\n\nThe CLI recognizes UTF BOMs and UTF-8 directly. It uses `charset-normalizer` for common legacy encodings and stops when the result is too ambiguous to map safely. Preparation reports entry counts, time range, ordering, empty text, format conversion, and ASS-specific preservation facts.\n\n## ASS style preservation and karaoke degradation\n\nOriginal ASS tags never go to the translation model. Inline style ranges become paired neutral markers such as `⟦S1⟧...⟦/S1⟧`; the markers can move with their meaning in the target language. Hard line breaks become unique movable `BR` markers. After translation, the CLI validates marker count, identity, closure, and nesting before restoring the original tags.\n\nFor example, this source:\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\ncan safely become:\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\nIf an inline-style response still cannot be restored after a retry, the Agent may explicitly downgrade only that subtitle entry to static text and must report its ID. Count, ID, wrapper, hard-break, or fixed-structure mismatches remain fatal; the Skill never borrows adjacent translations or guesses character positions.\n\nEntries containing `\\k`, `\\K`, `\\kf`, or `\\ko` karaoke timing are intentionally downgraded one entry at a time. The output keeps the event timeline, base Style, fields, and safe whole-line positioning, but removes syllable timing and no-longer-applicable character animation. This is reported as a degradation, not a translation failure. Other ordinary ASS entries in the same file retain their supported styling.\n\n## Agent execution order\n\nWhen an Agent uses this Skill, the deterministic CLI workflow may run directly. Use the following local visualizer steps only when the Agent or user wants live progress:\n\n1. Check the environment from the Skill directory: install or verify the Python dependency from `requirements.txt`, verify Python can run `scripts/subtitle_tool.py --help`, verify Node.js is 20 or newer, install Node dependencies with `npm install` when needed, and run `npm run build` successfully.\n2. Check `http://127.0.0.1:4317/api/health`. Reuse the service only when it is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict.\n3. When visual progress is requested, open the printed loopback URL in the selected browser and report whether it loaded.\n4. Run `visualizer:bridge -- identify`, then create the task, translate batches, validate responses, and compose through bridge.\n\nThe CLI block below is the deterministic core reference. Do not mix CLI composition with bridge composition for the same task and output path.\n\n## Deterministic CLI reference\n\nThe Agent normally runs these commands from the installed skill directory:\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\nSee `python3 scripts/subtitle_tool.py --help` and each subcommand's `--help` for collision and retry flags. The generated batch prompts contain text and stable IDs but no timelines or raw ASS override tags.\nThe final composition report is written alongside the subtitle as `<output-path>.report.json`; for example, `SPS.ja.srt` produces `SPS.ja.srt.report.json`. If the output already exists, choose a new path or pass the explicit overwrite flag only when replacement is intentional.\n\n## Local translation visualizer\n\nThis Skill includes an optional local, display-only Web workspace. It presents the Agent-created task queue on the left and the selected task's batches, validation, retries, degradations, timing, subtitle preview, and event stream on the right. Subtitle files, target languages, and translation controls remain in the Agent; the Web page does not accept task input. The original Python CLI remains the deterministic processing core.\n\nFor an Agent visualizer run, use the bridge as the single task execution path. The direct CLI commands above remain available for CLI-only use; do not compose the same task and output path through both paths.\n\nRun or reuse the local service from the Skill directory:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\nReuse the instance when the health response is HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when visual progress is requested and skip starting another process. If the request fails or reports an incompatible version, address the occupied port before starting the current release. If the port is occupied by another service, report the conflict and choose a different port or resolve it deliberately. The service binds only to `127.0.0.1` and persists local task history under `~/.agent-subtitle-translator/visualizer`. The Agent opens the printed URL explicitly when needed. The Agent continues reporting the same task progress in its own response. The visualizer does not call a translation provider or require an API key. The Agent sends real execution updates through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send batches/batch-0001.txt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to replace an existing subtitle or report by default. The bridge accepts `--output` only as a filename inside the current task's private output directory. Use a fresh filename for a separate result, or add `--overwrite` when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report is stored beside the output as `<output-path>.report.json`.\n\nThe Web page displays the reported Agent in the session line, records the reported model on each task card, and separately displays the shared program and Skill version from package.json. Pass the complete model identifier in `--model` whenever it is known, such as `GPT-5.6 Luna Hight`. `--model-version`, `--model-series`, and `--reasoning-strength` are optional, so older or other models can omit them and the Web page leaves those fields out. Do not invent values that the Agent cannot verify. Run identify at the beginning of each visualizer session. The Web page only displays tasks created and controlled by the Agent. Direct CLI-only workflows can run without the Web service; when the visualizer is active, keep task creation, validation, and composition on the bridge path.\n\n## Automatic ClawHub Publishing\n\nThe GitHub Actions workflow at `.github/workflows/clawhub-publish.yml` publishes\nthis skill whenever relevant files are pushed to `main`. It uses ClawHub's\nofficial reusable workflow, which skips unchanged content and automatically\ncreates the next patch version when the skill changed.\n\nBefore the first run, add a repository Actions secret named `CLAWHUB_TOKEN`:\n\n1. Create a ClawHub API token from the ClawHub web UI while signed in as the\n   owner of this skill.\n2. In GitHub, open **Settings → Secrets and variables → Actions** for this\n   repository and create the `CLAWHUB_TOKEN` secret with that value.\n3. Run **Publish Subtitle Translator to ClawHub** once from the Actions tab, or\n   push a relevant change to `main`.\n\nThe token is only passed to the publishing workflow and must never be committed\nto this repository.\n\n## Develop and test\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.7:_meta.json\n\n{\n  \"ownerId\": \"kn78ge2mfb4vyz0qn9xpnne8v58a732j\",\n  \"slug\": \"agent-subtitle-translator\",\n  \"version\": \"1.0.7\",\n  \"publishedAt\": 1785828937711\n}\n\nFile v1.0.7:.impeccable.md\n\n## Design Context\n\n### Users\n\n普通用户通过 Agent 同时发起一个或多个字幕翻译任务。他们希望不用理解命令行、批次文件或内部实现，也能看到每个任务当前进展、翻译耗时、校验结果、重试原因、降级提示和最终输出。\n\n### Brand Personality\n\n清晰、可靠、从容。界面要让用户始终知道系统正在做什么、已经完成什么，以及是否需要关注某个问题。\n\n### Aesthetic Direction\n\n面向普通用户的翻译工作台：左侧是可切换的任务队列，右侧是选中任务的过程详情。提供深色与浅色主题切换，使用明确的状态色、时间信息和事件流形成可读的过程叙事。动效用于表达任务状态变化、批次推进和结果完成，按当前需求保持开启，不提供减弱动效设置。\n\n### Design Principles\n\n1. 先让用户看懂任务全局，再逐步展开批次和单条字幕细节。\n2. 每个状态都给出可读的中文说明、时间和下一步结果。\n3. 错误、重试和降级需要显眼且可追溯，不能被装饰性视觉弱化。\n4. 多任务并行时保持左侧列表稳定，右侧详情切换不打断后台任务。\n5. 视觉风格应具备工具感和秩序感，同时保持普通用户可理解的语言与操作。\n\nFile v1.0.7:AGENTS.md\n\n# Repository Instructions\n\n- 在 `dev` 分支中研发迭代。\n\nFile v1.0.7:README.zh-CN.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator Logo\" width=\"180\">\n</p>\n\n[English](README.md)\n\n安全翻译单个 SRT、VTT 或 ASS 字幕文件：时间轴在本地处理，字幕 ID 严格校验，并尽可能完整保留 ASS 结构。\n\n本仓库首先是一个 Skill。内置 CLI 负责确定性的解码、解析、分批、校验和合成；执行 Agent 使用自身可用的翻译模型，因此 CLI 不需要外部 LLM API Key。\n\n> ⭐ 如果这个 Skill 对你有帮助，请为[本仓库点一个 Star](https://github.com/Lumen01/agent-subtitle-translator)。你的支持能让更多人发现这个项目，也会鼓励项目持续改进。\n\n## 安装 Skill\n\n### 让 Agent 执行安装\n\n将下面这段 Prompt 交给有终端权限的 Agent：\n\n```text\n请阅读 https://github.com/Lumen01/agent-subtitle-translator/blob/main/README.md，并按照其中“Install Manually”章节安装 Agent Subtitle Translator Skill。修改前先检查现有安装并保留无关文件。除非我明确要求仅安装到一个运行时，否则优先在 ~/.agents/skills 下安装一份供多个 Agent 共享的版本，并在不制造冲突副本的前提下将它暴露给我指定的各个运行时。在适当的用户环境或托管环境中安装声明的 Python 依赖，然后确认运行时能够发现已安装的 SKILL.md。不要在未比较并报告冲突前覆盖或删除现有安装。\n```\n\n### 手工安装\n\n#### 多 Agent 共用\n\n为 Codex、Claude、OpenCode 等兼容运行时安装一份共享副本：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\n如果运行时要求使用自己的 Skill 目录，将其指向共享副本：\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\n执行前先检查每个目标位置；不要盲目替换已有文件、目录或链接。\n\n#### 仅供一个运行时使用\n\n直接克隆到该运行时文档约定的 Skill 目录。例如：\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\n安装后的 Skill 根目录必须包含可发现的 `SKILL.md`。\n\n## 提示 Agent 使用\n\n在 Prompt 中写明 Skill、一个输入文件和必填的目标语言；源语言可省略。\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/movie.en.srt 翻译为简体中文（zh-Hans）。保留原时间轴，不覆盖已有输出，并报告所有降级项。\n```\n\n```text\n使用 $agent-subtitle-translator 将 ~/Movies/signs.ass 从英语翻译为巴西葡萄牙语（pt-BR）。尽可能保留 ASS 样式和事件元数据。\n```\n\nAgent 会以每批最多 32 条字幕准备任务，使用自身可用模型翻译，重试结构无效的批次，严格校验稳定 ID 和标记，并只在全部批次都能安全映射后合成。Skill 不设置并发上限；批次结果按稳定 ID 合并，不按完成先后合并。\n\n## 支持格式与输出\n\n| 输入 | 输出 | 行为 |\n| --- | --- | --- |\n| SRT | SRT | 保留时间轴；规范化编号和时间顺序。 |\n| VTT/WebVTT | SRT | 在本地转换为规范化 SRT。 |\n| ASS | ASS | 保留文档和事件结构，只替换 Dialogue 的可见正文。 |\n\n默认输出名为 `<stem>.<规范化-BCP47>.<ext>`，例如 `movie.zh-Hans.srt` 或 `movie.pt-BR.ass`。除非使用对应的显式覆盖参数，否则不会覆盖已有工作目录、已校验响应、字幕输出或报告。SRT 与 ASS 输出使用 UTF-8 BOM。\n\nCLI 可直接识别 UTF BOM 和 UTF-8，并通过 `charset-normalizer` 检测常见旧编码；检测结果过于含糊时会停止，以免错误映射。准备报告会列出条目数、时间范围、排序、空正文、格式转换和 ASS 专属保留信息。\n\n## ASS 样式保持与卡拉 OK 降级\n\n原始 ASS 标签不会提交给翻译模型。行内样式范围会转换为 `⟦S1⟧...⟦/S1⟧` 这类成对中性标记，标记可随对应语义在目标语言中移动。硬换行会转换为唯一、可移动的 `BR` 标记。翻译完成后，CLI 会校验标记数量、身份、闭合和嵌套，再恢复原标签。\n\n例如，以下原文：\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\n可以安全得到：\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\n如果重试后仍无法恢复某条字幕的行内样式，Agent 可显式地只把该条降级为静态文本，并必须报告其 ID。条数、ID、外层结构、硬换行或固定结构不匹配仍是致命错误；Skill 绝不会借用相邻译文，也不会根据字符位置猜测样式。\n\n含 `\\k`、`\\K`、`\\kf` 或 `\\ko` 卡拉 OK 计时的条目会按条明确降级。输出保留事件时间轴、基础 Style、其他字段和安全的整行位置，但移除逐音节计时和不再适用的字符动画。该情况会作为降级报告，而不是翻译失败。同一文件中的其他普通 ASS 条目仍保留受支持的样式。\n\n## Agent 执行顺序\n\nAgent 使用本 Skill 时，可以直接运行确定性 CLI。需要观察实时进度时，再按以下步骤启用本地 visualizer：\n\n1. 在 Skill 目录检查环境：安装或确认 `requirements.txt` 中的 Python 依赖，确认 Python 能运行 `scripts/subtitle_tool.py --help`，确认 Node.js 为 20 或更高版本；需要时运行 `npm install`，并确认 `npm run build` 成功。\n2. 检查 `http://127.0.0.1:4317/api/health`。只有健康状态正确、服务标识为 `subtitle-visualizer` 且 Skill 版本兼容时才复用；否则先处理端口占用，再启动服务。\n3. 需要观察实时进度时，在指定浏览器中打开服务打印的本机 URL，并报告页面是否加载成功。\n4. 运行 `visualizer:bridge -- identify`，然后创建任务、翻译批次、校验响应，并通过 bridge compose。\n\n下面的 CLI 代码块是确定性核心能力参考。同一任务和输出路径不要混用 CLI compose 与 bridge compose。\n\n## 确定性 CLI 参考\n\nAgent 通常在已安装的 Skill 目录运行以下命令：\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\n运行 `python3 scripts/subtitle_tool.py --help` 及各子命令的 `--help` 可查看碰撞与重试参数。生成的批次 Prompt 只包含正文和稳定 ID，不包含时间轴或原始 ASS override 标签。最终报告与字幕位于同一目录，路径为 `<output-path>.report.json`；例如 `SPS.ja.srt` 对应 `SPS.ja.srt.report.json`。如果输出已存在，请选择新路径；只有明确要替换原结果时才使用显式覆盖参数。\n\n## 本地翻译过程可视化\n\n本 Skill 提供一个可选的、只负责展示的本地 Web 工作台，适合普通用户同时观察多个由 Agent 创建的字幕翻译任务。左侧显示任务队列，点击任务后，右侧会展示批次进度、校验、重试、降级、翻译耗时、字幕明细和实时事件流。字幕文件、目标语言和翻译控制全部在 Agent 中完成，Web 页面不接受任务输入。原有 Python CLI 继续负责确定性的字幕处理核心。\n\nAgent 使用 visualizer 时，bridge 是唯一的任务执行入口。上面的 CLI 命令仍可用于纯 CLI 调用；同一任务和输出路径不要先后通过两套入口重复 compose。\n\n在 Skill 目录启动或复用本地服务：\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\n当健康接口返回 HTTP 200，且 JSON 中 `status` 为 `\"ok\"`、`service` 为 `\"subtitle-visualizer\"`，版本与当前 Skill 兼容（本版为 `1.1.1`）时，复用现有实例并仅在需要观察实时进度时打开其 URL，跳过第二次启动。请求失败或版本不兼容时，先处理占用端口，再启动当前版本。如果端口被其他服务占用，应报告冲突并选择其他端口或有意处理，不要自动终止未知进程。服务只监听 `127.0.0.1`，任务历史保存在仓库外的 `~/.agent-subtitle-translator/visualizer`。Agent 需要观察进度时显式打开打印出的本机 URL。Agent 端同时继续输出任务创建、字幕准备、批次处理、校验、重试、降级和最终生成状态。服务不会调用翻译服务，也不要求配置 API Key；Agent 通过桥接命令上报真实执行过程：\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent 名称\" \\\n  --model \"模型名称\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# 将 batches/batch-0001.txt 完整发送给当前可用的翻译模型。\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nbridge 默认拒绝覆盖已有字幕或报告。`--output` 只能指定当前任务私有 output 目录中的文件名。需要生成另一份结果时，请传入新的文件名；明确替换同一结果时，才追加 `--overwrite`：\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\n报告位于输出字幕旁边，路径为 `<output-path>.report.json`。\n\n如果校验失败，先在 Web 任务中记录失败，再使用原始 Prompt 和校验错误重试；发送重试前运行 `retry-batch --task TASK_ID --batch 1`。只有完成规定重试且剩余问题为 ASS `S` 样式标记不匹配时，才可以使用 `--allow-style-fallback`。\n\n运行 identify 后，Web 页面会在会话行显示 Agent，并在每个任务卡片内显示该任务记录的翻译模型；下方程序元数据显示共用的程序与 Skill 版本，该版本统一从 package.json 读取。Agent 知道完整模型标识时，应将它作为 `--model` 传入，例如 `GPT-5.6 Luna Hight`；也可以通过 `--model-version`、`--model-series` 和 `--reasoning-strength` 传入 `GPT`、`5.6`、`Sol`、`high` 这类结构化信息。旧模型或其他模型缺少可选字段时，Web 页面会自动省略对应字段；Agent 无法确认的值不应自行补全。建议在每次可视化会话开始时先执行一次 identify。Web 页面只展示 Agent 创建和控制的任务。纯 CLI 流程可以不启动 Web 服务；visualizer 启用后，任务创建、校验和 compose 都应保持在 bridge 入口。\n\n## 自动发布到 ClawHub\n\n`.github/workflows/clawhub-publish.yml` 会在相关文件推送到 `main` 时自动发布本技能。它使用 ClawHub 官方可复用工作流：未变更内容会被跳过；技能有变更时会自动发布下一个 patch 版本。\n\n首次运行前，请添加名为 `CLAWHUB_TOKEN` 的仓库 Actions Secret：\n\n1. 以该技能所有者身份登录 ClawHub，在网页中创建 ClawHub API token。\n2. 在 GitHub 仓库打开 **Settings → Secrets and variables → Actions**，新建名为 `CLAWHUB_TOKEN` 的 Secret，并填入该 token。\n3. 在 Actions 页面手动运行一次 **Publish Subtitle Translator to ClawHub**，或向 `main` 推送相关改动。\n\n该 token 只会传给发布工作流，绝不能提交到仓库。\n\n## 开发与测试\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover -s tests -v\npython3 -m py_compile scripts/subtitle_tool.py tests/test_subtitle_tool.py\npython3 /path/to/skill-creator/scripts/quick_validate.py .\nnpm install\nnpm test\n```\n\nFile v1.0.7:skill-card.md\n\n## Description: <br>\nTranslates one SRT, VTT, or ASS subtitle file at a time with local timeline handling, strict ID validation, safe output composition, and an optional loopback-only visualizer. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[lumen01](https://clawhub.ai/user/lumen01) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to translate a single subtitle file while preserving timing, supported ASS structure, and validation traceability. It is useful when an agent needs deterministic subtitle parsing, batched translation prompts, response validation, and final subtitle/report generation. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill reads the selected subtitle file and writes local work, output, and report files. <br>\nMitigation: Run it only on intended subtitle files, review generated paths before sharing outputs, and use overwrite flags only when replacement is intentional. <br>\nRisk: The optional visualizer stores task history in the user's home directory, which can retain subtitle content on shared machines. <br>\nMitigation: Stop the visualizer after use and manually clear ~/.agent-subtitle-translator/visualizer when subtitle contents are sensitive. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/lumen01/skills/agent-subtitle-translator) <br>\n- [Server-resolved GitHub source](https://github.com/Lumen01/agent-subtitle-translator) <br>\n- [Artifact README](README.md) <br>\n- [Artifact skill instructions](SKILL.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, files, guidance] <br>\n**Output Format:** [Markdown progress updates plus generated subtitle and JSON report files] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Processes one selected subtitle file per run and reports validation, degradation, output path, format, encoding, entry count, and time range.] <br>\n\n## Skill Version(s): <br>\n1.0.7 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.0.7:package-lock.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"agent-subtitle-translator\",\n      \"version\": \"1.1.1\",\n      \"devDependencies\": {\n        \"@types/node\": \"^22.15.0\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.20.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz\",\n      \"integrity\": \"sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"undici-types\": \"~6.21.0\"\n      }\n    },\n    \"node_modules/typescript\": {\n      \"version\": \"5.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n      \"dev\": true,\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=14.17\"\n      }\n    },\n    \"node_modules/undici-types\": {\n      \"version\": \"6.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    }\n  }\n}\n\nFile v1.0.7:package.json\n\n{\n  \"name\": \"agent-subtitle-translator\",\n  \"version\": \"1.1.1\",\n  \"private\": true,\n  \"description\": \"Local subtitle translation workflow with an optional loopback-only visualizer for Agent runs.\",\n  \"type\": \"module\",\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc -p tsconfig.json\",\n    \"test\": \"npm run build && node --test dist/tests/*.test.js\",\n    \"visualizer:start\": \"npm run build && node dist/src/server.js\",\n    \"visualizer:bridge\": \"npm run build && node dist/src/agent-bridge.js\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.15.0\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n\nFile v1.0.7:tsconfig.json\n\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"rootDir\": \".\",\n    \"outDir\": \"dist\",\n    \"strict\": true,\n    \"noImplicitOverride\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noEmitOnError\": true,\n    \"sourceMap\": true,\n    \"skipLibCheck\": true,\n    \"lib\": [\"ES2022\", \"DOM\"]\n  },\n  \"include\": [\"src/**/*.ts\", \"web/**/*.ts\", \"tests/**/*.ts\"],\n  \"exclude\": [\"dist\", \"node_modules\"]\n}\n\nFile v1.0.7:.github/workflows/clawhub-publish.yml\n\nname: Publish Subtitle Translator to ClawHub\n\non:\n  push:\n    branches: [main]\n    paths:\n      - SKILL.md\n      - scripts/**\n      - src/**\n      - web/**\n      - requirements.txt\n      - package.json\n      - package-lock.json\n      - tsconfig.json\n      - agents/**\n      - assets/**\n      - README.md\n      - README.zh-CN.md\n      - .clawhubignore\n      - .github/workflows/clawhub-publish.yml\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  id-token: write\n\njobs:\n  publish:\n    uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v0.23.1\n    with:\n      skill_path: .\n      dry_run: false\n      ref: ${{ github.sha }}\n    secrets:\n      clawhub_token: ${{ secrets.CLAWHUB_TOKEN }}\n\nFile v1.0.7:agents/openai.yaml\n\ninterface:\n  display_name: \"Agent Subtitle Translator\"\n  short_description: \"Translate SRT, VTT, and ASS subtitles safely\"\n  icon_small: \"./assets/icon-small.png\"\n  icon_large: \"./assets/icon-large.png\"\n  brand_color: \"#FF9940\"\n  default_prompt: \"Use $agent-subtitle-translator to translate one subtitle file while preserving its timing and supported ASS structure.\"\n\nArchive v1.0.6: 23 files, 77649 bytes\n\nFiles: AGENTS.md (64b), agents/openai.yaml (367b), package-lock.json (1460b), package.json (606b), README.md (12524b), README.zh-CN.md (12178b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2513b), SKILL.md (12834b), src/agent-bridge.ts (6312b), src/common.ts (4164b), src/python-cli.ts (4121b), src/server.ts (10566b), src/task-manager.ts (25862b), tests/test_subtitle_tool.py (18431b), tests/visualizer.test.ts (24794b), tsconfig.json (455b), web/app.ts (32501b), web/icons.ts (6681b), web/index.html (8668b), web/styles.css (33572b), _meta.json (144b)\n\nFile v1.0.6:SKILL.md\n\n---\nname: agent-subtitle-translator\ndescription: Translate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer. Use when an agent needs to translate SRT, WebVTT/VTT, or ASS subtitles; preserve ASS sections, event fields, inline semantic styling, or hard line breaks; normalize VTT to SRT; detect karaoke degradation; or validate an LLM subtitle translation before writing it.\nmetadata:\n  author: \"Lumen\"\n  openclaw:\n    requires:\n      bins:\n        - node\n        - npm\n        - python3\n    homepage: \"https://github.com/Lumen01/agent-subtitle-translator\"\n---\n\n# Agent Subtitle Translator\n\nTranslate only subtitle text with an available translation model. Delegate decoding, parsing, batching, marker validation, timeline mapping, and output writing to `scripts/subtitle_tool.py`. Never send timestamps or original ASS override tags to the model.\n\n## Prerequisite\n\nRun commands from this skill directory. The script uses only the standard library for UTF inputs; legacy encodings require `charset-normalizer`:\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help\n```\n\nDo not request or configure an external LLM API key for the script. Use the translation capability already available to the executing agent.\n\n### Runtime boundary\n\n- The core workflow reads the one subtitle file selected by the user, writes its work package and final output, and never contacts a translation provider.\n- The optional visualizer is a local display service. It binds only to `127.0.0.1`, stores task history under `~/.agent-subtitle-translator/visualizer`, and accepts bridge requests only through that local service.\n- The bridge does not accept remote URLs, the service never launches a browser subprocess, and visualizer output is confined to the current task's private `output` directory.\n- The Agent or user opens the visualizer URL explicitly. The visualizer is display-only and does not receive subtitle uploads or translation controls from the browser.\n\n## Workflow\n\n### Optional Agent visualizer workflow\n\nThe deterministic CLI workflow can run without a Web service. When the Agent or user chooses to observe progress in the visualizer, complete these steps before using the bridge:\n\n1. **Check the environment.** Run from the Skill directory. Install or verify the Python dependency from `requirements.txt`, confirm Python can run `scripts/subtitle_tool.py --help`, confirm Node.js satisfies the package requirement (Node 20 or newer), install Node dependencies once with `npm install`, and run `npm run build` successfully.\n2. **Check the Web service.** Request `http://127.0.0.1:4317/api/health`. Reuse the service only when the response is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict, then record the printed URL.\n3. **Open the Web page when requested.** Navigate the selected browser to the printed local URL and report whether it loaded. Browser access is an observation step and does not grant the page task-input or translation permissions.\n4. **Run the visualizer workflow.** Run `identify`, then create the task, start batches, submit and validate responses, and compose through `visualizer:bridge`. Keep reporting each meaningful operation in the Agent response.\n\nThe commands in the sections below describe the direct deterministic CLI workflow and the safety rules implemented by the bridge. During an Agent visualizer run, use the equivalent bridge commands after the local service is healthy. Do not compose the same task and output path through both workflows.\n\n### 1. Prepare one file\n\nRequire a target BCP 47 tag. Accept an optional source tag; omit it to let the translation model detect the source language.\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n```\n\nUse `--work-dir` to choose the package location. The command otherwise creates a hidden sibling directory. Do not use `--overwrite-work` unless replacing that package is intentional.\n\nInspect the JSON report. Stop on decoding, empty-body, invalid-timeline, or structural errors. Note any out-of-order input and ASS karaoke IDs. Preparation creates:\n\n- `manifest.json`: local structure, mapping, and validation facts; do not send it to the model.\n- `batches/batch-NNNN.txt`: ready-to-send prompts containing stable IDs and text, never timelines.\n- `validated/`: destination for verified batch results.\n\nEach batch contains at most 32 entries. Do not increase that ceiling. Dispatch batches serially or concurrently using the agent's available scheduling; this skill imposes no concurrency limit.\n\n### 2. Translate batches\n\nSend each complete `batch-NNNN.txt` prompt to the translation model without rewriting its fixed instructions. Save the raw response as UTF-8 text.\n\nDo not promise cross-batch consistency for names or terminology. The prompt supplies only the local batch context.\n\n### 3. Validate every response\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n```\n\nOn any count, ID, order, wrapper, hard-break, fixed-structure, or style-marker error, resend that batch with the original prompt and the validator error as a correction request. Never fill a missing translation from a neighboring entry.\n\nIf the retried response still has a count, ID, wrapper, `BR`, or `F` mismatch, stop the entire job. Reliable timeline mapping is impossible.\n\nIf only ASS `S` style markers remain invalid after a retry, validate with `--allow-style-fallback`. This removes inline style markers only for the affected entries and records their IDs. Do not use this option before a retry.\n\n```bash\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001-retry.txt \\\n  --allow-style-fallback\n```\n\nUse `--overwrite` only to replace the prior validated JSON for that batch.\n\n### 4. Compose after all batches validate\n\n```bash\npython3 scripts/subtitle_tool.py compose --manifest /path/work/manifest.json\n```\n\nThe script merges validated data by stable subtitle ID, independent of completion order. It refuses missing, duplicate, or extra IDs and refuses to overwrite output by default. If the output already exists, choose a new `--output` path or pass `--overwrite` only when replacing that exact output is intentional.\n\nThe final report is written next to the subtitle as `<output-path>.report.json`, not at the work directory root. For example, `SPS.ja.srt` has the report `SPS.ja.srt.report.json`.\n\nRead the final report and tell the user:\n\n- output path, format, encoding, entry count, and time range;\n- count and IDs of karaoke degradations;\n- count and IDs of inline-style fallbacks.\n\n## Local visualizer workflow\n\nThe local visualizer is optional. Direct CLI-only use remains available when an Agent is invoking the deterministic tool without a visualizer session. The Web interface is display-only: it never accepts subtitle files, target languages, or translation controls. The Agent remains the only task input and execution surface.\n\nThe visualizer listens on `127.0.0.1` by default and stores task history outside the repository under `~/.agent-subtitle-translator/visualizer`.\n\nInstall the service once, then check for a reusable instance before starting it:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n# Run this only when the health check fails:\n# npm run visualizer:start\n```\n\nReuse the existing instance when `/api/health` returns HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when the visualizer is requested and skip `npm run visualizer:start`. If the health request fails or reports an incompatible version, start the service only after addressing the occupied port. If the port responds with another service, report the conflict and use a different port or resolve it deliberately; do not terminate an unknown process automatically.\n\nThe visualizer does not call a translation model and keeps the deterministic safety contract; all task inputs and real translation stages come from the Agent through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send the complete batches/batch-0001.txt prompt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to overwrite an existing subtitle or report by default. Use a new `--output` path for a separate result, or pass `--overwrite` only when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report path returned by bridge composition is `<output-path>.report.json`, alongside the generated subtitle.\n\nIf validation fails, report the failure in the Web task, retry with the original prompt and the validator error, then submit the retried response. Use `retry-batch --task TASK_ID --batch 1` before sending the retry. Use `--allow-style-fallback` only after the required retry and only when the remaining problem is an ASS `S` marker mismatch.\n\nRun identify at the beginning of the visualizer session. The session line shows the reported Agent, each task card shows the model recorded for that task, and the program metadata line separately shows the shared program and Skill version read from package.json. Pass the complete model identifier in `--model` whenever the Agent knows it, such as `GPT-5.6 Luna Hight`; pass `--model-version`, `--model-series`, and `--reasoning-strength` when those fields exist, such as `GPT` + `5.6` + `Sol` + `high`. Older or other models may omit any optional field, and the Web page omits missing fields. Never invent a version, series, or reasoning value that the Agent cannot verify. Keep reporting the same progress in the Agent response after every meaningful bridge operation.\n\nThe Web interface supports multiple Agent-created tasks at once. The left queue shows each task and its overall status; the selected task shows batch progress, per-task and per-batch duration, visible subtitle text, validation/retry/degradation warnings, and the live event stream. The interface never displays the manifest, accepts task input, or sends timestamps and raw ASS override tags to the model.\n\n### Agent-side progress output\n\nThe Agent must continue reporting progress in its own response while the Web page is open. Web events do not replace Agent output. At minimum, report:\n\n- the visualizer URL and whether it was opened in the selected browser;\n- task creation and subtitle preparation, including entry and batch counts;\n- each batch start, validation result, retry, and degradation;\n- final composition, output path, format, duration, and any warnings.\n\nKeep these updates concise and synchronized with the bridge calls so the user can follow the same run in the Agent and in the Web page.\n\n## Format behavior\n\n- Write SRT input as UTF-8-BOM SRT.\n- Normalize VTT input locally and write UTF-8-BOM SRT.\n- Keep ASS as UTF-8-BOM ASS. Preserve non-dialogue sections, styles, comments, pure drawings, event order, timestamps, Layer, Style, Name, margins, Effect, and other event fields.\n- Translate only visible ASS Dialogue text. Convert inline style scopes to paired neutral markers and `\\N`/`\\n` to movable `BR` markers, then restore validated structure.\n- Degrade karaoke entries containing `\\k`, `\\K`, `\\kf`, or `\\ko` individually to static text. Preserve the base Style/event fields and safe whole-line positioning while removing syllable timing and inapplicable animation.\n- Name default output `<stem>.<normalized-BCP47>.<ext>`, such as `movie.zh-Hans.srt` or `movie.pt-BR.ass`.\n\n## Safety invariants\n\n- Process exactly one input file per run.\n- Never expose `manifest.json`, timestamps, or raw ASS override tags to the translation model.\n- Never infer mapping from proximity, text similarity, or character positions.\n- Never silently discard marker failures or degradations.\n- Never overwrite a work package, validated result, subtitle, or report without the matching explicit overwrite flag.\n\nFile v1.0.6:README.md\n\n# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator logo\" width=\"180\">\n</p>\n\n[简体中文](README.zh-CN.md)\n\nTranslate one SRT, VTT, or ASS subtitle file with local timeline handling, strict ID validation, and safe ASS structure preservation.\n\nThis repository is a Skill first. The bundled CLI performs deterministic decoding, parsing, batching, validation, and composition; the executing Agent uses its available translation model, so the CLI needs no external LLM API key.\n\n> ⭐ If this Skill helps you, please [star the repository](https://github.com/Lumen01/agent-subtitle-translator). It helps more people discover the project and supports continued improvements.\n\n## Install the Skill\n\n### Ask an Agent to install it\n\nCopy this prompt to an Agent with terminal access:\n\n```text\nRead https://github.com/Lumen01/agent-subtitle-translator/blob/main/README.md and install the Agent Subtitle Translator Skill according to its “Install Manually” section. Before changing anything, inspect existing installations and preserve unrelated files. Unless I explicitly request one runtime only, prefer one shared multi-Agent installation under ~/.agents/skills and expose it to each requested runtime without creating conflicting copies. Install the declared Python dependency in an appropriate user or managed environment, then confirm that the runtime can discover the installed SKILL.md. Do not overwrite or delete an existing installation without first comparing it and reporting the conflict.\n```\n\n### Install manually\n\n#### Shared by multiple Agents\n\nInstall one shared copy for Codex, Claude, OpenCode, and other compatible runtimes:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\nPoint each runtime at the shared copy if it requires its own skills directory:\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\nInspect each destination first; do not replace an existing file, directory, or link blindly.\n\n#### One runtime only\n\nClone directly into that runtime's documented skills directory. For example:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\nThe installed skill root must contain a discoverable `SKILL.md`.\n\n## Prompt an Agent to use it\n\nName the skill, one input file, and the required target language. The source language is optional.\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/movie.en.srt to Simplified Chinese (zh-Hans). Keep the original timing, do not overwrite existing output, and report any degradation.\n```\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/signs.ass from English to Brazilian Portuguese (pt-BR). Preserve ASS styles and event metadata wherever safe.\n```\n\nThe Agent prepares batches of at most 32 entries, translates them using its available model, retries invalid batch structures, validates stable IDs and markers, and composes only after every batch maps safely. The Skill does not impose a concurrency cap; completed batches are merged by stable ID, not completion order.\n\n## Supported formats and output\n\n| Input | Output | Behavior |\n| --- | --- | --- |\n| SRT | SRT | Preserve timing; normalize indices and timeline order. |\n| VTT/WebVTT | SRT | Convert locally to normalized SRT. |\n| ASS | ASS | Preserve the document and event structure; replace only visible Dialogue text. |\n\nDefault output is `<stem>.<normalized-BCP47>.<ext>`, for example `movie.zh-Hans.srt` or `movie.pt-BR.ass`. Existing work directories, validated responses, subtitle outputs, and reports are not overwritten unless the corresponding explicit overwrite flag is used. SRT and ASS outputs use UTF-8 BOM.\n\nThe CLI recognizes UTF BOMs and UTF-8 directly. It uses `charset-normalizer` for common legacy encodings and stops when the result is too ambiguous to map safely. Preparation reports entry counts, time range, ordering, empty text, format conversion, and ASS-specific preservation facts.\n\n## ASS style preservation and karaoke degradation\n\nOriginal ASS tags never go to the translation model. Inline style ranges become paired neutral markers such as `⟦S1⟧...⟦/S1⟧`; the markers can move with their meaning in the target language. Hard line breaks become unique movable `BR` markers. After translation, the CLI validates marker count, identity, closure, and nesting before restoring the original tags.\n\nFor example, this source:\n\n```text\nWhat date is {\\b1\\c&H00FFFF&}today{\\r}?\n```\n\ncan safely become:\n\n```text\n{\\b1\\c&H00FFFF&}今天{\\r}是几号？\n```\n\nIf an inline-style response still cannot be restored after a retry, the Agent may explicitly downgrade only that subtitle entry to static text and must report its ID. Count, ID, wrapper, hard-break, or fixed-structure mismatches remain fatal; the Skill never borrows adjacent translations or guesses character positions.\n\nEntries containing `\\k`, `\\K`, `\\kf`, or `\\ko` karaoke timing are intentionally downgraded one entry at a time. The output keeps the event timeline, base Style, fields, and safe whole-line positioning, but removes syllable timing and no-longer-applicable character animation. This is reported as a degradation, not a translation failure. Other ordinary ASS entries in the same file retain their supported styling.\n\n## Agent execution order\n\nWhen an Agent uses this Skill, the deterministic CLI workflow may run directly. Use the following local visualizer steps only when the Agent or user wants live progress:\n\n1. Check the environment from the Skill directory: install or verify the Python dependency from `requirements.txt`, verify Python can run `scripts/subtitle_tool.py --help`, verify Node.js is 20 or newer, install Node dependencies with `npm install` when needed, and run `npm run build` successfully.\n2. Check `http://127.0.0.1:4317/api/health`. Reuse the service only when it is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict.\n3. When visual progress is requested, open the printed loopback URL in the selected browser and report whether it loaded.\n4. Run `visualizer:bridge -- identify`, then create the task, translate batches, validate responses, and compose through bridge.\n\nThe CLI block below is the deterministic core reference. Do not mix CLI composition with bridge composition for the same task and output path.\n\n## Deterministic CLI reference\n\nThe Agent normally runs these commands from the installed skill directory:\n\n```bash\npython3 scripts/subtitle_tool.py prepare /path/movie.ass --target-language zh-Hans --source-language en\n\npython3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt\n\npython3 scripts/subtitle_tool.py compose \\\n  --manifest /path/.movie.zh-Hans.subtitle-work/manifest.json\n```\n\nSee `python3 scripts/subtitle_tool.py --help` and each subcommand's `--help` for collision and retry flags. The generated batch prompts contain text and stable IDs but no timelines or raw ASS override tags.\nThe final composition report is written alongside the subtitle as `<output-path>.report.json`; for example, `SPS.ja.srt` produces `SPS.ja.srt.report.json`. If the output already exists, choose a new path or pass the explicit overwrite flag only when replacement is intentional.\n\n## Local translation visualizer\n\nThis Skill includes an optional local, display-only Web workspace. It presents the Agent-created task queue on the left and the selected task's batches, validation, retries, degradations, timing, subtitle preview, and event stream on the right. Subtitle files, target languages, and translation controls remain in the Agent; the Web page does not accept task input. The original Python CLI remains the deterministic processing core.\n\nFor an Agent visualizer run, use the bridge as the single task execution path. The direct CLI commands above remain available for CLI-only use; do not compose the same task and output path through both paths.\n\nRun or reuse the local service from the Skill directory:\n\n```bash\nnpm install\ncurl -fsS http://127.0.0.1:4317/api/health\n```\n\nReuse the instance when the health response is HTTP 200 with `status: \"ok\"`, `service: \"subtitle-visualizer\"`, and a version compatible with this Skill (`1.1.1` for this release); open its URL only when visual progress is requested and skip starting another process. If the request fails or reports an incompatible version, address the occupied port before starting the current release. If the port is occupied by another service, report the conflict and choose a different port or resolve it deliberately. The service binds only to `127.0.0.1` and persists local task history under `~/.agent-subtitle-translator/visualizer`. The Agent opens the printed URL explicitly when needed. The Agent continues reporting the same task progress in its own response. The visualizer does not call a translation provider or require an API key. The Agent sends real execution updates through the bridge:\n\n```bash\nnpm run visualizer:bridge -- identify \\\n  --agent \"Agent name\" \\\n  --model \"Model name\" \\\n  --model-version \"5.6\" \\\n  --model-series \"Sol\" \\\n  --reasoning-strength \"high\"\n\nnpm run visualizer:bridge -- create \\\n  --input ~/Movies/movie.en.srt \\\n  --target-language zh-Hans\n\nnpm run visualizer:bridge -- batch-start --task TASK_ID --batch 1\n# Send batches/batch-0001.txt to the available translation model.\nnpm run visualizer:bridge -- submit-response \\\n  --task TASK_ID \\\n  --batch 1 \\\n  --response /tmp/batch-0001.txt\n\nnpm run visualizer:bridge -- compose --task TASK_ID\n```\n\nBridge composition refuses to replace an existing subtitle or report by default. The bridge accepts `--output` only as a filename inside the current task's private output directory. Use a fresh filename for a separate result, or add `--overwrite` when intentionally replacing the exact existing pair:\n\n```bash\nnpm run visualizer:bridge -- compose --task TASK_ID --overwrite\n```\n\nThe report is stored beside the output as `<output-path>.report.json`.\n\nThe Web page displays the reported Agent in the session line, records the reported model on each task card, and separately displays the shared program and Skill version from package.json. Pass the complete model identifier in `--model` whenever it is known, such as `GPT-5.6 Luna Hight`. `--model-version`, `--model-series`, and `--reasoning-strength` are optional, so older or other models can omit them and the Web page leaves those fields out. Do not invent values that the Agent cannot verify. Run identify at the beginning of each visualizer session. The Web page only displays tasks created and controlled by the Agent. Direct CLI-only workflows can run without the Web service; when the visualizer is active, keep task creation, validation, and composition on the bridge path.\n\n## Automatic ClawHub Publishing\n\nThe GitHub Actions workflow at `.github/workflows/clawhub-publish.yml` publishes\nthis skill whenever relevant files are pushed to `main`. It uses ClawHub's\nofficial reusable workflow, which skips unchanged content and automatically\ncreates the next patch version when the skill changed.\n\nBefore the first run, add a repository Actions secret named `CLAWHUB_TOKEN`:\n\n1. Create a ClawHub API token from the ClawHub web UI while signed in as the\n   owner of this skill.\n2. In GitHub, open **Settings → Secrets and variables → Actions** for this\n   repository and create the `CLAWHUB_TOKEN` secret with that value.\n3. Run **Publish Subtitle Translator to ClawHub** once from the Actions tab, or\n   push a relevant change to `main`.\n\nThe token is only passed to the publishing workflow and must never be committed\nto this repository.\n\n## Develop and test\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 -m unittest discover \n\nArchive v1.0.5: 23 files, 77542 bytes\n\nFiles: AGENTS.md (64b), agents/openai.yaml (367b), package-lock.json (1460b), package.json (661b), README.md (12943b), README.zh-CN.md (12612b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2467b), SKILL.md (13300b), src/agent-bridge.ts (5897b), src/common.ts (4164b), src/python-cli.ts (4121b), src/server.ts (11316b), src/task-manager.ts (24912b), tests/test_subtitle_tool.py (18431b), tests/visualizer.test.ts (22772b), tsconfig.json (455b), web/app.ts (32501b), web/icons.ts (6681b), web/index.html (8668b), web/styles.css (33572b), _meta.json (144b)\n\nArchive v1.0.4: 24 files, 572366 bytes\n\nFiles: .clawhubignore (186b), .github (0b), .github/workflows (0b), .github/workflows/clawhub-publish.yml (600b), agents (0b), AGENTS.md (64b), agents/openai.yaml (367b), assets (0b), assets/icon-large.png (271934b), assets/icon-small.png (271934b), README.md (7579b), README.zh-CN.md (7094b), requirements.txt (27b), scripts (0b), scripts/subtitle_tool.py (43893b), SKILL.md (5350b), tests (0b), tests/fixtures (0b), tests/fixtures/basic.srt (91b), tests/fixtures/basic.vtt (101b), tests/fixtures/karaoke.ass (626b), tests/fixtures/styled.ass (969b), tests/test_subtitle_tool.py (18431b), _meta.json (144b)\n\nArchive v1.0.3: 10 files, 28065 bytes\n\nFiles: AGENTS.md (64b), agents/openai.yaml (367b), README.md (7579b), README.zh-CN.md (7094b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2355b), SKILL.md (5350b), tests/test_subtitle_tool.py (18431b), _meta.json (144b)\n\nArchive v1.0.2: 23 files, 40056 bytes\n\nFiles: .clawhubignore (186b), .github (0b), .github/workflows (0b), .github/workflows/clawhub-publish.yml (600b), agents (0b), agents/openai.yaml (367b), assets (0b), assets/icon-large.svg (982b), assets/icon-small.png (9492b), README.md (7579b), README.zh-CN.md (7094b), requirements.txt (27b), scripts (0b), scripts/subtitle_tool.py (43893b), SKILL.md (5350b), tests (0b), tests/fixtures (0b), tests/fixtures/basic.srt (91b), tests/fixtures/basic.vtt (101b), tests/fixtures/karaoke.ass (626b), tests/fixtures/styled.ass (969b), tests/test_subtitle_tool.py (18431b), _meta.json (144b)\n\nArchive v1.0.1: 10 files, 28662 bytes\n\nFiles: agents/openai.yaml (367b), assets/icon-large.svg (982b), README.md (7579b), README.zh-CN.md (7094b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2672b), SKILL.md (5350b), tests/test_subtitle_tool.py (18431b), _meta.json (144b)\n\nArchive v1.0.0: 10 files, 28523 bytes\n\nFiles: agents/openai.yaml (367b), assets/icon-large.svg (982b), README.md (7469b), README.zh-CN.md (6984b), requirements.txt (27b), scripts/subtitle_tool.py (43893b), skill-card.md (2633b), SKILL.md (5350b), tests/test_subtitle_tool.py (18431b), _meta.json (144b)","readmeExcerpt":"Skill: Agent Subtitle Translator Owner: lumen01 Summary: Translate SRT, VTT, and ASS subtitles safely Tags: latest:1.0.9 Version history: v1.0.9 | 2026-09-04T10:42:18.665Z | auto - Added full project structure including scripts, assets, web UI, agents, and tests directories - Integrated optional local loopback-only visualizer with secure, display-only web interface - Introduced fixtures and validation tests for SRT, ","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"python3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help"},{"language":"bash","snippet":"python3 scripts/subtitle_tool.py prepare /path/movie.ass \\\n  --target-language zh-Hans \\\n  --source-language en"},{"language":"bash","snippet":"python3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001.txt"},{"language":"bash","snippet":"python3 scripts/subtitle_tool.py validate-response \\\n  --manifest /path/work/manifest.json \\\n  --batch 1 \\\n  --response /path/responses/batch-0001-retry.txt \\\n  --allow-style-fallback"},{"language":"bash","snippet":"python3 scripts/subtitle_tool.py compose --manifest /path/work/manifest.json"},{"language":"bash","snippet":"curl -fsS http://127.0.0.1:4317/api/health"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: agent-subtitle-translator\ndescription: Translate one subtitle file at a time with deterministic local parsing, timeline preservation, strict batch mapping, safe output composition, and an optional loopback-only visualizer. Use when an agent needs to translate SRT, WebVTT/VTT, or ASS subtitles; preserve ASS sections, event fields, inline semantic styling, or hard line breaks; normalize VTT to SRT; detect karaoke degradation; or validate an LLM subtitle translation before writing it.\nmetadata:\n  author: \"Lumen\"\n  openclaw:\n    requires:\n      bins:\n        - node\n        - npm\n        - python3\n    homepage: \"https://github.com/Lumen01/agent-subtitle-translator\"\n---\n\n# Agent Subtitle Translator\n\nTranslate only subtitle text with an available translation model. Delegate decoding, parsing, batching, marker validation, timeline mapping, and output writing to `scripts/subtitle_tool.py`. Never send timestamps or original ASS override tags to the model.\n\n## Prerequisite\n\nRun commands from this skill directory. The script uses only the standard library for UTF inputs; legacy encodings require `charset-normalizer`:\n\n```bash\npython3 -m pip install -r requirements.txt\npython3 scripts/subtitle_tool.py --help\n```\n\nDo not request or configure an external LLM API key for the script. Use the translation capability already available to the executing agent.\n\n### Runtime boundary\n\n- The core workflow reads the one subtitle file selected by the user, writes its work package and final output, and never contacts a translation provider.\n- The optional visualizer is a local display service. It binds only to `127.0.0.1`, stores task history under `~/.agent-subtitle-translator/visualizer`, and accepts bridge requests only through that local service.\n- The bridge does not accept remote URLs, the service never launches a browser subprocess, and visualizer output is confined to the current task's private `output` directory.\n- The Agent or user opens the visualizer URL explicitly. The visualizer is display-only and does not receive subtitle uploads or translation controls from the browser.\n\n## Workflow\n\n### Optional Agent visualizer workflow\n\nThe deterministic CLI workflow can run without a Web service. When the Agent or user chooses to observe progress in the visualizer, complete these steps before using the bridge:\n\n1. **Check the environment.** Run from the Skill directory. Install or verify the Python dependency from `requirements.txt`, confirm Python can run `scripts/subtitle_tool.py --help`, confirm Node.js satisfies the package requirement (Node 20 or newer), install Node dependencies once with `npm install`, and run `npm run build` successfully.\n2. **Check the Web service.** Request `http://127.0.0.1:4317/api/health`. Reuse the service only when the response is healthy, identifies `subtitle-visualizer`, and reports a compatible Skill version. Otherwise start the service after resolving any occupied-port conflict, then record the printed URL.\n3. **Open the Web"},{"path":"README.md","content":"# Agent Subtitle Translator Skill\n\n<p align=\"center\">\n  <img src=\"assets/icon-large.png\" alt=\"Agent Subtitle Translator logo\" width=\"180\">\n</p>\n\n[简体中文](README.zh-CN.md)\n\nTranslate one SRT, VTT, or ASS subtitle file with local timeline handling, strict ID validation, and safe ASS structure preservation.\n\nThis repository is a Skill first. The bundled CLI performs deterministic decoding, parsing, batching, validation, and composition; the executing Agent uses its available translation model, so the CLI needs no external LLM API key.\n\n> ⭐ If this Skill helps you, please [star the repository](https://github.com/Lumen01/agent-subtitle-translator). It helps more people discover the project and supports continued improvements.\n\n## Install the Skill\n\n### Ask an Agent to install it\n\nCopy this prompt to an Agent with terminal access:\n\n```text\nInstall this Skill following the instructions at https://github.com/Lumen01/agent-subtitle-translator and confirm that the current Agent can use it. If it conflicts with an existing installation, let me know before proceeding.\n```\n\n### Install manually\n\n#### Shared by multiple Agents\n\nInstall one shared copy for Codex, Claude, OpenCode, and other compatible runtimes:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.agents/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.agents/skills/agent-subtitle-translator/requirements.txt\n```\n\nPoint each runtime at the shared copy if it requires its own skills directory:\n\n```bash\nmkdir -p ~/.codex/skills ~/.claude/skills\nln -s ~/.agents/skills/agent-subtitle-translator ~/.codex/skills/agent-subtitle-translator\nln -s ~/.agents/skills/agent-subtitle-translator ~/.claude/skills/agent-subtitle-translator\n```\n\nInspect each destination first; do not replace an existing file, directory, or link blindly.\n\n#### One runtime only\n\nClone directly into that runtime's documented skills directory. For example:\n\n```bash\ngit clone https://github.com/Lumen01/agent-subtitle-translator.git ~/.codex/skills/agent-subtitle-translator\npython3 -m pip install --user -r ~/.codex/skills/agent-subtitle-translator/requirements.txt\n```\n\nThe installed skill root must contain a discoverable `SKILL.md`.\n\n## Prompt an Agent to use it\n\nName the skill, one input file, and the required target language. The source language is optional.\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/movie.en.srt to Simplified Chinese (zh-Hans). Keep the original timing, do not overwrite existing output, and report any degradation.\n```\n\n```text\nUse $agent-subtitle-translator to translate ~/Movies/signs.ass from English to Brazilian Portuguese (pt-BR). Preserve ASS styles and event metadata wherever safe.\n```\n\nThe Agent prepares batches of at most 32 entries, translates them using its available model, retries invalid batch structures, validates stable IDs and markers, and composes only after every batch maps safely. The Skill does not impose a concurrency cap; completed batch"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn78ge2mfb4vyz0qn9xpnne8v58a732j\",\n  \"slug\": \"agent-subtitle-translator\",\n  \"version\": \"1.0.9\",\n  \"publishedAt\": 1788518538665\n}"},{"path":".impeccable.md","content":"## Design Context\n\n### Users\n\n普通用户通过 Agent 同时发起一个或多个字幕翻译任务。他们希望不用理解命令行、批次文件或内部实现，也能看到每个任务当前进展、翻译耗时、校验结果、重试原因、降级提示和最终输出。\n\n### Brand Personality\n\n清晰、可靠、从容。界面要让用户始终知道系统正在做什么、已经完成什么，以及是否需要关注某个问题。\n\n### Aesthetic Direction\n\n面向普通用户的翻译工作台：左侧是可切换的任务队列，右侧是选中任务的过程详情。提供深色与浅色主题切换，使用明确的状态色、时间信息和事件流形成可读的过程叙事。动效用于表达任务状态变化、批次推进和结果完成，按当前需求保持开启，不提供减弱动效设置。\n\n### Design Principles\n\n1. 先让用户看懂任务全局，再逐步展开批次和单条字幕细节。\n2. 每个状态都给出可读的中文说明、时间和下一步结果。\n3. 错误、重试和降级需要显眼且可追溯，不能被装饰性视觉弱化。\n4. 多任务并行时保持左侧列表稳定，右侧详情切换不打断后台任务。\n5. 视觉风格应具备工具感和秩序感，同时保持普通用户可理解的语言与操作。"},{"path":"AGENTS.md","content":"# Repository Instructions\n\n- 在 `dev` 分支中研发迭代。"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Translate SRT, VTT, and ASS subtitles safely Skill: Agent Subtitle Translator Owner: lumen01 Summary: Translate SRT, VTT, and ASS subtitles safely Tags: latest:1.0.9 Version history: v1.0.9 | 2026-09-04T10:42:18.665Z | auto - Added full project structure including scripts, assets, web UI, agents, and tests directories - Integrated optional local loopback-only visualizer with secure, display-only web interface - Introduced fixtures and validation tests for SRT,","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1616,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T21:43:21.251Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:40:20.446Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}