### Canned LLM Response for wiki-edo-lead-slot-dup
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md
Example of a canned LLM response for the 'wiki-edo-lead-slot-dup' test case, preserving slot 11 duplication. This response is derived from console logs or manual reproduction, not a live LLM call.
```text
⟦0⟧江戶⟦/0⟧(⟦1⟧日語⟦/1⟧:⟦2⟧...⟦/2⟧...)是⟦11⟧現今日本首都⟦/11⟧⟦12⟧東京⟦/12⟧的⟦11⟧舊稱⟦/11⟧。⟦*13⟧
```
--------------------------------
### Get Shinkansen Settings
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Reads user-customized settings combined with defaults. API Key is fetched from local storage.
```javascript
import { getSettings } from './lib/storage.js';
const settings = await getSettings();
```
--------------------------------
### Example HTML Structure for gmail-button-nested-a
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md
Simplified and sanitized HTML structure for the 'gmail-button-nested-a' test case. Note the specific styling on the TD and A elements, and the lack of styling on the SPAN.
```html
Learn more
|
```
--------------------------------
### Preset Shortcuts (v1.4.12)
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Information about preset shortcuts for translation, including manifest commands, storage schema, and behavior.
```APIDOC
## Preset Shortcuts (v1.4.12)
### Description
Provides functionality for setting and managing translation presets using keyboard shortcuts.
### Manifest Commands
- `translate-preset-1` (Alt+A): Preset Flash
- `translate-preset-2` (Alt+S): Preset Flash Lite
- `translate-preset-3` (Alt+D): Preset Google MT
### Storage Schema
`translatePresets: [{ slot, engine, model, label }]`
Three default presets are built into `lib/storage.js` `DEFAULT_SETTINGS`.
### Behavior
- **Idle State**: Pressing any preset key initiates translation using the `engine` + `model` of the corresponding slot.
- **Translating**: Pressing any preset key aborts the current translation.
- **Translation Complete**: Pressing any preset key restores the page (`restorePage`), regardless of the slot.
### Model Override
`content.js` `SK.translateUnits` passes the slot's model to `TRANSLATE_BATCH` payload.modelOverride. `background.js` `handleTranslate` uses `geminiOverrides.model` to override `geminiConfig.model`, differentiating cache partitions with the `cacheTag` parameter.
### Future Options UI (v1.4.13)
Planned UI for editing engine, model, and label. For v1.4.12, users can temporarily modify presets directly via `chrome.storage.sync.translatePresets`.
```
--------------------------------
### Get State Function for Debug API
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Returns a snapshot of the current translation state. This is a read-only method provided by the debug API.
```javascript
getState(): Object
```
--------------------------------
### Set Shinkansen Settings
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Writes settings, with API Key automatically saved to local storage and other settings to sync storage. Allows partial updates.
```javascript
import { setSettings } from './lib/storage.js';
// 更新部分設定
await setSettings({
apiKey: 'NEW_API_KEY',
geminiConfig: {
model: 'gemini-3.1-flash-lite-preview',
temperature: 0.8
},
ytSubtitle: {
autoTranslate: false
}
});
```
--------------------------------
### Importing ES Modules with fetch Mock for Google Translate Batch
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This test demonstrates importing ES modules directly using `await import()` and mocking `globalThis.fetch`. It's used to test the Google Translate batch functionality, including URL chunking and handling of multiple result batches.
```javascript
mock `globalThis.fetch` 直接 import ES module;驗證 SEP 串接、URL 長度分塊、空陣列、多批次 result 依 idx 寫回
```
--------------------------------
### Get Cache Statistics
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Retrieve statistics about the current cache status using cache.stats. This includes the number of entries and total size in bytes for both translation cache and glossary cache.
```javascript
import * as cache from './lib/cache.js';
const stats = await cache.stats();
// {
// count: 1250, // 翻譯快取條目數
// bytes: 2500000, // 翻譯快取大小(bytes)
// glossaryCount: 15, // 術語表快取條目數
// glossaryBytes: 50000 // 術語表快取大小(bytes)
// }
```
--------------------------------
### Popup/Options Script to Background Script Message: QUERY_USAGE
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Retrieves detailed usage records for display in a table on the options page. The response includes an array of usage records.
```javascript
QUERY_USAGE
{ ok, records }
```
--------------------------------
### Start YouTube Subtitle Translation
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Automatically intercepts YouTube subtitle data, translates it in batches based on time windows, and replaces the displayed subtitles in real-time. Also provides access to translation status via SK.YT.
```javascript
const SK = window.__SK;
// 啟動 YouTube 字幕翻譯
await SK.translateYouTubeSubtitles();
```
```javascript
// 存取字幕翻譯狀態
const YT = SK.YT;
console.log({
active: YT.active,
rawSegments: YT.rawSegments,
captionMap: YT.captionMap,
translatedUpToMs: YT.translatedUpToMs
});
```
--------------------------------
### Popup/Options Script to Background Script Message: QUERY_USAGE_CHART
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Requests data formatted for a usage statistics chart in the options page. The response provides the chart data.
```javascript
QUERY_USAGE_CHART
{ ok, data }
```
--------------------------------
### Popup/Options Script to Background Script Message: USAGE_STATS
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Requests cumulative usage statistics, including total input tokens, output tokens, cost in USD, and the time period since the last reset. Used for display in the popup.
```javascript
USAGE_STATS
{ ok, totalInputTokens, totalOutputTokens, totalCostUSD, since }
```
--------------------------------
### Popup/Options Script to Background Script Message: QUERY_USAGE_STATS
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Queries aggregated usage statistics for display in the options page. The response contains the statistics object.
```javascript
QUERY_USAGE_STATS
{ ok, stats }
```
--------------------------------
### Default System Prompt Structure for Gemini
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
The default system prompt is defined in lib/storage.js. It uses XML tags to define the translator's role, critical rules, linguistic guidelines, and formatting preferences. This prompt is dynamically augmented based on the content being translated.
```JavaScript
const DEFAULT_SYSTEM_PROMPT = `
定位為「精通英美流行文化與台灣在地文學的首席翻譯專家」,追求出版級台灣當代語感
禁止輸出思考過程、忠實保留不雅詞彙(不做道德審查)、專有名詞保留英文原文(地理位置例外,須翻為台灣標準譯名)
台灣道地語感(拒絕翻譯腔)、禁用中國大陸用語(附具體對照表)、台灣通行譯名、特殊詞彙首次出現加註原文
全形標點、破折號改寫、中英夾雜半形空格、數字格式(1–99 中文數字、100 以上阿拉伯數字)、年份格式
`;
```
--------------------------------
### Add testInject Helper to Shinkansen
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md
This helper function is to be added to the window.__shinkansen object in content.js. It serializes an element, injects a translation, and returns source text and slot count. Use this for testing the serialize -> inject path without network latency.
```javascript
testInject(el, translation) {
const { text, slots } = serializeWithPlaceholders(el);
const unit = { kind: 'element', el };
injectTranslation(unit, translation, slots);
return { sourceText: text, slotCount: slots.length };
}
```
--------------------------------
### Popup/Options Script to Background Script Message: CLEAR_USAGE
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Instructs the background script to clear all recorded usage data. The background script confirms the operation.
```javascript
CLEAR_USAGE
{ ok }
```
--------------------------------
### Popup/Options Script to Background Script Message: RESET_USAGE
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Resets the cumulative usage statistics. The response includes the reset statistics.
```javascript
RESET_USAGE
{ ok, totalInputTokens, totalOutputTokens, totalCostUSD, since }
```
--------------------------------
### Rate Limiter Implementation Details
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
The rate limiter uses a three-dimensional sliding window for RPM, TPM, and RPD. It persists RPD data in chrome.storage.local and applies a safety margin to limits. Error handling for 429 responses includes respecting the Retry-After header and exponential backoff.
```JavaScript
// RPM: 60-second sliding window using a circular buffer of timestamps
// TPM: 60-second sliding window using token estimation (Math.ceil(text.length / 3.5))
// RPD: Resets at Pacific midnight, persisted in chrome.storage.local (key rateLimit_rpd_)
// Safety Margin: Each limit multiplied by (1 - safetyMargin), default 10%
// 429 Handling: Respect Retry-After header, otherwise exponential backoff (2^n * 500ms, max 8s). RPD exceeded means no retry.
```
--------------------------------
### Settings Management API
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
APIs for reading and writing user settings, including API keys and translation configurations.
```APIDOC
## GET /settings
### Description
Reads the complete settings by merging default and user-customized settings. The API Key is read from local storage and is not synced via Google accounts.
### Method
GET
### Endpoint
/settings
### Response
#### Success Response (200)
- **apiKey** (string) - The API key.
- **geminiConfig** (object) - Configuration for Gemini models.
- **model** (string) - The Gemini model to use.
- **serviceTier** (string) - The service tier for the model.
- **temperature** (number) - The temperature setting for the model.
- **maxOutputTokens** (number) - Maximum output tokens.
- **systemInstruction** (string) - System instructions for the model.
- **pricing** (object) - Pricing information.
- **inputPerMTok** (number) - Cost per million input tokens.
- **outputPerMTok** (number) - Cost per million output tokens.
- **tier** (string) - The service tier.
- **ytSubtitle** (object) - YouTube subtitle settings.
- **autoTranslate** (boolean) - Whether to auto-translate subtitles.
- **engine** (string) - The translation engine for subtitles.
- **windowSizeS** (number) - The time window size in seconds for subtitle processing.
- **lookaheadS** (number) - The lookahead time in seconds for subtitle processing.
- **translatePresets** (array) - Presets for translation.
- **slot** (number) - The slot number for the preset.
- **engine** (string) - The translation engine for the preset.
- **model** (string) - The model used in the preset.
- **label** (string) - A label for the preset.
- **glossary** (object) - Glossary settings.
- **enabled** (boolean) - Whether the glossary is enabled.
- **skipThreshold** (number) - Threshold for skipping glossary entries.
- **blockingThreshold** (number) - Threshold for blocking glossary entries.
- **fixedGlossary** (object) - Fixed glossary settings.
- **global** (array) - Global glossary entries.
- **byDomain** (object) - Domain-specific glossary entries.
### Response Example
```json
{
"apiKey": "AIza...",
"geminiConfig": {
"model": "gemini-3-flash-preview",
"serviceTier": "DEFAULT",
"temperature": 1.0,
"maxOutputTokens": 8192,
"systemInstruction": "你是一位精通..."
},
"pricing": {
"inputPerMTok": 0.50,
"outputPerMTok": 3.00
},
"tier": "tier1",
"ytSubtitle": {
"autoTranslate": true,
"engine": "gemini",
"windowSizeS": 30,
"lookaheadS": 10
},
"translatePresets": [
{ "slot": 1, "engine": "gemini", "model": "gemini-3.1-flash-lite-preview", "label": "Flash Lite" },
{ "slot": 2, "engine": "gemini", "model": "gemini-3-flash-preview", "label": "Flash" },
{ "slot": 3, "engine": "google", "model": null, "label": "Google MT" }
],
"glossary": {
"enabled": false,
"skipThreshold": 1,
"blockingThreshold": 5
},
"fixedGlossary": {
"global": [],
"byDomain": {}
}
}
```
## POST /settings
### Description
Writes settings. The API Key is automatically written to local storage, and other settings are written to sync storage.
### Method
POST
### Endpoint
/settings
### Request Body
- **apiKey** (string) - Optional - The API key to set.
- **geminiConfig** (object) - Optional - Configuration for Gemini models.
- **model** (string) - Optional - The Gemini model to use.
- **temperature** (number) - Optional - The temperature setting for the model.
- **ytSubtitle** (object) - Optional - YouTube subtitle settings.
- **autoTranslate** (boolean) - Optional - Whether to auto-translate subtitles.
### Request Example
```json
{
"apiKey": "NEW_API_KEY",
"geminiConfig": {
"model": "gemini-3.1-flash-lite-preview",
"temperature": 0.8
},
"ytSubtitle": {
"autoTranslate": false
}
}
```
```
--------------------------------
### Popup/Options Script to Background Script Message: EXPORT_USAGE_CSV
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Requests the export of usage statistics in CSV format from the options page. The background script returns the CSV data.
```javascript
EXPORT_USAGE_CSV
{ ok, csv }
```
--------------------------------
### Core Message API - TRANSLATE_BATCH_GOOGLE
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Translates text segments in batches using the free, unofficial Google Translate endpoint. This method does not require an API key, bypasses rate limits, and incurs no cost, making it suitable for understanding content where perfect translation is not critical.
```APIDOC
## POST /api/translate/batch/google
### Description
Translates text segments in batches using the free, unofficial Google Translate endpoint. This method does not require an API key, bypasses rate limits, and incurs no cost, making it suitable for understanding content where perfect translation is not critical.
### Method
POST
### Endpoint
/api/translate/batch/google
### Parameters
#### Request Body
- **type** (string) - Required - Message type, should be 'TRANSLATE_BATCH_GOOGLE'
- **payload** (object) - Required - Payload for the translation request
- **texts** (array of strings) - Required - The text segments to translate
### Request Example
```json
{
"type": "TRANSLATE_BATCH_GOOGLE",
"payload": {
"texts": ["Breaking news today", "Weather forecast for tomorrow"]
}
}
```
### Response
#### Success Response (200)
- **ok** (boolean) - Indicates if the operation was successful
- **result** (array of strings) - The translated text segments
- **usage** (object) - Statistics about the API usage
- **engine** (string) - The translation engine used ('google')
- **chars** (integer) - The number of characters translated
- **cacheHits** (integer) - Number of local cache hits
#### Response Example
```json
{
"ok": true,
"result": ["今日重大新聞", "明天天氣預報"],
"usage": {
"engine": "google",
"chars": 42,
"cacheHits": 0
}
}
```
```
--------------------------------
### Popup Panel Specification
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Details the layout and functionality of the main popup panel.
```APIDOC
## 13. Popup Panel Specification
### 13.1 Layout
- Header: emoji 🚄 + Name "Shinkansen" + Version (dynamic)
- Main Button: "Translate Page" / "Show Original" (toggles based on `GET_STATE`)
- Edit Translation Button: (hidden by default, shown after translation; toggles `TOGGLE_EDIT_MODE`)
- Whitelist Auto-Translate Toggle
- Glossary Consistency Toggle
- YouTube Subtitle Translation Toggle (only on YouTube video pages)
- Cache Statistics (count / size) + Clear Cache Button
- Cumulative Cost / Token Display (read via `USAGE_STATS` message; reset function in options page)
- Status Bar: ("Status: Ready" / "Status: Translating..." / error messages, etc.)
- Footer: Settings Button (opens options page) + Shortcut Hint (dynamic, reads `chrome.commands`)
### 13.2 Version Display
**Must** be dynamically read via `chrome.runtime.getManifest().version`, not hardcoded.
```
--------------------------------
### Implement Pure Google Docs URL Parsing Test
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This test case focuses on the URL parsing logic for pure Google Docs links. It notes that cross-tab redirection flows are not covered and will require future end-to-end testing.
```javascript
test/regression/pure-gdoc-url.spec.js
```
--------------------------------
### Implement Detect Navigation Anchor Threshold Test
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This test case is designed to verify the detection of navigation anchors based on a specific threshold. It ensures that navigation elements are correctly identified under defined conditions.
```javascript
test/regression/detect-nav-anchor-threshold.spec.js
```
--------------------------------
### Access Debugging Interface via window.__shinkansen
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Utilize the global `window.__shinkansen` object in the browser console for debugging purposes. It provides methods to inspect version, state, collect data, and test specific functionalities.
```javascript
// 在瀏覽器 console 中使用
const api = window.__shinkansen;
```
```javascript
// 查看版本
api.version; // '1.4.22'
```
```javascript
// 查看翻譯狀態
api.getState();
// { translated: true, translating: false, stickyTranslate: true,
// replacedCount: 45, cacheSize: 100, guardCacheSize: 45 }
```
```javascript
// 收集段落(除錯用)
api.collectParagraphs();
```
```javascript
// 帶統計資訊
api.collectParagraphsWithStats();
// { units: [...], skipStats: { notBlockTag: 5, ... } }
```
```javascript
// 測試序列化
const el = document.querySelector('p');
api.serialize(el); // { text: '...', slots: [...] }
```
```javascript
// 測試注入
api.testInject(el, '測試翻譯');
```
```javascript
// 測試 Google Docs URL 判斷
api.testGoogleDocsUrl('https://docs.google.com/document/d/xxx/edit');
// { isEditor: true, isMobileBasic: false, mobileBasicUrl: '...mobilebasic' }
```
--------------------------------
### JavaScript for Dynamic Version Display
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Demonstrates how to dynamically read the extension's version number using the chrome.runtime.getManifest().version API. This ensures the version displayed is always up-to-date.
```javascript
chrome.runtime.getManifest().version
```
--------------------------------
### Default Settings Structure for Shinkansen
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
This JSON object defines the default configuration settings for the Shinkansen extension, including API parameters, glossary settings, domain rules, and UI preferences. These settings are managed via chrome.storage.sync.
```json
{
"geminiConfig": {
"model": "gemini-3-flash-preview",
"serviceTier": "DEFAULT",
"temperature": 1.0,
"topP": 0.95,
"topK": 40,
"maxOutputTokens": 8192,
"systemInstruction": "(見 §3.3 DEFAULT_SYSTEM_PROMPT)"
},
"pricing": { "inputPerMTok": 0.50, "outputPerMTok": 3.00 },
"glossary": {
"enabled": false,
"prompt": "(見 DEFAULT_GLOSSARY_PROMPT)",
"temperature": 0.1,
"skipThreshold": 1,
"blockingThreshold": 5,
"timeoutMs": 60000,
"maxTerms": 200
},
"domainRules": { "whitelist": [] },
"autoTranslate": false,
"debugLog": false,
"tier": "tier1",
"safetyMargin": 0.1,
"maxRetries": 3,
"rpmOverride": null,
"tpmOverride": null,
"rpdOverride": null,
"maxConcurrentBatches": 10,
"maxUnitsPerBatch": 12,
"maxCharsPerBatch": 3500,
"maxTranslateUnits": 1000,
"toastOpacity": 0.7,
"toastAutoHide": true,
"skipTraditionalChinesePage": true,
"ytSubtitle": {
"autoTranslate": true,
"temperature": 0.1,
"systemPrompt": "(見 DEFAULT_SUBTITLE_SYSTEM_PROMPT)",
"windowSizeS": 30,
"lookaheadS": 10,
"debugToast": false,
"onTheFly": false,
"model": "",
"pricing": null
}
}
```
--------------------------------
### Expose testInject API in content.js
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md
Adds a `testInject` function to the `window.__shinkansen` object for testing purposes. This function performs a full 'serialize + mock LLM response + inject' flow on a specified element without network calls. It requires the element to be a valid DOM Element.
```javascript
// 測試專用:對指定 element 跑一次完整的「serialize + 假 LLM 回應 + inject」
// 流程,回傳統計資訊。測試斷言對象是注入後的 DOM(element 本身)。
// 不觸發任何網路呼叫。
testInject(el, translation) {
if (!el || el.nodeType !== Node.ELEMENT_NODE) {
throw new Error('testInject: el must be an Element');
}
const { text, slots } = serializeWithPlaceholders(el);
const unit = { kind: 'element', el };
injectTranslation(unit, translation, slots);
return { sourceText: text, slotCount: slots.length };
}
```
--------------------------------
### Background/Popup Script to Content Script Message: TRANSLATE_PRESET
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Triggers translation using a specific preset slot (1, 2, or 3) in the content script. Handles restoring the page or aborting translation based on the current state.
```javascript
TRANSLATE_PRESET
v1.4.12:依 payload.slot(1/2/3)觸發對應 preset 翻譯;已翻譯時任一 slot 皆 restorePage;翻譯中任一 slot 皆 abort
```
--------------------------------
### Expose selectBestSlotOccurrences API in content.js
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md
Exposes the `selectBestSlotOccurrences` function for pure function testing within Category C. This allows testing the slot selection logic in isolation.
```javascript
// 測試專用:暴露 selectBestSlotOccurrences 給 Category C 純函式測試。
selectBestSlotOccurrences(text) {
return selectBestSlotOccurrences(text);
}
```
--------------------------------
### Content Script to Background Script Message: LOG_USAGE
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Logs usage statistics, such as input and output tokens, from the content script to the background script. The background script confirms receipt with an 'ok' status.
```javascript
LOG_USAGE
{ inputTokens, outputTokens, … }
{ ok }
```
--------------------------------
### Content Script to Background Script Message: STICKY_QUERY
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Queries the background script about the sticky translation status of the current tab. The response indicates whether translation should occur and the associated slot.
```javascript
STICKY_QUERY
—
{ ok, shouldTranslate, slot }
```
--------------------------------
### Content Script to Background Script Message: STICKY_SET
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Sets the current tab as sticky with a specific slot number after a successful translation. The background script confirms the operation.
```javascript
STICKY_SET
{ slot: number }
{ ok }
```
--------------------------------
### Test Preset Hotkey Behavior
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This regression test suite covers the behavior of preset hotkeys in the application, ensuring correct functionality across different states (idle, translated, translating) and slots. It uses direct function calls and stubbed methods for testing.
```javascript
test/regression/preset-hotkey-behavior.spec.js
```
--------------------------------
### Background/Popup Script to Content Script Message: GET_STATE
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Requests the current translation state from the content script. Used to determine the appropriate action for UI elements like buttons.
```javascript
GET_STATE
查詢翻譯狀態
```
--------------------------------
### Core Message API - TRANSLATE_SUBTITLE_BATCH
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Dedicated endpoint for translating YouTube subtitles. It utilizes a separate system prompt optimized for conversational language and specific temperature settings, supporting independent model and pricing configurations.
```APIDOC
## POST /api/translate/subtitle/batch
### Description
Dedicated endpoint for translating YouTube subtitles. It utilizes a separate system prompt optimized for conversational language and specific temperature settings, supporting independent model and pricing configurations.
### Method
POST
### Endpoint
/api/translate/subtitle/batch
### Parameters
#### Request Body
- **type** (string) - Required - Message type, should be 'TRANSLATE_SUBTITLE_BATCH'
- **payload** (object) - Required - Payload for the translation request
- **texts** (array of strings) - Required - The subtitle text segments to translate
### Request Example
```json
{
"type": "TRANSLATE_SUBTITLE_BATCH",
"payload": {
"texts": [
"Welcome back to the channel",
"Today we are going to talk about AI"
]
}
}
```
### Response
#### Success Response (200)
- **ok** (boolean) - Indicates if the operation was successful
- **result** (array of strings) - The translated subtitle text segments
- **usage** (object) - Statistics about the API usage (structure similar to TRANSLATE_BATCH)
- **rpdExceeded** (boolean) - Flag indicating if the daily quota was exceeded
- **hadMismatch** (boolean) - Flag indicating if there was a mismatch in segment alignment
#### Response Example
```json
{
"ok": true,
"result": ["歡迎回到頻道", "今天我們要談論人工智能"],
"usage": {
"inputTokens": 150,
"outputTokens": 80,
"cachedTokens": 50,
"costUSD": 0.0012,
"billedInputTokens": 112,
"billedCostUSD": 0.0009,
"cacheHits": 0
},
"rpdExceeded": false,
"hadMismatch": false
}
```
```
--------------------------------
### Content Script to Background Script Message: EXTRACT_GLOSSARY
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Requests the extraction of glossary terms from a given input. The background script processes the input and returns the identified terms and diagnostic information.
```javascript
EXTRACT_GLOSSARY
{ input }
{ ok, terms, _diag }
```
--------------------------------
### Testing Parallel Batch Translation for YouTube Subtitles
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This test focuses on the parallel processing of subtitle translation batches for YouTube. It mocks `chrome.runtime.sendMessage` to introduce a fixed delay and records timestamps to assert that subsequent batches are processed in parallel within a short time frame.
```javascript
mock `chrome.runtime.sendMessage` 固定 100ms 延遲 + 記錄呼叫時間戳;17 條 rawSegments 切成 [1,8,8],呼叫 `translateYouTubeSubtitles`,斷言 batch 2 呼叫時間 - batch 1 呼叫時間 < 50ms
```
--------------------------------
### Implement Whitelist Auto Translate Jest Unit Test
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This Jest unit test suite covers the integration of domain whitelisting and automatic translation features. It tests various scenarios including exact matches, wildcards, root domain hits, and cases where auto-translate is disabled or the whitelist is empty.
```javascript
test/jest-unit/whitelist-auto-translate.test.cjs
```
--------------------------------
### Log and Query Usage Data
Source: https://context7.com/jimmysu0309/shinkansen/llms.txt
Record translation token counts and costs, with support for IndexedDB persistence and statistical queries. Use LOG_USAGE to record, and QUERY_USAGE to retrieve records or stats.
```javascript
// 記錄翻譯用量(由 translatePage 內部呼叫)
browser.runtime.sendMessage({
type: 'LOG_USAGE',
payload: {
url: location.href,
title: document.title,
inputTokens: 500,
outputTokens: 250,
cachedTokens: 100,
billedInputTokens: 425,
billedCostUSD: 0.0015,
segments: 20,
cacheHits: 5,
durationMs: 3500,
timestamp: Date.now()
}
});
```
```javascript
// 查詢用量紀錄
const { records } = await browser.runtime.sendMessage({
type: 'QUERY_USAGE',
payload: {
startDate: '2025-01-01',
endDate: '2025-01-31',
limit: 100
}
});
```
```javascript
// 查詢統計摘要
const { stats } = await browser.runtime.sendMessage({
type: 'QUERY_USAGE_STATS',
payload: { startDate: '2025-01-01' }
});
// { totalTokens: 125000, totalCost: 0.45, recordCount: 50 }
```
```javascript
// 匯出 CSV
const { csv } = await browser.runtime.sendMessage({
type: 'EXPORT_USAGE_CSV',
payload: {}
});
```
--------------------------------
### Shinkansen Batch Translation Protocol
Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md
Describes how Shinkansen handles batching and segmenting text for translation requests.
```APIDOC
## Batch Translation Protocol
### Description
Shinkansen sends multiple text segments concatenated with a specific separator for batch translation. The response is split using the same separator to align segments.
### Method
POST (via Google Gemini API)
### Endpoint
`https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent`
### Parameters
#### Request Body (Batching)
- **Text Segmentation**: Segments are joined by `\n<<>>\n`.
- **Batching Strategy**: Uses a greedy approach with two thresholds: `maxCharsPerBatch` (default 3500) and `maxUnitsPerBatch` (default 12). Either threshold triggers batch finalization.
- **Large Segments**: Segments exceeding batch limits are processed individually.
### Response Handling
#### Alignment Failure Fallback
If the number of returned segments does not match the number of sent segments, the system reverts to processing each segment individually.
### Implementation Details
- **Primary Packing Layer**: `packBatches()` in `content.js`.
- **Secondary Insurance Layer**: `packChunks()` in `lib/gemini.js`.
```
--------------------------------
### Mocking TRANSLATE_BATCH for YouTube Subtitle Translation Test
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This snippet illustrates how to mock the `TRANSLATE_BATCH` message in a testing environment. It specifies the expected return value for a subtitle translation request, ensuring that the translated text is correctly returned.
```javascript
mock `TRANSLATE_BATCH` 回傳 `['你好,世界!']`
```
--------------------------------
### Mock YouTube Player Response for Subtitle Translation
Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md
This HTML snippet demonstrates the structure for mocking the `ytInitialPlayerResponse` and the caption display element for testing YouTube subtitle translation. It's used to simulate the YouTube player's state and the initial display of captions.
```html
Hello, world!
```