@geolonia/yuuhitsu 0.1.17 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,15 @@
1
- import type { AIProvider, ChatRequest, ChatResponse, StreamChunk } from "./interface.js";
1
+ import type { AIProvider, ChatRequest, ChatResponse, StreamChunk, StructuredTranslateRequest, StructuredTranslateResponse } from "./interface.js";
2
2
  export declare class ClaudeProvider implements AIProvider {
3
3
  private client;
4
4
  private model;
5
5
  constructor(model: string);
6
6
  chat(request: ChatRequest): Promise<ChatResponse>;
7
7
  chatStream(request: ChatRequest): AsyncIterable<StreamChunk>;
8
+ /**
9
+ * Translate segments using Anthropic tool_use (structured output).
10
+ * Forces Claude to return a JSON object matching the translation schema —
11
+ * no prose wrapping, no schema deviations.
12
+ */
13
+ translateStructured(request: StructuredTranslateRequest): Promise<StructuredTranslateResponse>;
8
14
  }
9
15
  //# sourceMappingURL=claude.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/provider/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAExB,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAYnB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAiChD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC;CA6BpE"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/provider/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AA2BxB,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAYnB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAiChD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC;IA8BnE;;;;OAIG;IACG,mBAAmB,CACvB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC;CA2CxC"}
@@ -1,4 +1,27 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
+ const TRANSLATION_TOOL_NAME = "record_translations";
3
+ const TRANSLATION_TOOL = {
4
+ name: TRANSLATION_TOOL_NAME,
5
+ description: "Record the translated text segments in structured JSON format",
6
+ input_schema: {
7
+ type: "object",
8
+ properties: {
9
+ translations: {
10
+ type: "array",
11
+ items: {
12
+ type: "object",
13
+ properties: {
14
+ id: { type: "integer", description: "Segment ID (must match input ID exactly)" },
15
+ text: { type: "string", description: "Translated text for this segment" },
16
+ },
17
+ required: ["id", "text"],
18
+ },
19
+ description: "Translated segments — one entry per input segment, ID must match",
20
+ },
21
+ },
22
+ required: ["translations"],
23
+ },
24
+ };
2
25
  export class ClaudeProvider {
3
26
  client;
4
27
  model;
@@ -65,5 +88,42 @@ export class ClaudeProvider {
65
88
  }
66
89
  yield { content: "", done: true };
67
90
  }
91
+ /**
92
+ * Translate segments using Anthropic tool_use (structured output).
93
+ * Forces Claude to return a JSON object matching the translation schema —
94
+ * no prose wrapping, no schema deviations.
95
+ */
96
+ async translateStructured(request) {
97
+ const response = await this.client.messages.create({
98
+ model: request.model || this.model,
99
+ max_tokens: request.maxTokens ?? 4096,
100
+ system: request.systemPrompt,
101
+ messages: [
102
+ {
103
+ role: "user",
104
+ content: JSON.stringify({ segments: request.segments }),
105
+ },
106
+ ],
107
+ tools: [TRANSLATION_TOOL],
108
+ tool_choice: { type: "tool", name: TRANSLATION_TOOL_NAME },
109
+ });
110
+ const toolUseBlock = response.content.find((b) => b.type === "tool_use");
111
+ if (!toolUseBlock) {
112
+ throw new Error(`[yuuhitsu] ClaudeProvider.translateStructured: no tool_use block in response` +
113
+ ` (stop_reason: ${response.stop_reason})`);
114
+ }
115
+ const input = toolUseBlock.input;
116
+ if (!Array.isArray(input.translations)) {
117
+ throw new Error(`[yuuhitsu] ClaudeProvider.translateStructured: translations field is missing or not an array`);
118
+ }
119
+ return {
120
+ translations: input.translations,
121
+ usage: {
122
+ promptTokens: response.usage.input_tokens,
123
+ completionTokens: response.usage.output_tokens,
124
+ totalTokens: response.usage.input_tokens + response.usage.output_tokens,
125
+ },
126
+ };
127
+ }
68
128
  }
69
129
  //# sourceMappingURL=claude.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/provider/claude.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/provider/claude.ts"],"names":[],"mappings":"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"}
@@ -23,8 +23,35 @@ export interface StreamChunk {
23
23
  content: string;
24
24
  done: boolean;
25
25
  }
26
+ /** Request for structured output translation (tool_use path). */
27
+ export interface StructuredTranslateRequest {
28
+ segments: Array<{
29
+ id: number;
30
+ text: string;
31
+ }>;
32
+ systemPrompt: string;
33
+ model?: string;
34
+ maxTokens?: number;
35
+ }
36
+ /** Response from structured output translation. */
37
+ export interface StructuredTranslateResponse {
38
+ translations: Array<{
39
+ id: number;
40
+ text: string;
41
+ }>;
42
+ usage: {
43
+ promptTokens: number;
44
+ completionTokens: number;
45
+ totalTokens: number;
46
+ };
47
+ }
26
48
  export interface AIProvider {
27
49
  chat(request: ChatRequest): Promise<ChatResponse>;
28
50
  chatStream(request: ChatRequest): AsyncIterable<StreamChunk>;
51
+ /**
52
+ * Structured output translation via provider-native JSON schema enforcement.
53
+ * Optional: implemented by Claude. Gemini and Ollama fall back to text mode.
54
+ */
55
+ translateStructured?(request: StructuredTranslateRequest): Promise<StructuredTranslateResponse>;
29
56
  }
30
57
  //# sourceMappingURL=interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/provider/interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;CAC9D"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/provider/interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,iEAAiE;AACjE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7D;;;OAGG;IACH,mBAAmB,CAAC,CAClB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CAAC;CACzC"}
@@ -6,45 +6,10 @@ interface FrontmatterSeparation {
6
6
  body: string;
7
7
  }
8
8
  /**
9
- * Separate frontmatter from Markdown content
9
+ * Separate frontmatter from Markdown content.
10
10
  * Handles: LF, CRLF, no trailing newline after closing ---, trailing spaces, empty frontmatter
11
- * @param content - Full Markdown content
12
- * @returns Object with separated frontmatter and body
13
11
  */
14
12
  export declare function separateFrontmatter(content: string): FrontmatterSeparation;
15
- interface CodeProtection {
16
- text: string;
17
- map: Map<string, string>;
18
- }
19
- /**
20
- * Replace fenced code blocks and inline code with placeholders.
21
- * Uses a line-by-line parser instead of regex to avoid V8 stack overflow
22
- * on files with many code blocks (backreference + [\s\S]*? causes recursive backtracking).
23
- */
24
- export declare function protectCodeBlocks(content: string): CodeProtection;
25
- /**
26
- * Restore placeholders back to original code blocks/inline code.
27
- */
28
- export declare function restoreCodeBlocks(content: string, map: Map<string, string>): string;
29
- export declare const BLOCK_BOUNDARY_SENTINEL = "<!--BB-->";
30
- /**
31
- * Insert block boundary sentinels before structural Markdown elements
32
- * (list items, headings, horizontal rules, code fences, code block placeholders).
33
- * P-A4: prevents newline collapse around structural boundaries during LLM translation.
34
- * When called after protectCodeBlocks, fenced blocks appear as __CODE_BLOCK_N__ placeholders;
35
- * the function treats those placeholders as structural to protect fence-adjacent newlines.
36
- */
37
- export declare function protectBlockBoundaries(content: string): string;
38
- /**
39
- * Remove block boundary sentinels and restore newlines lost during LLM translation.
40
- * Uses a 3-pass strategy plus Layer 3 list-aware fallback (P-A4 v3):
41
- * Pass 1: normalize LLM-deformed variants (e.g. <!-- BB -->) to exact sentinel form
42
- * Pass 2: split + restore newlines (handles both clean and collapsed sentinel cases)
43
- * Pass 3: post-restore warning for residual sentinel-like patterns (silent failure prevention)
44
- * Layer 3: detect list items collapsed onto one line ("- A- B") and split them back
45
- * Applied unconditionally — handles the case where LLM deleted ALL sentinels
46
- */
47
- export declare function restoreBlockBoundaries(content: string): string;
48
13
  export interface TranslateOptions {
49
14
  provider: AIProvider;
50
15
  inputPath: string;
@@ -69,8 +34,8 @@ export interface TranslateResult {
69
34
  */
70
35
  export declare function findHeadingPositions(lines: string[], level: number): number[];
71
36
  /**
72
- * Split lines at the given positions into chunks (each position starts a new chunk).
73
- * Segments exceeding maxChunkLines are further split using ### headings or safeSplitLines.
37
+ * Split lines at the given positions into chunks. Segments exceeding maxChunkLines
38
+ * are further split using ### headings or safeSplitLines.
74
39
  */
75
40
  export declare function splitAtPositions(lines: string[], positions: number[], maxChunkLines: number): string[];
76
41
  /**
@@ -79,8 +44,7 @@ export declare function splitAtPositions(lines: string[], positions: number[], m
79
44
  */
80
45
  export declare function safeSplitLines(lines: string[], maxChunkLines: number): string[];
81
46
  /**
82
- * Merge chunks smaller than MIN_CHUNK_LINES into the previous chunk,
83
- * as long as the merged result does not exceed maxLines.
47
+ * Merge chunks smaller than MIN_CHUNK_LINES into the previous chunk.
84
48
  */
85
49
  export declare function mergeSmallChunks(chunks: string[], maxLines: number): string[];
86
50
  /**
@@ -88,6 +52,33 @@ export declare function mergeSmallChunks(chunks: string[], maxLines: number): st
88
52
  * Falls back to safe line-count splitting when no headings are present.
89
53
  */
90
54
  export declare function splitIntoChunks(content: string, maxChunkLines?: number): string[];
55
+ interface CodeProtection {
56
+ text: string;
57
+ map: Map<string, string>;
58
+ }
59
+ /**
60
+ * Replace fenced code blocks and inline code with placeholders.
61
+ * Used by glossary-fix.ts to protect code blocks before text replacement.
62
+ */
63
+ export declare function protectCodeBlocks(content: string): CodeProtection;
64
+ /**
65
+ * Restore placeholders back to original code blocks/inline code.
66
+ */
67
+ export declare function restoreCodeBlocks(content: string, map: Map<string, string>): string;
68
+ /**
69
+ * Translate a Markdown file using AST-based approach.
70
+ *
71
+ * Architecture (0.2.0):
72
+ * 1. Separate frontmatter (preserved verbatim)
73
+ * 2. Split body into chunks by heading boundaries
74
+ * 3. For each chunk: parse to AST → extract text nodes → translate via LLM → write back
75
+ * 4. Serialize AST → markdown → concatenate → write output
76
+ *
77
+ * Key properties:
78
+ * - Code blocks (fenced and inline) are never sent to LLM (AST handles them deterministically)
79
+ * - Markdown structure (headings, lists, tables, HR) is preserved by AST round-trip
80
+ * - No sentinel injection or removal needed
81
+ */
91
82
  export declare function translateFile(options: TranslateOptions): Promise<TranslateResult>;
92
83
  export {};
93
84
  //# sourceMappingURL=translate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/tasks/translate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAG3C,UAAU,qBAAqB;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAmB1E;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAwDjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAgBnF;AAED,eAAO,MAAM,uBAAuB,cAAc,CAAC;AASnD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0C9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkG9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAiJD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAa7E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,MAAM,GACpB,MAAM,EAAE,CA2BV;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CA6B/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,aAAa,SAA0B,GACtC,MAAM,EAAE,CAcV;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAwE1B"}
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/tasks/translate.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAM3C,UAAU,qBAAqB;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAa1E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAa7E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,MAAM,GACpB,MAAM,EAAE,CAyBV;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,aAAa,SAA0B,GACtC,MAAM,EAAE,CAcV;AAMD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CA8CjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAYnF;AAkRD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA+E1B"}
@@ -1,21 +1,19 @@
1
1
  import { readFileSync, writeFileSync, mkdirSync } from "fs";
2
2
  import { dirname, basename, extname, join } from "path";
3
+ import { remark } from "remark";
4
+ import remarkGfm from "remark-gfm";
5
+ import { visit } from "unist-util-visit";
3
6
  import { buildGlossaryPrompt } from "./glossary.js";
4
7
  export const DEFAULT_MAX_CHUNK_LINES = 300;
5
8
  const MIN_CHUNK_LINES = 50;
9
+ // P-A1: minimum ratio of output characters to input characters (truncation check)
10
+ const MIN_OUTPUT_RATIO = 0.3;
6
11
  /**
7
- * Separate frontmatter from Markdown content
12
+ * Separate frontmatter from Markdown content.
8
13
  * Handles: LF, CRLF, no trailing newline after closing ---, trailing spaces, empty frontmatter
9
- * @param content - Full Markdown content
10
- * @returns Object with separated frontmatter and body
11
14
  */
12
15
  export function separateFrontmatter(content) {
13
- // Normalize CRLF to LF for regex matching
14
16
  const normalized = content.replace(/\r\n/g, "\n");
15
- // Match frontmatter (two alternations to keep closing --- on its own line):
16
- // Case 1: non-empty body: ^---\n ... \n---[ \t]*(\n|$)
17
- // Case 2: empty body: ^---\n---[ \t]*(\n|$)
18
- // Using alternation avoids the \n? ambiguity that allows --- to match mid-line.
19
17
  const frontmatterRegex = /^---\n([\s\S]*?)\n---[ \t]*(\n|$)|^---\n---[ \t]*(\n|$)/;
20
18
  const match = normalized.match(frontmatterRegex);
21
19
  if (match) {
@@ -26,359 +24,7 @@ export function separateFrontmatter(content) {
26
24
  }
27
25
  return { frontmatter: null, body: normalized };
28
26
  }
29
- /**
30
- * Replace fenced code blocks and inline code with placeholders.
31
- * Uses a line-by-line parser instead of regex to avoid V8 stack overflow
32
- * on files with many code blocks (backreference + [\s\S]*? causes recursive backtracking).
33
- */
34
- export function protectCodeBlocks(content) {
35
- const map = new Map();
36
- let blockIndex = 0;
37
- let inlineIndex = 0;
38
- // Step 1: Replace fenced code blocks using line-by-line parsing
39
- const lines = content.split("\n");
40
- const resultLines = [];
41
- let fenceOpen = null; // the backtick sequence that opened the current block
42
- let blockLines = [];
43
- for (const line of lines) {
44
- const fenceMatch = line.match(/^(`{3,})/);
45
- if (fenceOpen === null) {
46
- // Not inside a code block
47
- if (fenceMatch) {
48
- // Opening fence found
49
- fenceOpen = fenceMatch[1];
50
- blockLines = [line];
51
- }
52
- else {
53
- resultLines.push(line);
54
- }
55
- }
56
- else {
57
- // Inside a code block — look for closing fence with same or more backticks
58
- blockLines.push(line);
59
- if (fenceMatch && fenceMatch[1].length >= fenceOpen.length && line.trim() === fenceMatch[1]) {
60
- // Closing fence found — store as single-line placeholder (no padding).
61
- // Padding was previously used to preserve line count, but it caused chunk
62
- // boundaries to fall inside the placeholder's whitespace region, leading to
63
- // non-deterministic LLM output when the code block exceeded --max-chunk-lines.
64
- const original = blockLines.join("\n") + "\n";
65
- const placeholder = `__CODE_BLOCK_${blockIndex++}__`;
66
- map.set(placeholder, original);
67
- resultLines.push(placeholder);
68
- fenceOpen = null;
69
- blockLines = [];
70
- }
71
- }
72
- }
73
- // If we ended inside an unclosed fence, emit lines as-is
74
- if (fenceOpen !== null) {
75
- resultLines.push(...blockLines);
76
- }
77
- let result = resultLines.join("\n");
78
- // Step 2: Replace inline code (single backtick, not within code blocks)
79
- result = result.replace(/`([^`\n]+)`/g, (match) => {
80
- const placeholder = `__INLINE_CODE_${inlineIndex++}__`;
81
- map.set(placeholder, match);
82
- return placeholder;
83
- });
84
- return { text: result, map };
85
- }
86
- /**
87
- * Restore placeholders back to original code blocks/inline code.
88
- */
89
- export function restoreCodeBlocks(content, map) {
90
- let result = content;
91
- for (const [placeholder, original] of map.entries()) {
92
- if (original.endsWith("\n")) {
93
- // Fenced code block: original already has trailing \n — just replace, one \n total.
94
- result = result.split(placeholder + "\n").join(original);
95
- result = result.split(placeholder).join(original);
96
- }
97
- else {
98
- // Inline code: original has NO trailing \n. Preserve any \n that follows the placeholder
99
- // so that newlines inserted by restoreBlockBoundaries (Layer 3) are not consumed.
100
- // e.g. "__INLINE_CODE_0__\n- next item" → "`code`\n- next item" (not "`code`- next item")
101
- result = result.split(placeholder + "\n").join(original + "\n");
102
- result = result.split(placeholder).join(original);
103
- }
104
- }
105
- return result;
106
- }
107
- export const BLOCK_BOUNDARY_SENTINEL = "<!--BB-->";
108
- // Temporary escape for pre-existing <!--BB--> literals in user content.
109
- // Uses a character sequence unlikely to appear in markdown documents.
110
- const ESCAPED_SENTINEL = "\x01BB\x01";
111
- // Fallback regex: catches LLM-deformed variants (e.g. <!-- BB -->, <!--BB__-->, <!--BBx-->)
112
- const SENTINEL_FALLBACK = /<!--\s*BB[a-zA-Z0-9_-]*\s*-->/g;
113
- // Broad check: detects severely-deformed residuals not caught by SENTINEL_FALLBACK
114
- const SENTINEL_RESIDUAL_CHECK = /<!--[\s\S]*?BB[\s\S]*?-->/g;
115
- /**
116
- * Insert block boundary sentinels before structural Markdown elements
117
- * (list items, headings, horizontal rules, code fences, code block placeholders).
118
- * P-A4: prevents newline collapse around structural boundaries during LLM translation.
119
- * When called after protectCodeBlocks, fenced blocks appear as __CODE_BLOCK_N__ placeholders;
120
- * the function treats those placeholders as structural to protect fence-adjacent newlines.
121
- */
122
- export function protectBlockBoundaries(content) {
123
- // Escape all sentinel-like patterns (exact + variants) to prevent control-marker confusion.
124
- // SENTINEL_FALLBACK covers <!--BB-->, <!-- BB -->, <!--BBx-->, <!--BB-x-->, etc.
125
- // On restore, these all round-trip back to <!--BB--> (minor cosmetic vs. content deletion).
126
- const escaped = content.replace(SENTINEL_FALLBACK, ESCAPED_SENTINEL);
127
- const lines = escaped.split("\n");
128
- const result = [];
129
- for (const line of lines) {
130
- const isListItem = /^\s*[-*+]\s/.test(line) || // unordered list
131
- /^\s*\d+\.\s/.test(line); // ordered list
132
- const isOtherStructural = !isListItem && (/^ {0,3}#{1,6}\s/.test(line) || // heading (CommonMark: 0-3 leading spaces)
133
- /^ {0,3}-{3,}\s*$/.test(line) || // hr (dash, 0-3 leading spaces)
134
- /^ {0,3}\*{3,}\s*$/.test(line) || // hr (asterisk, 0-3 leading spaces)
135
- /^ {0,3}_{3,}\s*$/.test(line) || // hr (underscore, 0-3 leading spaces)
136
- /^\s*`{3,}/.test(line) || // fenced code (backtick)
137
- /^\s*~{3,}/.test(line) || // fenced code (tilde)
138
- /^__CODE_BLOCK_\d+__$/.test(line.trim()) // code block placeholder (after protectCodeBlocks)
139
- );
140
- if (isListItem) {
141
- // P-A4 v3: double sentinel BEFORE each list item to resist LLM collapse.
142
- // 0.1.16 used a single sentinel; LLM deleted it and collapsed items to one line.
143
- // Two sentinels before each item mean the LLM must delete both to collapse — higher bar.
144
- // After-sentinels are intentionally omitted to preserve clean round-trip (no trailing \n).
145
- result.push(BLOCK_BOUNDARY_SENTINEL);
146
- result.push(BLOCK_BOUNDARY_SENTINEL);
147
- result.push(line);
148
- }
149
- else if (isOtherStructural) {
150
- result.push(BLOCK_BOUNDARY_SENTINEL);
151
- result.push(line);
152
- }
153
- else {
154
- result.push(line);
155
- }
156
- }
157
- return result.join("\n");
158
- }
159
- /**
160
- * Remove block boundary sentinels and restore newlines lost during LLM translation.
161
- * Uses a 3-pass strategy plus Layer 3 list-aware fallback (P-A4 v3):
162
- * Pass 1: normalize LLM-deformed variants (e.g. <!-- BB -->) to exact sentinel form
163
- * Pass 2: split + restore newlines (handles both clean and collapsed sentinel cases)
164
- * Pass 3: post-restore warning for residual sentinel-like patterns (silent failure prevention)
165
- * Layer 3: detect list items collapsed onto one line ("- A- B") and split them back
166
- * Applied unconditionally — handles the case where LLM deleted ALL sentinels
167
- */
168
- export function restoreBlockBoundaries(content) {
169
- // Pass 1: normalize variant sentinels introduced by LLM deformation (cmd_389 Root Cause A/B)
170
- const normalized = content.replace(SENTINEL_FALLBACK, BLOCK_BOUNDARY_SENTINEL);
171
- let restored;
172
- // Pass 2: split + restore newlines
173
- if (!normalized.includes(BLOCK_BOUNDARY_SENTINEL)) {
174
- // No exact sentinels: fall through to Pass 3 + Layer 3 (handles fully-deleted sentinel case)
175
- restored = normalized;
176
- }
177
- else {
178
- const parts = normalized.split(BLOCK_BOUNDARY_SENTINEL);
179
- restored = parts[0];
180
- for (let i = 1; i < parts.length; i++) {
181
- // Strip a leading newline from next part (present when LLM preserved sentinel on its own line)
182
- const stripped = parts[i].replace(/^\n/, "");
183
- if (restored.length === 0) {
184
- // Sentinel was at the very start of content — no preceding text to separate from
185
- restored = stripped;
186
- }
187
- else {
188
- // Ensure restored ends with exactly one newline before appending next part
189
- restored = restored.replace(/\n?$/, "\n") + stripped;
190
- }
191
- }
192
- }
193
- // Pass 3: post-restore warning for patterns not caught by SENTINEL_FALLBACK.
194
- // Runs for BOTH the sentinel-present and no-sentinel paths so fully-deformed output
195
- // is still flagged. Check before unescaping to avoid false positives from user <!--BB-->.
196
- const residuals = restored.match(SENTINEL_RESIDUAL_CHECK);
197
- if (residuals && residuals.length > 0) {
198
- console.warn(`[yuuhitsu] restoreBlockBoundaries: ${residuals.length} residual sentinel-like pattern(s) detected after restore:`, residuals.slice(0, 5));
199
- }
200
- // Unescape any pre-existing <!--BB--> that were escaped before protection
201
- if (restored.includes(ESCAPED_SENTINEL)) {
202
- restored = restored.split(ESCAPED_SENTINEL).join(BLOCK_BOUNDARY_SENTINEL);
203
- }
204
- // Layer 3 (P-A4 v3): list-aware fallback — detect inline list concatenation that
205
- // survived Layer 1+2 (LLM joined "- A\n- B" into "- A- B" on a single line).
206
- // Applied unconditionally: handles the worst case where ALL sentinels were deleted.
207
- // Uses /gm flag: ^ anchors to line start per line (multiline mode).
208
- //
209
- // Two sub-patterns:
210
- // (a) Spaced: "- A- B" or "- A - B" — requires whitespace after 2nd marker (original).
211
- // (b) Placeholder-end: "- A: __INLINE_CODE_0__-B" — inline code placeholder at end of
212
- // previous item followed directly by next list marker (no space). This is the pattern
213
- // LLM produces when translating to Japanese (Japanese text has no space after marker).
214
- // (?<!\s) guard: require the char immediately before the 2nd marker to be non-whitespace.
215
- // This prevents false-positive splits on prose like "- Linux - macOS support" where the
216
- // inline "- " is preceded by a space (valid prose) rather than collapsed item text.
217
- // True collapse ("- A- B") has NO space before the 2nd marker → lookbehind passes.
218
- const LIST_INLINE_MERGE_UNORDERED = /(^\s*[-*+]\s[^\n]*?)(?<!\s)([-*+]\s)/gm;
219
- const LIST_INLINE_MERGE_ORDERED = /(^\s*\d+\.\s[^\n]*?)(?<!\s)(\d+\.\s)/gm;
220
- // Placeholder-end pattern: matches code-placeholder end (\d+__) immediately before list marker.
221
- // Inserts "\n" + space (standard list-item format: "- content") so the new line passes
222
- // /^\s*[-*+]\s/ checks in integration tests.
223
- // (?=[^a-z]) guard avoids false positives for "__CODE__-style" (lowercase word hyphens).
224
- // e.g. "__INLINE_CODE_0__-次の項目" → "__INLINE_CODE_0__\n- 次の項目"
225
- const LIST_INLINE_MERGE_PLACEHOLDER_UNORDERED = /(\d+__)([-*+])(?=[^a-z])/gm;
226
- const LIST_INLINE_MERGE_PLACEHOLDER_ORDERED = /(\d+__)(\d+\.)(?=[^a-z])/gm;
227
- // Apply iteratively: JavaScript replace() scans left-to-right in the original string,
228
- // so "- A- B- C" needs two passes (first splits A-B, second splits B-C on the new line).
229
- let layer3applied = false;
230
- let prev;
231
- do {
232
- prev = restored;
233
- restored = restored.replace(LIST_INLINE_MERGE_UNORDERED, (_match, p1, p2) => {
234
- layer3applied = true;
235
- return `${p1}\n${p2}`;
236
- });
237
- restored = restored.replace(LIST_INLINE_MERGE_ORDERED, (_match, p1, p2) => {
238
- layer3applied = true;
239
- return `${p1}\n${p2}`;
240
- });
241
- restored = restored.replace(LIST_INLINE_MERGE_PLACEHOLDER_UNORDERED, (_match, p1, p2) => {
242
- layer3applied = true;
243
- return `${p1}\n${p2} `; // trailing space ensures valid "- content" list-item format
244
- });
245
- restored = restored.replace(LIST_INLINE_MERGE_PLACEHOLDER_ORDERED, (_match, p1, p2) => {
246
- layer3applied = true;
247
- return `${p1}\n${p2} `;
248
- });
249
- } while (restored !== prev);
250
- if (layer3applied) {
251
- console.warn("[yuuhitsu] restoreBlockBoundaries: Layer 3 list-aware fallback applied — " +
252
- "LLM concatenated list items inline. Layer 1+2 sentinels were insufficient.");
253
- }
254
- return restored;
255
- }
256
- const DEFAULT_TEMPLATE = `You are a professional translator. Translate the following Markdown document to {{targetLanguage}}.
257
-
258
- Rules:
259
- - Preserve all Markdown formatting (headings, links, code blocks, tables, lists)
260
- - Do not translate code blocks, URLs, or file paths
261
- - Do not translate frontmatter keys (only translate values where appropriate)
262
- - Maintain the same document structure
263
- - Produce natural, fluent text in the target language
264
- - Every opening \`\`\` you write MUST be followed by a language identifier on the same line (e.g., \`\`\`json, \`\`\`bash, \`\`\`typescript)
265
- - If the language is unknown, use \`\`\`text — never emit a bare opening \`\`\`
266
-
267
- CRITICAL - Link and URL preservation:
268
- - NEVER modify any URLs or link paths. Keep all href/src values exactly as-is.
269
- - NEVER change internal link paths (e.g., /ja/..., /en/..., ./relative-path). Preserve them verbatim.
270
- - NEVER convert external URLs to different language versions.
271
- - If the source has [text](/ja/changelog), the output must keep the same path, only translate the link text if needed.
272
- - Example: [紹介](/ja/intro) → translate "紹介" but keep "/ja/intro" unchanged
273
- - Example: [MDN](https://developer.mozilla.org/ja/) → keep the /ja/ in URL, translate "MDN" if needed
274
-
275
- Additional rules for Japanese translation:
276
- - Use full-width punctuation: 。、?! (not .,?!)
277
- - Add half-width spaces around English words and numbers (e.g., "Vela とは", "NGSIv2 は", "3 つの")
278
- - Use natural Japanese terms for technical words where appropriate (e.g., "registration" → "登録", "subscription" → "サブスクリプション")
279
- - Keep product names, proper nouns, and abbreviations unchanged (e.g., Vela, FIWARE, NGSIv2, NGSI-LD, MCP)
280
-
281
- Example — code fence with language identifier:
282
- Bad: \`\`\` echo hello \`\`\`
283
- Good: \`\`\`bash echo hello \`\`\``;
284
- function buildPrompt(content, targetLang, hasPlaceholders, hasSentinels, templateContent, glossaryConfig) {
285
- const template = templateContent || DEFAULT_TEMPLATE;
286
- let systemPrompt = template
287
- .replace(/\{\{targetLanguage\}\}/g, targetLang)
288
- .replace(/\{\{content\}\}/g, "");
289
- if (glossaryConfig) {
290
- const glossarySection = buildGlossaryPrompt(glossaryConfig, targetLang);
291
- if (glossarySection) {
292
- systemPrompt += glossarySection;
293
- }
294
- }
295
- if (hasSentinels) {
296
- systemPrompt +=
297
- "\n\n## Block boundary markers (P-A4 v2)\n\n" +
298
- "Lines containing the marker `<!--BB-->` are **block boundary markers** inserted\n" +
299
- "by the translation pipeline to preserve newlines around structural elements.\n\n" +
300
- "Rules for `<!--BB-->` markers (HTML comment form):\n" +
301
- "- Output every `<!--BB-->` marker **verbatim and unchanged** in your translation.\n" +
302
- "- Each marker must remain on its own line, in the same position relative to\n" +
303
- " surrounding content.\n" +
304
- "- Do not translate, remove, paraphrase, modify, normalize whitespace inside, or\n" +
305
- " rename these markers.\n" +
306
- "- Do not add new `<!--BB-->` markers; only preserve existing ones.\n\n" +
307
- "Good example (correct preservation):\n" +
308
- " Input:\n" +
309
- " <!--BB-->\n" +
310
- " - List item one\n" +
311
- " <!--BB-->\n" +
312
- " - List item two\n" +
313
- " <!--BB-->\n" +
314
- " ## Section heading\n" +
315
- " Output:\n" +
316
- " <!--BB-->\n" +
317
- " - リスト項目その一\n" +
318
- " <!--BB-->\n" +
319
- " - リスト項目その二\n" +
320
- " <!--BB-->\n" +
321
- " ## セクション見出し\n\n" +
322
- "Bad examples (DO NOT do these):\n" +
323
- " - <!--BB--> ❌ → <!--BB__--> (added suffix — FORBIDDEN)\n" +
324
- " - <!--BB--> ❌ → <!-- BB --> (added internal whitespace — FORBIDDEN)\n" +
325
- " - <!--BB--> ❌ → <!--bb--> (case change — FORBIDDEN)\n" +
326
- " - <!--BB--> ❌ → (omitted) (deleted — FORBIDDEN)\n" +
327
- " - <!--BB--> ❌ → <!--BB-x--> (added suffix — FORBIDDEN)\n\n" +
328
- "Preserve the marker exactly: 9 characters, opening `<!--`, content `BB`,\n" +
329
- "closing `-->`, no whitespace, no case changes, no suffixes.\n\n" +
330
- "## List boundary protection (P-A4 v3 list addendum)\n\n" +
331
- "For list items (lines starting with `-`, `*`, `+`, or `1.`),\n" +
332
- "`<!--BB-->` markers appear **multiple times in a row** (e.g., two consecutive\n" +
333
- "`<!--BB-->` lines). This is intentional — preserve ALL of them.\n\n" +
334
- "Bad example (DO NOT do this):\n" +
335
- " <!--BB-->\n" +
336
- " <!--BB-->\n" +
337
- " - Item A\n" +
338
- " <!--BB-->\n" +
339
- " <!--BB-->\n" +
340
- " - Item B\n\n" +
341
- " ❌ becomes: - Item A- Item B (list items on one line — FORBIDDEN)\n\n" +
342
- "Good example (keep each item on its own line):\n" +
343
- " <!--BB-->\n" +
344
- " <!--BB-->\n" +
345
- " - アイテムA\n" +
346
- " <!--BB-->\n" +
347
- " <!--BB-->\n" +
348
- " - アイテムB\n\n" +
349
- "Key rules for lists:\n" +
350
- "- Each list item MUST remain on its own line.\n" +
351
- "- NEVER join two list items into one line (e.g., `- A- B` is FORBIDDEN).\n" +
352
- "- Preserve ALL `<!--BB-->` markers, even when they appear consecutively.\n\n" +
353
- "Bad example (DO NOT do this) — inline code list collapse:\n" +
354
- " - Item A: `value 1`\n" +
355
- " - Item B: `value 2`\n\n" +
356
- " ❌ becomes: - Item A: `value 1`- Item B: `value 2` (FORBIDDEN, space before marker)\n" +
357
- " ❌ becomes: - Item A: `value 1`-Item B: `value 2` (FORBIDDEN, no space)\n\n" +
358
- "Good example: each list item must remain on its own line, even when items contain inline code:\n" +
359
- " - アイテムA: `value 1`\n" +
360
- " - アイテムB: `value 2`";
361
- }
362
- if (hasPlaceholders) {
363
- systemPrompt +=
364
- "\n\nIMPORTANT - Placeholder preservation:\n" +
365
- "- Tokens matching __CODE_BLOCK_N__ or __INLINE_CODE_N__ are placeholders for code blocks/inline code.\n" +
366
- "- Output them VERBATIM and UNCHANGED. Do NOT translate, modify, or remove them.\n" +
367
- "- Example: if input has __CODE_BLOCK_0__, output must contain __CODE_BLOCK_0__ exactly.";
368
- }
369
- return [
370
- { role: "system", content: systemPrompt },
371
- { role: "user", content },
372
- ];
373
- }
374
- function resolveOutputPath(inputPath, targetLang, outputPath) {
375
- if (outputPath)
376
- return outputPath;
377
- const dir = dirname(inputPath);
378
- const ext = extname(inputPath);
379
- const base = basename(inputPath, ext);
380
- return join(dir, `${base}.${targetLang}${ext}`);
381
- }
27
+ // ─── Chunking utilities (kept for splitIntoChunks export) ───────────────────
382
28
  /**
383
29
  * Find positions (line indices) of Markdown headings at the given level,
384
30
  * excluding lines inside fenced code blocks or table rows.
@@ -389,7 +35,7 @@ export function findHeadingPositions(lines, level) {
389
35
  const prefix = "#".repeat(level) + " ";
390
36
  for (let i = 0; i < lines.length; i++) {
391
37
  const line = lines[i];
392
- if (/^`{3,}/.test(line))
38
+ if (/^(`{3,}|~{3,})/.test(line))
393
39
  inCodeBlock = !inCodeBlock;
394
40
  if (inCodeBlock)
395
41
  continue;
@@ -401,8 +47,8 @@ export function findHeadingPositions(lines, level) {
401
47
  return positions;
402
48
  }
403
49
  /**
404
- * Split lines at the given positions into chunks (each position starts a new chunk).
405
- * Segments exceeding maxChunkLines are further split using ### headings or safeSplitLines.
50
+ * Split lines at the given positions into chunks. Segments exceeding maxChunkLines
51
+ * are further split using ### headings or safeSplitLines.
406
52
  */
407
53
  export function splitAtPositions(lines, positions, maxChunkLines) {
408
54
  const result = [];
@@ -417,8 +63,6 @@ export function splitAtPositions(lines, positions, maxChunkLines) {
417
63
  continue;
418
64
  if (segmentLines.length > maxChunkLines) {
419
65
  const subPositions = findHeadingPositions(segmentLines, 3);
420
- // Filter out position 0: splitting at the start doesn't reduce segment size
421
- // and causes infinite recursion when the only heading is at position 0.
422
66
  const effectivePositions = subPositions.filter((p) => p > 0);
423
67
  if (effectivePositions.length > 0) {
424
68
  result.push(...splitAtPositions(segmentLines, effectivePositions, maxChunkLines));
@@ -443,12 +87,8 @@ export function safeSplitLines(lines, maxChunkLines) {
443
87
  let inCodeBlock = false;
444
88
  for (let i = 0; i < lines.length; i++) {
445
89
  const line = lines[i];
446
- const isFence = /^`{3,}/.test(line);
90
+ const isFence = /^(`{3,}|~{3,})/.test(line);
447
91
  const isTableLine = line.startsWith("|");
448
- // Check split eligibility BEFORE toggling fence state:
449
- // - never split inside a code block
450
- // - never split ON a fence line (would separate opening/closing ``` from their block)
451
- // - never split ON a table row
452
92
  const canSplitHere = !inCodeBlock && !isFence && !isTableLine;
453
93
  if (isFence)
454
94
  inCodeBlock = !inCodeBlock;
@@ -463,8 +103,7 @@ export function safeSplitLines(lines, maxChunkLines) {
463
103
  return chunks.filter((c) => c.trim().length > 0);
464
104
  }
465
105
  /**
466
- * Merge chunks smaller than MIN_CHUNK_LINES into the previous chunk,
467
- * as long as the merged result does not exceed maxLines.
106
+ * Merge chunks smaller than MIN_CHUNK_LINES into the previous chunk.
468
107
  */
469
108
  export function mergeSmallChunks(chunks, maxLines) {
470
109
  if (chunks.length <= 1)
@@ -500,9 +139,290 @@ export function splitIntoChunks(content, maxChunkLines = DEFAULT_MAX_CHUNK_LINES
500
139
  }
501
140
  return safeSplitLines(lines, maxChunkLines);
502
141
  }
142
+ /**
143
+ * Replace fenced code blocks and inline code with placeholders.
144
+ * Used by glossary-fix.ts to protect code blocks before text replacement.
145
+ */
146
+ export function protectCodeBlocks(content) {
147
+ const map = new Map();
148
+ let blockIndex = 0;
149
+ let inlineIndex = 0;
150
+ const lines = content.split("\n");
151
+ const resultLines = [];
152
+ let fenceOpen = null;
153
+ let blockLines = [];
154
+ for (const line of lines) {
155
+ const fenceMatch = line.match(/^(`{3,})/);
156
+ if (fenceOpen === null) {
157
+ if (fenceMatch) {
158
+ fenceOpen = fenceMatch[1];
159
+ blockLines = [line];
160
+ }
161
+ else {
162
+ resultLines.push(line);
163
+ }
164
+ }
165
+ else {
166
+ blockLines.push(line);
167
+ if (fenceMatch && fenceMatch[1].length >= fenceOpen.length && line.trim() === fenceMatch[1]) {
168
+ const original = blockLines.join("\n") + "\n";
169
+ const placeholder = `__CODE_BLOCK_${blockIndex++}__`;
170
+ map.set(placeholder, original);
171
+ resultLines.push(placeholder);
172
+ fenceOpen = null;
173
+ blockLines = [];
174
+ }
175
+ }
176
+ }
177
+ if (fenceOpen !== null) {
178
+ resultLines.push(...blockLines);
179
+ }
180
+ let result = resultLines.join("\n");
181
+ result = result.replace(/`([^`\n]+)`/g, (match) => {
182
+ const placeholder = `__INLINE_CODE_${inlineIndex++}__`;
183
+ map.set(placeholder, match);
184
+ return placeholder;
185
+ });
186
+ return { text: result, map };
187
+ }
188
+ /**
189
+ * Restore placeholders back to original code blocks/inline code.
190
+ */
191
+ export function restoreCodeBlocks(content, map) {
192
+ let result = content;
193
+ for (const [placeholder, original] of map.entries()) {
194
+ if (original.endsWith("\n")) {
195
+ result = result.split(placeholder + "\n").join(original);
196
+ result = result.split(placeholder).join(original);
197
+ }
198
+ else {
199
+ result = result.split(placeholder + "\n").join(original + "\n");
200
+ result = result.split(placeholder).join(original);
201
+ }
202
+ }
203
+ return result;
204
+ }
205
+ /**
206
+ * Extract all translatable text nodes from an mdast AST.
207
+ * remark AST guarantees text nodes cannot be inside code/inlineCode nodes,
208
+ * so we only skip empty/whitespace-only nodes.
209
+ */
210
+ function extractTextNodes(ast) {
211
+ const nodes = [];
212
+ visit(ast, "text", (node) => {
213
+ if (!node.value.trim())
214
+ return;
215
+ nodes.push({ node, id: nodes.length });
216
+ });
217
+ return nodes;
218
+ }
219
+ /**
220
+ * Build system prompt for text-mode batch translation (Gemini / Ollama fallback).
221
+ * Includes JSON format instructions since we're relying on the LLM to output JSON.
222
+ */
223
+ function buildBatchSystemPrompt(targetLang, templateContent, glossaryConfig) {
224
+ const basePrompt = templateContent
225
+ ? templateContent.replace(/\{\{targetLanguage\}\}/g, targetLang)
226
+ : `You are a professional translator. Translate text segments to ${targetLang}.
227
+
228
+ Rules:
229
+ - Translate only the text content; do not add or remove punctuation structure
230
+ - Preserve proper nouns, code identifiers, URLs, and file paths unchanged
231
+ - Produce natural, fluent text in the target language
232
+ - For Japanese: use full-width punctuation (。、?!), add half-width spaces around English words/numbers
233
+ - Keep product names, abbreviations, and technical terms unchanged (e.g., NGSI-LD, MCP, GeoJSON)`;
234
+ let prompt = basePrompt;
235
+ if (glossaryConfig) {
236
+ const glossarySection = buildGlossaryPrompt(glossaryConfig, targetLang);
237
+ if (glossarySection)
238
+ prompt += glossarySection;
239
+ }
240
+ prompt += `
241
+
242
+ ## Translation format
243
+
244
+ You will receive a JSON object with a "segments" array.
245
+ Each segment has an "id" (integer) and "text" (string to translate).
246
+
247
+ Return ONLY a valid JSON object with a "translations" array.
248
+ Each translation must have the same "id" and the translated "text".
249
+ Do not include any explanation, markdown, or text outside the JSON object.
250
+
251
+ Example input:
252
+ {"segments": [{"id": 0, "text": "Hello world"}, {"id": 1, "text": "This is a test."}]}
253
+
254
+ Example output:
255
+ {"translations": [{"id": 0, "text": "こんにちは世界"}, {"id": 1, "text": "これはテストです。"}]}`;
256
+ return prompt;
257
+ }
258
+ /**
259
+ * Build system prompt for structured output translation (Claude tool_use path).
260
+ * No JSON format instructions needed — the tool schema enforces the response shape.
261
+ */
262
+ function buildStructuredSystemPrompt(targetLang, templateContent, glossaryConfig) {
263
+ const basePrompt = templateContent
264
+ ? templateContent.replace(/\{\{targetLanguage\}\}/g, targetLang)
265
+ : `You are a professional translator. Translate each text segment to ${targetLang}.
266
+
267
+ Rules:
268
+ - Translate only the text content; do not alter structure or punctuation outside the text
269
+ - Preserve proper nouns, code identifiers, URLs, and file paths unchanged
270
+ - Produce natural, fluent text in the target language
271
+ - For Japanese: use full-width punctuation (。、?!), add half-width spaces around English words/numbers
272
+ - Keep product names, abbreviations, and technical terms unchanged (e.g., NGSI-LD, MCP, GeoJSON)
273
+ - Each segment is independent; translate it on its own`;
274
+ let prompt = basePrompt;
275
+ if (glossaryConfig) {
276
+ const glossarySection = buildGlossaryPrompt(glossaryConfig, targetLang);
277
+ if (glossarySection)
278
+ prompt += glossarySection;
279
+ }
280
+ return prompt;
281
+ }
282
+ /**
283
+ * Parse translation JSON response from LLM (text mode fallback).
284
+ * Handles both clean JSON and JSON embedded in prose (extracts first {...} block).
285
+ */
286
+ function parseTranslationResponse(raw) {
287
+ const trimmed = raw.trim();
288
+ try {
289
+ return JSON.parse(trimmed);
290
+ }
291
+ catch {
292
+ // Extract first JSON object if LLM added prose around it
293
+ const jsonMatch = trimmed.match(/\{[\s\S]*\}/);
294
+ if (jsonMatch) {
295
+ return JSON.parse(jsonMatch[0]);
296
+ }
297
+ throw new Error(`Failed to parse translation response: ${trimmed.slice(0, 200)}`);
298
+ }
299
+ }
300
+ function assertValidTranslations(value) {
301
+ if (!Array.isArray(value) ||
302
+ value.some((item) => {
303
+ if (typeof item !== "object" || item === null)
304
+ return true;
305
+ const candidate = item;
306
+ return typeof candidate.id !== "number" || typeof candidate.text !== "string";
307
+ })) {
308
+ throw new Error("[yuuhitsu] translateBatch: invalid translation payload — expected Array<{id: number, text: string}>");
309
+ }
310
+ }
311
+ /**
312
+ * Translate a batch of text segments using the provider.
313
+ *
314
+ * - If the provider implements `translateStructured` (Claude): uses tool_use to
315
+ * enforce the JSON schema at the API level, guaranteeing 1:1 ID mapping.
316
+ * - Otherwise: falls back to text-mode JSON prompt (Gemini / Ollama).
317
+ *
318
+ * In both paths the 1:1 ID mapping is validated and an error is thrown on mismatch.
319
+ */
320
+ async function translateBatch(provider, nodes, targetLang, templateContent, glossaryConfig) {
321
+ if (nodes.length === 0) {
322
+ return { usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 } };
323
+ }
324
+ const segments = nodes.map(({ node, id }) => ({ id, text: node.value }));
325
+ // P-A1: track total input character count for truncation detection
326
+ const totalInputChars = segments.reduce((sum, s) => sum + s.text.length, 0);
327
+ let translations;
328
+ let usage;
329
+ if (provider.translateStructured) {
330
+ // Structured output path: provider (Claude) enforces JSON schema via tool_use
331
+ const systemPrompt = buildStructuredSystemPrompt(targetLang, templateContent, glossaryConfig);
332
+ const result = await provider.translateStructured({ segments, systemPrompt });
333
+ assertValidTranslations(result.translations);
334
+ translations = result.translations;
335
+ usage = result.usage;
336
+ // P-A1: warn on truncation (compare translated chars to input chars)
337
+ const totalOutputChars = translations.reduce((sum, t) => sum + t.text.length, 0);
338
+ if (totalInputChars > 0 && totalOutputChars < totalInputChars * MIN_OUTPUT_RATIO) {
339
+ console.warn(`[yuuhitsu] translateBatch: output may be truncated ` +
340
+ `(input chars: ${totalInputChars}, output chars: ${totalOutputChars})`);
341
+ }
342
+ }
343
+ else {
344
+ // Text mode fallback: Gemini / Ollama
345
+ const systemPrompt = buildBatchSystemPrompt(targetLang, templateContent, glossaryConfig);
346
+ const messages = [
347
+ { role: "system", content: systemPrompt },
348
+ { role: "user", content: JSON.stringify({ segments }) },
349
+ ];
350
+ const response = await provider.chat({ model: "", messages });
351
+ const parsed = parseTranslationResponse(response.content);
352
+ assertValidTranslations(parsed.translations);
353
+ // P-A1: warn on truncation (compare translated text chars, not raw JSON string length)
354
+ const totalOutputChars = parsed.translations.reduce((sum, t) => sum + t.text.length, 0);
355
+ if (totalInputChars > 0 && totalOutputChars < totalInputChars * MIN_OUTPUT_RATIO) {
356
+ console.warn(`[yuuhitsu] translateBatch: output may be truncated ` +
357
+ `(input chars: ${totalInputChars}, output chars: ${totalOutputChars})`);
358
+ }
359
+ translations = parsed.translations;
360
+ usage = response.usage;
361
+ }
362
+ // Validate strict 1:1 ID mapping (both paths):
363
+ // - no duplicate output IDs (Map silently overwrites; we must detect before)
364
+ // - no unexpected IDs (IDs not present in the input set)
365
+ // - no missing IDs (input ID absent from output)
366
+ const inputIds = new Set(nodes.map(({ id }) => id));
367
+ const seenOutputIds = new Set();
368
+ const duplicateIds = [];
369
+ const unexpectedIds = [];
370
+ for (const t of translations) {
371
+ if (seenOutputIds.has(t.id)) {
372
+ duplicateIds.push(t.id);
373
+ }
374
+ else {
375
+ seenOutputIds.add(t.id);
376
+ }
377
+ if (!inputIds.has(t.id)) {
378
+ unexpectedIds.push(t.id);
379
+ }
380
+ }
381
+ if (duplicateIds.length > 0) {
382
+ throw new Error(`[yuuhitsu] translateBatch: duplicate IDs in response (IDs: ${duplicateIds.join(", ")})`);
383
+ }
384
+ if (unexpectedIds.length > 0) {
385
+ throw new Error(`[yuuhitsu] translateBatch: unexpected IDs in response (IDs: ${unexpectedIds.join(", ")})`);
386
+ }
387
+ const translationMap = new Map(translations.map((t) => [t.id, t.text]));
388
+ const missingIds = nodes.filter(({ id }) => !translationMap.has(id)).map(({ id }) => id);
389
+ if (missingIds.length > 0) {
390
+ throw new Error(`[yuuhitsu] translateBatch: partial translation — ${missingIds.length} node(s) missing` +
391
+ ` from response (IDs: ${missingIds.join(", ")})`);
392
+ }
393
+ // Apply translations back to AST nodes
394
+ for (const { node, id } of nodes) {
395
+ const translated = translationMap.get(id);
396
+ if (translated !== undefined && translated.trim()) {
397
+ node.value = translated;
398
+ }
399
+ }
400
+ return { usage };
401
+ }
402
+ function resolveOutputPath(inputPath, targetLang, outputPath) {
403
+ if (outputPath)
404
+ return outputPath;
405
+ const dir = dirname(inputPath);
406
+ const ext = extname(inputPath);
407
+ const base = basename(inputPath, ext);
408
+ return join(dir, `${base}.${targetLang}${ext}`);
409
+ }
410
+ /**
411
+ * Translate a Markdown file using AST-based approach.
412
+ *
413
+ * Architecture (0.2.0):
414
+ * 1. Separate frontmatter (preserved verbatim)
415
+ * 2. Split body into chunks by heading boundaries
416
+ * 3. For each chunk: parse to AST → extract text nodes → translate via LLM → write back
417
+ * 4. Serialize AST → markdown → concatenate → write output
418
+ *
419
+ * Key properties:
420
+ * - Code blocks (fenced and inline) are never sent to LLM (AST handles them deterministically)
421
+ * - Markdown structure (headings, lists, tables, HR) is preserved by AST round-trip
422
+ * - No sentinel injection or removal needed
423
+ */
503
424
  export async function translateFile(options) {
504
- const { provider, inputPath, targetLang, templateContent, glossaryConfig, maxChunkLines } = options;
505
- // Read input file
425
+ const { provider, inputPath, targetLang, templateContent, glossaryConfig, maxChunkLines, } = options;
506
426
  let content;
507
427
  try {
508
428
  content = readFileSync(inputPath, "utf-8");
@@ -513,46 +433,41 @@ export async function translateFile(options) {
513
433
  }
514
434
  throw err;
515
435
  }
516
- // Check for empty file
517
436
  if (content.trim().length === 0) {
518
437
  throw new Error(`Input file is empty: ${inputPath}`);
519
438
  }
520
439
  const resolvedOutput = resolveOutputPath(inputPath, targetLang, options.outputPath);
521
- // Ensure output directory exists
522
440
  mkdirSync(dirname(resolvedOutput), { recursive: true });
523
- // Separate frontmatter from body
524
441
  const { frontmatter, body } = separateFrontmatter(content);
525
- // Protect code blocks: replace with placeholders before sending to LLM
526
- const { text: protectedBody, map: codeMap } = protectCodeBlocks(body);
527
- const hasPlaceholders = codeMap.size > 0;
528
- // Protect block boundaries: insert %%BB%% sentinels before structural elements (P-A4)
529
- const bodyWithSentinels = protectBlockBoundaries(protectedBody);
530
- const hasSentinels = bodyWithSentinels.includes(BLOCK_BOUNDARY_SENTINEL);
531
- // Split body into chunks if needed (frontmatter is never sent to LLM)
532
- const chunks = splitIntoChunks(bodyWithSentinels, maxChunkLines);
533
- const translatedParts = [];
442
+ // Split body into text chunks (heading-based, same as before)
443
+ const chunks = splitIntoChunks(body, maxChunkLines ?? DEFAULT_MAX_CHUNK_LINES);
444
+ const translatedChunks = [];
534
445
  let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
535
446
  for (const chunk of chunks) {
536
- const messages = buildPrompt(chunk, targetLang, hasPlaceholders, hasSentinels, templateContent, glossaryConfig);
537
- const response = await provider.chat({
538
- model: "",
539
- messages,
540
- });
541
- translatedParts.push(response.content);
542
- totalUsage.promptTokens += response.usage.promptTokens;
543
- totalUsage.completionTokens += response.usage.completionTokens;
544
- totalUsage.totalTokens += response.usage.totalTokens;
447
+ // Parse chunk to AST (code blocks, inline code become typed nodes → never reach LLM)
448
+ const processor = remark().use(remarkGfm);
449
+ const ast = processor.parse(chunk);
450
+ // Extract translatable text nodes
451
+ const textNodes = extractTextNodes(ast);
452
+ if (textNodes.length > 0) {
453
+ const { usage } = await translateBatch(provider, textNodes, targetLang, templateContent, glossaryConfig);
454
+ totalUsage.promptTokens += usage.promptTokens;
455
+ totalUsage.completionTokens += usage.completionTokens;
456
+ totalUsage.totalTokens += usage.totalTokens;
457
+ }
458
+ // Serialize AST back to markdown
459
+ const translatedChunk = processor.stringify(ast);
460
+ translatedChunks.push(translatedChunk);
545
461
  }
546
- // Restore block boundaries (sentinels newlines) then restore code block placeholders.
547
- // join("\n") ensures chunk boundaries always have a separator even if LLM drops trailing newlines.
548
- const translatedBodyWithSentinels = translatedParts.join("\n");
549
- const translatedBodyWithPlaceholders = restoreBlockBoundaries(translatedBodyWithSentinels);
550
- const translatedBody = restoreCodeBlocks(translatedBodyWithPlaceholders, codeMap);
551
- // Recombine frontmatter with translated body
462
+ // Join chunks: normalize each chunk to exactly one trailing newline
463
+ // (preserves trailing spaces for Markdown hard line breaks), then join
464
+ // with a single "\n" so chunk boundaries produce exactly one blank line.
465
+ const translatedBody = translatedChunks
466
+ .map((c) => c.replace(/\n+$/, "\n"))
467
+ .join("\n");
552
468
  const translatedContent = frontmatter
553
469
  ? frontmatter + translatedBody
554
470
  : translatedBody;
555
- // Write output
556
471
  writeFileSync(resolvedOutput, translatedContent, "utf-8");
557
472
  return {
558
473
  outputPath: resolvedOutput,
@@ -1 +1 @@
1
- {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/tasks/translate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/tasks/translate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geolonia/yuuhitsu",
3
- "version": "0.1.17",
3
+ "version": "0.2.0",
4
4
  "description": "右筆 (Yuuhitsu) - AI-powered document operations CLI. Translate, generate, and sync documents using Claude, Gemini, or Ollama.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,6 +36,9 @@
36
36
  "dotenv": "^16.4.0",
37
37
  "fast-glob": "^3.3.3",
38
38
  "openai": "^4.77.0",
39
+ "remark": "^15.0.1",
40
+ "remark-gfm": "^4.0.1",
41
+ "unist-util-visit": "^5.1.0",
39
42
  "yaml": "^2.7.0"
40
43
  },
41
44
  "devDependencies": {
@@ -43,5 +46,9 @@
43
46
  "tsx": "^4.19.0",
44
47
  "typescript": "^5.7.0",
45
48
  "vitest": "^3.0.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public",
52
+ "registry": "https://registry.npmjs.org/"
46
53
  }
47
54
  }