kokoro-writer 0.1.1

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.
Files changed (4) hide show
  1. package/LICENSE +91 -0
  2. package/README.md +116 -0
  3. package/dist/cli.js +388 -0
  4. package/package.json +30 -0
package/LICENSE ADDED
@@ -0,0 +1,91 @@
1
+ Required Notice: Copyright 2026 Kokoro OS / 千田正憲 (Masanori Chida) (https://usekokoro.com)
2
+
3
+ # PolyForm Shield License 1.0.0
4
+
5
+ <https://polyformproject.org/licenses/shield/1.0.0>
6
+
7
+ ## Acceptance
8
+
9
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
10
+
11
+ ## Copyright License
12
+
13
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
14
+
15
+ ## Distribution License
16
+
17
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
18
+
19
+ ## Notices
20
+
21
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
22
+
23
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
24
+
25
+ ## Changes and New Works License
26
+
27
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
28
+
29
+ ## Patent License
30
+
31
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
32
+
33
+ ## Noncompete
34
+
35
+ Any purpose is a permitted purpose, except for providing any product that competes with the software or any product the licensor or any of its affiliates provides using the software.
36
+
37
+ ## Competition
38
+
39
+ Goods and services compete even when they provide functionality through different kinds of interfaces or for different technical platforms. Applications can compete with services, libraries with plugins, frameworks with development tools, and so on, even if they're written in different programming languages or for different computer architectures. Goods and services compete even when provided free of charge. If you market a product as a practical substitute for the software or another product, it definitely competes.
40
+
41
+ ## New Products
42
+
43
+ If you are using the software to provide a product that does not compete, but the licensor or any of its affiliates brings your product into competition by providing a new version of the software or another product using the software, you may continue using versions of the software available under these terms beforehand to provide your competing product, but not any later versions.
44
+
45
+ ## Discontinued Products
46
+
47
+ You may begin using the software to compete with a product or service that the licensor or any of its affiliates has stopped providing, unless the licensor includes a plain-text line beginning with `Licensor Line of Business:` with the software that mentions that line of business. For example:
48
+
49
+ > Licensor Line of Business: YoyodyneCMS Content Management System (http://example.com/cms)
50
+
51
+ ## Sales of Business
52
+
53
+ If the licensor or any of its affiliates sells a line of business developing the software or using the software to provide a product, the buyer can also enforce [Noncompete](#noncompete) for that product.
54
+
55
+ ## Fair Use
56
+
57
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
58
+
59
+ ## No Other Rights
60
+
61
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
62
+
63
+ ## Patent Defense
64
+
65
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
66
+
67
+ ## Violations
68
+
69
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
70
+
71
+ ## No Liability
72
+
73
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
74
+
75
+ ## Definitions
76
+
77
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
78
+
79
+ A **product** can be a good or service, or a combination of them.
80
+
81
+ **You** refers to the individual or entity agreeing to these terms.
82
+
83
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all its affiliates.
84
+
85
+ **Affiliates** means the other organizations than an organization has control over, is under the control of, or is under common control with.
86
+
87
+ **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
88
+
89
+ **Your licenses** are all the licenses granted to you for the software under these terms.
90
+
91
+ **Use** means anything you do with the software requiring one of your licenses.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # kokoro-writer
2
+
3
+ **Turn rough notes into a finished document, in Markdown.** Spec, meeting minutes, manual, report, proposal, business email — or a style like a short story, a talk script or a social post.
4
+
5
+ ```bash
6
+ export ANTHROPIC_API_KEY=sk-ant-...
7
+ npx kokoro-writer notes.md --format minutes # writes notes.writer.md
8
+ npx kokoro-writer "new build is out, fixes the save bug" --style sns
9
+ ```
10
+
11
+ ### Easiest: ask your AI to run it
12
+
13
+ No terminal skills needed. If you work with an AI coding tool (Claude Code etc.), ask it:
14
+
15
+ ```
16
+ Run npx kokoro-writer notes.md --format minutes in this folder and show me the result.
17
+ ```
18
+
19
+ **Needs your Anthropic API key on your machine** (`ANTHROPIC_API_KEY`). Set it once in your system's environment variables, then restart your AI tool — Windows: search "environment variables" in Settings; macOS/Linux: add `export ANTHROPIC_API_KEY=...` to `~/.zshrc` or `~/.bashrc`. ★Do not paste your key into the AI chat — it stays in the conversation history.
20
+
21
+ The commands above are for running it yourself in a terminal.
22
+
23
+ - **Free, no sign-up.** Runs on *your* Anthropic API key; AI costs are billed to that key. `--model sonnet` (or `sonnet-expert`) writes more carefully at a higher cost; the default is `haiku`.
24
+ - **It does not invent quietly.** Things your notes did not say are left as blanks like `[要追記: date]`, and if the AI added facts that were not in your text, it lists them for you to check.
25
+ - **Output follows your language.** Notes in English give an English document.
26
+ - `npx kokoro-writer --list` shows every format and style. With neither, it only tidies (keeps your words, adds headings and lists).
27
+ - Your text goes through the Kokoro OS server to Anthropic and is **not stored**. Limited to 20 runs per 10 minutes.
28
+
29
+ Options: `<file or "text">` `--format <name>` `--style <name>` `--model haiku|sonnet|sonnet-expert` `--out name.md` `--yes` `--list` `--lang ja|en`
30
+
31
+ ## A spec for people to read (from a kokoro-baton spec)
32
+
33
+ ```bash
34
+ npx kokoro-writer spec-doc # in the folder with kokoro-spec.md → spec-for-readers.md
35
+ ```
36
+
37
+ `kokoro-spec.md` is written for the AI that builds your app. `spec-doc` turns it into a document for people — the client, your team, yourself next month.
38
+
39
+ - **AI writes only two sections:** "Overview" and "Design approach". Everything else — what counts as done, every decision, what is not decided yet, the look values, your design laws, the tunable numbers and how to check it — is **copied** from the spec and your code without going through AI.
40
+ - **Then it checks itself (no AI):** every decision in the spec must appear word for word, and numbers in the AI-written text that are not in the material are listed. Anything found is shown at the top of the document.
41
+ - Numbers come from the `PARAMS` block in your code (the layout a kokoro-baton spec asks for), and look values from the `STYLE` block — found in the folder automatically, or point to a file with `--code`.
42
+ - One Writer run on your key. Options: `[folder or spec file]` `--code file` `--out name.md` `--yes` `--model …`
43
+
44
+ ## One spec per system (from your finished code)
45
+
46
+ ```bash
47
+ npx kokoro-writer system-docs # → system-specs/1_<name>.md, 2_<name>.md, …
48
+ ```
49
+
50
+ - **AI splits your code into systems** (e.g. "Weapons and auto-attack", "Enemy spawning and difficulty"). Where each system starts and ends is quoted line by line and **checked against your code word for word** — only confirmed parts are kept. You see the split and say yes before anything is written.
51
+ - **For each system, AI writes six sections:** purpose, rules, flow, exceptions, what appears on screen, tuning notes (tuning notes only when there is a `PARAMS` block). The calculation lines (code as it is), the numbers used (name, key, current value, the reason from your code comment) and the related decisions from `kokoro-spec.md` are **copied** without AI.
52
+ - **Checks (no AI):** numbers in the AI text that are not in the material, numbers that do not exist in `PARAMS`, and how many times the AI wrote "cannot tell from the code".
53
+ - **Then another AI checks it against the code** (Claude Fable — the AI that wrote it is not the one that checks it). Each disagreement must quote the spec sentence and the code **word for word**; only quotes found word for word are used. The fixed sentence goes into the spec in bold with a `[fixed N]` mark, and a before → after table is added at the end. Findings whose quotes could not be confirmed are listed, not applied. ★Not finding a disagreement does not prove there is none.
54
+ - One file: the file with `PARAMS`, or point to one with `--code`. Uses one AI call to split, then Writer and Fable once per system (on your key; the check is roughly $0.25 per system). `--no-check` skips the check. An existing folder is never overwritten — a new one (`-2`, `-3`…) is made.
55
+
56
+ **Related:** decide what to build with [`kokoro-baton`](https://www.npmjs.com/package/kokoro-baton); check what you built with [`kokoro-aegis`](https://www.npmjs.com/package/kokoro-aegis).
57
+
58
+ ## License
59
+
60
+ [PolyForm Shield 1.0.0](https://polyformproject.org/licenses/shield/1.0.0) — free to use for any purpose, including at work and commercially. You may not use it to build a product that competes with it.
61
+
62
+ ---
63
+
64
+ ## 日本語
65
+
66
+ **メモや下書きを、仕上がった文書(Markdown)にする道具です。** 仕様書・議事録・業務マニュアル・報告書・提案書・ビジネスメールなどの形や、短編・プレゼン台本・SNS 投稿などの文体を選べます。
67
+
68
+ ```bash
69
+ npx kokoro-writer メモ.md --format minutes # メモ.writer.md ができる
70
+ npx kokoro-writer "新しい版を出した。保存の不具合を直した" --style sns
71
+ ```
72
+
73
+ ### いちばん簡単な使い方:AI に頼む
74
+
75
+ ターミナルの操作が分からなくても使えます。Claude Code などの AI と一緒に作っているなら、その AI にこう頼んでください。
76
+
77
+ ```
78
+ このフォルダで npx kokoro-writer メモ.md --format minutes を実行して、できたものを見せてください。
79
+ ```
80
+
81
+ **あなたの Anthropic の API キーが、パソコンに入っている必要があります**(`ANTHROPIC_API_KEY`)。一度だけ入れておき、AI の道具を開き直してください。Windows:設定で「環境変数」と検索 →「アカウントの環境変数を編集」で新しく足す。Mac:`~/.zshrc` に `export ANTHROPIC_API_KEY=...` を足す。★キーを AI との会話に貼らないでください(会話の記録に残ります)。
82
+
83
+ 上のコマンドは、ターミナルで自分で打つ人向けです。
84
+
85
+ - **無料・登録なし。** あなたのキーで動き、AI の費用はそのキーに付きます。`--model sonnet`(または `sonnet-expert`)で、より丁寧に書きます(費用は上がります)。ふだんは `haiku` です。
86
+ - **黙って作り話をしません。** メモに書いていないことは `[要追記: 日時]` のような空欄で残し、AI が書き足した事実があれば「確かめてください」と並べます。
87
+ - **入れた文章の言葉で書きます。** 英語のメモなら英語の文書になります。
88
+ - `npx kokoro-writer --list` で、選べる形と文体の一覧が出ます。どちらも付けなければ「そのまま整える」(言葉は変えず、見出しや箇条書きだけ整える)です。
89
+ - 文章は Kokoro OS のサーバーを通って Anthropic に送られます。**保存はしません。** 10 分に 20 回までです。
90
+ - **Word や PDF で欲しいとき**は、Kokoro OS の画面の Writer で書き出せます(Plus)。この道具が出すのは中身(Markdown)だけです。
91
+
92
+ ### 人が読む仕様書(kokoro-baton の指示書から)
93
+
94
+ ```bash
95
+ npx kokoro-writer spec-doc # kokoro-spec.md のあるフォルダで → spec-for-readers.md
96
+ ```
97
+
98
+ - `kokoro-spec.md` は作る AI 向けの紙です。`spec-doc` は、それを人(依頼主・仲間・来月の自分)が読む仕様書にします。
99
+ - **AI が書くのは「概要」と「設計の考え方」の 2 節だけ。** 合格・決めたこと・まだ決めていないこと・見た目の値・デザインの法則・調整する数・確かめ方は、指示書とコードから **AI を通さずに写します。**
100
+ - **最後に照らし合わせます(AI なし)。** 指示書の決めたことが全部、文字どおり入っているか/AI の文に、材料に無い数が無いか。引っかかったら文書の先頭に書きます。
101
+ - 数はコードの `PARAMS`、見た目の値は `STYLE` の塊から(フォルダから自動で探します。`--code` でファイルを指せます)。
102
+ - Writer を 1 回だけ使います(あなたのキー)。
103
+
104
+ ### 仕組みの仕様書(出来上がったコードから)
105
+
106
+ ```bash
107
+ npx kokoro-writer system-docs # → system-specs/1_名前.md、2_名前.md …(名前が日本語のときは 1_system.md)
108
+ ```
109
+
110
+ - **AI がコードを仕組みに分けます**(例:「武器と自動攻撃」「敵の出現と難易度」)。どこからどこまでかはコードの行を引用させ、**コードと文字どおり照らし合わせて**、確かめられた所だけを使います。分け方を見せて、「これで書く」と言ってから先へ進みます。
111
+ - **仕組みごとに、AI が 6 つの節を書きます**:目的・ルール・処理の流れ・例外・画面に出すもの・調整の勘所(勘所は `PARAMS` があるときだけ)。計算の行(コードそのまま)・使う数(名前・キー・今の値・コードのコメントの理由)・関わる決めごと(`kokoro-spec.md` から)は、AI を通さずに写します。
112
+ - **照らし合わせ(AI なし)**:AI の文に材料に無い数が無いか/使う数が `PARAMS` に実在するか/「コードからは分からない」と書いた所の数。
113
+ - **そのあと、別の AI がコードと照らし合わせます**(Claude Fable。書いた AI とは別の係)。食い違いは、仕様書の文とコードを**一字一句**引用させ、文字どおり見つかったものだけを使います。直した文は太字で[直した N]の印を付けて本文に入れ、末尾に前→後の表を足します。引用が確かめられなかった指摘は、本文を直さずに並べます。★見つからなかったことは、無いと証明したことではありません。
114
+ - 対象は 1 ファイルです(`PARAMS` のあるファイルか、`--code` で指したファイル)。分けるのに AI を 1 回、仕組みの数だけ Writer と Fable を使います(あなたのキー。照らし合わせは 1 本あたり約 35 円の見込み)。`--no-check` で照らし合わせを外せます。前のフォルダは上書きせず、`-2`・`-3` … の新しいフォルダに書きます。
115
+
116
+ **使ってよい範囲**:PolyForm Shield 1.0.0。仕事でも商売でも自由に使えます。これと競合する製品を作るために使うことはできません。
package/dist/cli.js ADDED
@@ -0,0 +1,388 @@
1
+ #!/usr/bin/env node
2
+ "use strict";var he=Object.create;var Pn=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,de=Object.prototype.hasOwnProperty;var $e=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of fe(e))!de.call(n,r)&&r!==t&&Pn(n,r,{get:()=>e[r],enumerable:!(s=pe(e,r))||s.enumerable});return n};var q=(n,e,t)=>(t=n!=null?he(me(n)):{},$e(e||!n||!n.__esModule?Pn(t,"default",{value:n,enumerable:!0}):t,n));var L=q(require("node:fs")),B=q(require("node:path")),ge=q(require("node:readline")),H=require("node:process");var nn=n=>process.env[n]?.trim()||"";function Tn(n){let e=nn("KOKORO_API_KEY"),t=nn("ANTHROPIC_API_KEY");return e&&t?{\u7A2E\u985E:"\u81EA\u524D\uFF0BKokoro",\u898B\u51FA\u3057:{"x-kokoro-api-key":e,"x-anthropic-api-key":t}}:e&&n==="Kokoro\u3082"?{\u7A2E\u985E:"Kokoro",\u898B\u51FA\u3057:{"x-kokoro-api-key":e}}:t?{\u7A2E\u985E:"\u81EA\u524D",\u898B\u51FA\u3057:{"x-anthropic-api-key":t}}:null}function vn(n,e){let t=!!nn("KOKORO_API_KEY"),s=!!nn("ANTHROPIC_API_KEY");return n==="\u81EA\u524D\u3060\u3051"&&t&&!s?e==="en"?"This step does not accept a Kokoro key alone yet. Also set your own Anthropic key in ANTHROPIC_API_KEY and run again (AI costs go to that key; a fee is taken from your Kokoro balance).":"\u3053\u306E\u6BB5\u306F\u3001\u307E\u3060 Kokoro \u306E\u30AD\u30FC\u3060\u3051\u3067\u306F\u52D5\u304D\u307E\u305B\u3093\u3002\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\u3082 ANTHROPIC_API_KEY \u306B\u5165\u308C\u3066\u304B\u3089\u3001\u3082\u3046\u4E00\u5EA6\u52D5\u304B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08AI \u306E\u8CBB\u7528\u306F\u305D\u306E\u30AD\u30FC\u306B\u3001\u624B\u6570\u6599\u306F Kokoro \u306E\u6B8B\u9AD8\u304B\u3089\uFF09\u3002":e==="en"?"No key found. Set ANTHROPIC_API_KEY (your own Anthropic key; AI costs go to that key, Kokoro OS charges nothing), then run again.":"\u30AD\u30FC\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002ANTHROPIC_API_KEY\uFF08\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\u30FBAI \u306E\u8CBB\u7528\u306F\u305D\u306E\u30AD\u30FC\u306B\u4ED8\u304D\u3001Kokoro OS \u306F\u6599\u91D1\u3092\u3044\u305F\u3060\u304D\u307E\u305B\u3093\uFF09\u3092\u5165\u308C\u3066\u304B\u3089\u3001\u3082\u3046\u4E00\u5EA6\u52D5\u304B\u3057\u3066\u304F\u3060\u3055\u3044\u3002"}function Mn(n,e){return n.\u7A2E\u985E==="Kokoro"?e==="en"?"Paying with your Kokoro key (AI costs from your Kokoro balance). To pay AI costs with your own Anthropic key, also set ANTHROPIC_API_KEY.":"Kokoro \u306E\u30AD\u30FC\u3067\u6255\u3044\u307E\u3059\uFF08AI \u306E\u8CBB\u7528\u3082 Kokoro \u306E\u6B8B\u9AD8\u304B\u3089\uFF09\u3002AI \u306E\u8CBB\u7528\u3092\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\u3067\u6255\u3046\u3068\u304D\u306F\u3001ANTHROPIC_API_KEY \u3082\u5165\u308C\u3066\u304F\u3060\u3055\u3044\u3002":n.\u7A2E\u985E==="\u81EA\u524D\uFF0BKokoro"?e==="en"?"AI costs go to your Anthropic key (ANTHROPIC_API_KEY). If a Kokoro fee applies, it is taken from your Kokoro balance (KOKORO_API_KEY) and shown after each call.":"AI \u306E\u8CBB\u7528\u306F\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\uFF08ANTHROPIC_API_KEY\uFF09\u306B\u4ED8\u304D\u307E\u3059\u3002Kokoro \u306E\u624B\u6570\u6599\u304C\u304B\u304B\u308B\u3068\u304D\u306F\u3001Kokoro \u306E\u6B8B\u9AD8\uFF08KOKORO_API_KEY\uFF09\u304B\u3089\u5F15\u3044\u3066\u3001\u547C\u3076\u305F\u3073\u306B\u984D\u3092\u51FA\u3057\u307E\u3059\u3002":e==="en"?"Paying AI costs with your Anthropic key (ANTHROPIC_API_KEY).":"AI \u306E\u8CBB\u7528\u306F\u3001\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\uFF08ANTHROPIC_API_KEY\uFF09\u3067\u6255\u3044\u307E\u3059\u3002"}function en(n,e){let t=n?.billing;if(!t||typeof t.charged_yen!="number")return null;let s=r=>r.toLocaleString(e==="en"?"en-US":"ja-JP",{maximumFractionDigits:2});return e==="en"?`This call: \xA5${s(t.charged_yen)} \xB7 Kokoro balance: \xA5${s(t.balance_yen??0)}`:`\u3053\u306E\u56DE ${s(t.charged_yen)} \u5186 \u30FB Kokoro \u306E\u6B8B\u9AD8 ${s(t.balance_yen??0)} \u5186`}var be={slide:{ja:{\u983C\u307F:"\u6307\u793A\u66F8 kokoro-spec.md\uFF08\u4E0A\u304B\u3089\u898B\u4E0B\u308D\u3059\u751F\u304D\u6B8B\u308A\u30A2\u30AF\u30B7\u30E7\u30F3\u30B2\u30FC\u30E0\u30FB\u7D04 3 \u4E07\u5B57\uFF09",markdown:`---
3
+ marp: true
4
+ paginate: true
5
+ ---
6
+
7
+ # \u6575\u304C\u8FEB\u3063\u3066\u304F\u308B\uFF0C\u6B66\u5668\u3092\u9078\u3093\u3067\u6483\u3064
8
+
9
+ \u4E0A\u304B\u3089\u898B\u4E0B\u308D\u3059\u30A2\u30AF\u30B7\u30E7\u30F3\u30B2\u30FC\u30E0\u3002\u6B66\u5668\u3092\u9078\u3093\u3067\u6575\u3092\u5012\u3059\uFF0C\u3067\u304D\u308B\u3060\u3051\u9577\u304F\u751F\u304D\u6B8B\u308B\u3002\u30D6\u30E9\u30A6\u30B6\u3067 1 \u679A\u306E HTML \u3067\u904A\u3079\u308B\u3002
10
+
11
+ <!--
12
+ \u3053\u306E\u30B2\u30FC\u30E0\u306E\u6838\u306F\u300C\u6B66\u5668\u3054\u3068\u306B\u7570\u306A\u308B\u653B\u6483\u7BC4\u56F2\u3068\u653B\u6483\u901F\u5EA6\u3067\uFF0C\u6575\u3092\u5012\u3059\u6C17\u6301\u3061\u3088\u3055\u300D\u3067\u3059\u3002\u898B\u305F\u76EE\u3067\u306F\u306A\u304F\uFF0C\u305D\u306E\u624B\u89E6\u308A\u3092\u6700\u521D\u306B\u5B8C\u6210\u3055\u305B\u307E\u3059\u3002
13
+ -->
14
+
15
+ ---
16
+
17
+ ## \u6B66\u5668\u3092\u9078\u3093\u3067\u3082\uFF0C\u5B9F\u611F\u304C\u7121\u3044
18
+
19
+ \u77ED\u5263\u30FB\u65A7\u30FB\u5F13 \u2015\u2015 \u9078\u3093\u3060\u6B66\u5668\u3067\uFF0C\u672C\u5F53\u306B\u4F55\u304C\u5909\u308F\u3063\u3066\u3044\u308B\u306E\u304B\u5206\u304B\u3089\u306A\u3044\u3002\u6575\u3092\u5012\u3059\u307E\u3067\u306E\u6D41\u308C\u304C\u9055\u3046\u3053\u3068\u3092\uFF0C\u4F53\u3067\u611F\u3058\u305F\u3044\u3002
20
+
21
+ <!--
22
+ \u3044\u307E\u8003\u3048\u3066\u3044\u308B\u306E\u306F\u300C\u653B\u6483\u7BC4\u56F2\u3068\u653B\u6483\u901F\u5EA6\u306F\u9055\u3046\u300D\u3068\u3044\u3046\u4ED5\u69D8\u3067\u3059\u3002\u3051\u308C\u3069\u3082\uFF0C\u305D\u308C\u304C\u753B\u9762\u3067\u660E\u78BA\u306B\u898B\u3048\u3066\uFF0C\u89E6\u3063\u305F\u3068\u304D\u9055\u3046\u624B\u89E6\u308A\u306B\u306A\u3063\u3066\u3044\u306A\u3051\u308C\u3070\uFF0C\u9078\u3093\u3060\u610F\u5473\u304C\u3042\u308A\u307E\u305B\u3093\u3002
23
+ -->
24
+
25
+ ---
26
+
27
+ ## 3 \u7A2E\u985E\u306E\u6B66\u5668\u3092\u4F5C\u308B\u3002\u7BC4\u56F2\u3082\u901F\u3055\u3082\uFF0C\u5927\u304D\u304F\u7570\u306A\u308B
28
+
29
+ \u77ED\u5263\uFF1A\u7BC4\u56F2 50px\u30FB\u653B\u6483 1 \u79D2 / \u65A7\uFF1A\u7BC4\u56F2 100px\u30FB\u653B\u6483 1.5 \u79D2 / \u5F13\uFF1A\u7BC4\u56F2 150px\u30FB\u653B\u6483 0.5 \u79D2\u3002\u9078\u3093\u3060\u3068\u304D\uFF0C\u305D\u306E\u5DEE\u304C\u5206\u304B\u308B\u3088\u3046\u306B\u3002
30
+
31
+ <!--
32
+ \u91CD\u8981\u306A\u306E\u306F\u300C\u5DEE\u304C\u5927\u304D\u3044\u300D\u3053\u3068\u3067\u3059\u3002\u534A\u5F84\u306E\u9055\u3044\uFF0C\u6575\u304C\u6D88\u3048\u308B\u307E\u3067\u306E\u6642\u9593\uFF0C\u653B\u6483\u304C\u5F53\u305F\u308B\u30DA\u30FC\u30B9 \u2015\u2015 \u3059\u3079\u3066\u3092\u904A\u3093\u3067\u3044\u308B\u9593\u305A\u3063\u3068\u898B\u3048\u308B\u5F62\u3067\u51FA\u3057\u307E\u3059\u3002\u30B2\u30FC\u30E0\u958B\u59CB\u6642\u306B\u9078\u3093\u3060\u6B66\u5668\u306E\u60C5\u5831\u3092\u53F3\u4E0A\u306B\u5E38\u6642\u8868\u793A\u3002
33
+ -->
34
+
35
+ ---
36
+
37
+ ## \u6575\u306E\u6D41\u308C\u306B\u5408\u308F\u305B\u3066\uFF0C\u6B66\u5668\u3092\u4F7F\u3044\u5206\u3051\u305F\u304F\u306A\u308B
38
+
39
+ \u6575\u306E\u6570\u304C\u5897\u3048\u308B\uFF0C\u6575\u306E\u901F\u3055\u304C\u4E0A\u304C\u308B\u3002\u305D\u308C\u306B\u5BFE\u3057\u3066\u300C\u3053\u306E\u6B66\u5668\u306A\u3089\u300D\u300C\u4ECA\u306A\u3089\u300D\u3068\uFF0C\u5224\u65AD\u3057\u3066\u9078\u3076\u9762\u767D\u3055\u3002\u6642\u9593\u304C\u7D4C\u3064\u306B\u3064\u308C\u96E3\u3057\u304F\u306A\u308B\u4E2D\u3067\uFF0C\u751F\u304D\u6B8B\u308B\u5FEB\u611F\u3002
40
+
41
+ <!--
42
+ \u904A\u3073\u306A\u304C\u3089\u300C\u7BC4\u56F2\u306E\u5E83\u3055\u304C\u6709\u5229\u306A\u5C40\u9762\u300D\u300C\u901F\u3055\u304C\u5FC5\u8981\u306A\u5C40\u9762\u300D\u304C\u81EA\u7136\u306B\u51FA\u3066\u304F\u308B\u3088\u3046\u306B\u8A2D\u8A08\u3057\u307E\u3059\u3002\u96E3\u6613\u5EA6\u306F 30 \u79D2\u3054\u3068\uFF0C\u307E\u305F\u306F\u6575\u306E\u6570\u3067\u6BB5\u968E\u7684\u306B\u4E0A\u3052\u3066\u3044\u304F\u3002\u6575\u306F\u5168\u65B9\u5411\u304B\u3089\u51FA\u73FE\u3057\uFF0C2\uFF5E3 \u7A2E\u985E\u304C\u7570\u306A\u308B\u901F\u3055\u3067\u8FEB\u3063\u3066\u304F\u308B\u3002
43
+ -->
44
+
45
+ ---
46
+
47
+ ## \u9078\u3093\u3060\u6B66\u5668\u304C\uFF0C\u672C\u5F53\u306B\u9055\u3046\u3002\u305D\u308C\u304C\u6C17\u6301\u3061\u3044\u3044
48
+
49
+ \u30AD\u30FC\u30DC\u30FC\u30C9\u3067\u52D5\u304F\uFF0C\u6575\u306B\u8FD1\u3065\u304F\u3068\u81EA\u52D5\u3067\u653B\u6483\u3002HP \u304C\u6E1B\u3063\u3066\u30B2\u30FC\u30E0\u30AA\u30FC\u30D0\u30FC\u3002\u6642\u9593\u304C\u51FA\u3066\u3044\u308B\u3002 \u2015\u2015 \u5168\u90E8\u304C\u6B66\u5668\u306E\u9078\u629E\u306B\u3064\u306A\u304C\u308B\u3002
50
+
51
+ <!--
52
+ \u6700\u5F8C\u306B\u899A\u3048\u3066\u307B\u3057\u3044\u306E\u306F\u300C\u898B\u305F\u76EE\u3067\u306F\u306A\u304F\uFF0C\u624B\u89E6\u308A\u3092\u5B8C\u6210\u3055\u305B\u308B\u300D\u3068\u3044\u3046\u3053\u3068\u3067\u3059\u3002\u6B66\u5668\u3092\u9078\u3093\u3060\u77AC\u9593\u304B\u3089\uFF0C\u6575\u3068\u306E\u8DDD\u96E2\u306E\u53D6\u308A\u65B9\u30FB\u6575\u304C\u6D88\u3048\u308B\u30B9\u30D4\u30FC\u30C9\u30FB\u6B21\u306E\u6575\u307E\u3067\u306E\u9593\u9694 \u2015\u2015 \u5168\u90E8\u304C\u9055\u3046\u3002\u305D\u306E\u9055\u3044\u3092\u904A\u3093\u3067\u3044\u3066\u81EA\u7136\u306B\u611F\u3058\u3089\u308C\u308B\u3053\u3068\u3002
53
+ -->
54
+
55
+ ---
56
+
57
+ ## \u307E\u305A\u6700\u5C0F\u7248\u3067\u8A66\u3059\u3002\u898B\u305F\u76EE\u306F\u5F8C\u56DE\u3057
58
+
59
+ \u7B2C 1 \u6BB5\u968E\uFF1A\u30B3\u30A2\u3060\u3051\u4F5C\u308B\u3002UI \u306F\u78E8\u304B\u306A\u3044\u3002\u624B\u89E6\u308A\u304C\u5B8C\u6210\u3057\u305F\u3089\u898B\u305B\u3066\u304F\u3060\u3055\u3044\u3002\u305D\u3053\u304B\u3089\u76F4\u3057\u307E\u3059\u3002
60
+
61
+ <!--
62
+ \u8272\u3092\u5857\u308B\u30FB\u80CC\u666F\u3092\u4F5C\u308B \u2015\u2015 \u305D\u308C\u306F\u5168\u90E8\u3042\u3068\u3067\u3059\u3002\u3044\u307E\u5927\u4E8B\u306A\u306E\u306F\u300C\u6575\u3092\u5012\u3059\u3053\u3068\u306E\u6C17\u6301\u3061\u3088\u3055\u300D\u3060\u3051\u3002\u305D\u308C\u304C\u5B9F\u73FE\u3067\u304D\u305F\u3089\uFF0C\u6B21\u306E\u6BB5\u968E\u306B\u9032\u307F\u307E\u3059\u3002
63
+ -->
64
+ `},en:{\u983C\u307F:"Announcement for next week's study session. Topic: how to build a simple household budget app. Thursday 7pm, online, free, beginners welcome.",markdown:`---
65
+ marp: true
66
+ paginate: true
67
+ ---
68
+
69
+ # Build Your First Budget App
70
+
71
+ Next Thursday \xB7 7pm \xB7 Online \xB7 Free
72
+
73
+ <!--
74
+ We're hosting a hands-on session next week where you'll learn to build a simple budget app from scratch. No coding experience needed\u2014if you can follow along, you're in. It's a short evening, but you'll walk away with working code.
75
+ -->
76
+
77
+ ---
78
+
79
+ ## Why This Matters
80
+
81
+ Managing money feels complicated. Apps exist, but how do they work?
82
+
83
+ <!--
84
+ Most people use budget apps but never look under the hood. This session flips that: you'll see the mechanics yourself, understand how data flows, and realize it's not magic\u2014just logic.
85
+ -->
86
+
87
+ ---
88
+
89
+ ## What We'll Build
90
+
91
+ A working budget app \xB7 Input income & expenses \xB7 See your balance
92
+
93
+ <!--
94
+ We'll code a simple app that takes income and spending, stores it, and shows your current balance. Step by step, no jumping around. You'll have real, runnable code by the end.
95
+ -->
96
+
97
+ ---
98
+
99
+ ## What You Get
100
+
101
+ Working knowledge of app basics \xB7 Confidence to build more
102
+
103
+ <!--
104
+ You'll understand how apps store and display data. That foundation opens doors to learning more complex apps later. Plus, you can show it to friends or use it yourself.
105
+ -->
106
+
107
+ ---
108
+
109
+ ## One Word
110
+
111
+ Learn by making, not by watching.
112
+
113
+ <!--
114
+ This isn't a lecture. You'll write code and see it work in real time. That's how it sticks\u2014and how you actually learn.
115
+ -->
116
+
117
+ ---
118
+
119
+ ## Join Us
120
+
121
+ Thursday 7pm \xB7 Sign up now \xB7 Bring a laptop
122
+
123
+ <!--
124
+ It's free, online, and open to everyone. All you need is a device and curiosity. See you there.
125
+ -->
126
+ `}},kami:{ja:{\u983C\u307F:"\u308A\u3093\u3054\u30FB\u307F\u304B\u3093\u30FB\u30D0\u30CA\u30CA\u306E\u6804\u990A\uFF08100g \u3042\u305F\u308A\u306E\u30AB\u30ED\u30EA\u30FC\u30FB\u30D3\u30BF\u30DF\u30F3 C\u30FB\u98DF\u7269\u7E4A\u7DAD\uFF09\u3092\u6BD4\u3079\u308B",markdown:`# \u679C\u7269\u306E\u6804\u990A\u6BD4\u8F03\uFF08100g \u3042\u305F\u308A\uFF09
127
+
128
+ \u308A\u3093\u3054\u30FB\u307F\u304B\u3093\u30FB\u30D0\u30CA\u30CA\u306E100g \u3042\u305F\u308A\u306E\u30AB\u30ED\u30EA\u30FC\u30FB\u30D3\u30BF\u30DF\u30F3 C\u30FB\u98DF\u7269\u7E4A\u7DAD\u3092\u6BD4\u8F03\u3057\u305F\u8868\u3002
129
+
130
+ | \u679C\u7269 | \u30AB\u30ED\u30EA\u30FC\uFF08kcal\uFF09 | \u30D3\u30BF\u30DF\u30F3 C\uFF08mg\uFF09 | \u98DF\u7269\u7E4A\u7DAD\uFF08g\uFF09 |
131
+ | --- | --- | --- | --- |
132
+ | \u308A\u3093\u3054 | 61 | 4 | 1.5 |
133
+ | \u307F\u304B\u3093 | 45 | 33 | 1.6 |
134
+ | \u30D0\u30CA\u30CA | 89 | 16 | 1.1 |
135
+ `,csv:`\u679C\u7269,\u30AB\u30ED\u30EA\u30FC\uFF08kcal\uFF09,\u30D3\u30BF\u30DF\u30F3 C\uFF08mg\uFF09,\u98DF\u7269\u7E4A\u7DAD\uFF08g\uFF09\r
136
+ \u308A\u3093\u3054,61,4,1.5\r
137
+ \u307F\u304B\u3093,45,33,1.6\r
138
+ \u30D0\u30CA\u30CA,89,16,1.1\r
139
+ `},en:{\u983C\u307F:"Compare apples, oranges and bananas: calories, vitamin C and fiber per 100 g",markdown:`# Nutritional Comparison of Apples, Oranges, and Bananas
140
+
141
+ Nutritional content per 100g for three common fruits. Bananas are highest in calories, oranges excel in vitamin C, and all three provide similar fiber content.
142
+
143
+ | Fruit | Calories (kcal) | Vitamin C (mg) | Fiber (g) |
144
+ | --- | --- | --- | --- |
145
+ | Apple | 52 | 5.7 | 2.4 |
146
+ | Orange | 47 | 53.2 | 2.4 |
147
+ | Banana | 89 | 8.7 | 2.6 |
148
+
149
+ **How columns were worked out**
150
+
151
+ - Calories (kcal): per 100g
152
+ - Vitamin C (mg): per 100g
153
+ - Fiber (g): per 100g
154
+ `,csv:`Fruit,Calories (kcal),Vitamin C (mg),Fiber (g)\r
155
+ Apple,52,5.7,2.4\r
156
+ Orange,47,53.2,2.4\r
157
+ Banana,89,8.7,2.6\r
158
+ `}},writer:{ja:{\u983C\u307F:"\u6765\u9031\u306E\u5B9A\u4F8B\u306F\u6728\u66DC15\u6642\u304B\u3089\u3002\u8B70\u984C\u306F\u3075\u305F\u3064\u3002\u65B0\u3057\u3044\u30A2\u30D7\u30EA\u306E\u540D\u524D\u30923\u6848\u304B\u3089\u6C7A\u3081\u308B\u3053\u3068\u3001\u516C\u958B\u65E5\u3092\u6C7A\u3081\u308B\u3053\u3068\u3002\u516C\u958B\u65E5\u306F11\u6708\u4E2D\u65EC\u3067\u8ABF\u6574\u4E2D\u3002\u5C71\u7530\u3055\u3093\u304C\u540D\u524D\u306E\u6848\u3092\u307E\u3068\u3081\u3066\u304F\u308B\u3002\uFF08--format minutes\uFF09",markdown:`# \u6765\u9031\u306E\u5B9A\u4F8B \u8B70\u4E8B\u9332
159
+
160
+ ### \u57FA\u672C\u60C5\u5831
161
+
162
+ \u65E5\u6642\uFF1A\u6765\u9031\u6728\u66DC15\u6642
163
+
164
+ \u5834\u6240\uFF1A[\u8981\u8FFD\u8A18: \u958B\u50AC\u5834\u6240]
165
+
166
+ \u51FA\u5E2D\u8005\uFF1A[\u8981\u8FFD\u8A18: \u51FA\u5E2D\u8005\u540D]
167
+
168
+ \u8A18\u9332\u8005\uFF1A[\u8981\u8FFD\u8A18: \u8A18\u9332\u8005\u540D]
169
+
170
+ ## \u8B70\u984C
171
+
172
+ 1. \u65B0\u3057\u3044\u30A2\u30D7\u30EA\u306E\u540D\u524D\u30923\u6848\u304B\u3089\u6C7A\u3081\u308B\u3053\u3068
173
+ 2. \u516C\u958B\u65E5\u3092\u6C7A\u3081\u308B\u3053\u3068
174
+
175
+ ### \u8B70\u984C1: \u65B0\u3057\u3044\u30A2\u30D7\u30EA\u306E\u540D\u524D\u30923\u6848\u304B\u3089\u6C7A\u3081\u308B\u3053\u3068
176
+
177
+ \u5C71\u7530\u3055\u3093\u304C\u540D\u524D\u306E\u6848\u3092\u307E\u3068\u3081\u3066\u304F\u308B\u3002
178
+
179
+ ### \u8B70\u984C2: \u516C\u958B\u65E5\u3092\u6C7A\u3081\u308B\u3053\u3068
180
+
181
+ \u516C\u958B\u65E5\u306F11\u6708\u4E2D\u65EC\u3067\u8ABF\u6574\u4E2D\u3002
182
+
183
+ ## \u30A2\u30AF\u30B7\u30E7\u30F3\u30A2\u30A4\u30C6\u30E0
184
+
185
+ - \u5C71\u7530\u3055\u3093 / \u65B0\u3057\u3044\u30A2\u30D7\u30EA\u306E\u540D\u524D\u306E\u6848\u3092\u307E\u3068\u3081\u308B / \u6765\u9031\u6728\u66DC15\u6642\u307E\u3067\u306B
186
+ `},en:{\u983C\u307F:"Next weekly meeting is Thursday at 3pm. Two topics: pick the new app name from three ideas, and set the launch date. Launch is being planned for mid-November. Yamada will bring the name ideas. (--format minutes)",markdown:`# Weekly Meeting
187
+
188
+ ### Basic Information
189
+
190
+ Date: Thursday at 3pm
191
+
192
+ Attendees: [\u8981\u8FFD\u8A18: \u51FA\u5E2D\u8005\u540D]
193
+
194
+ Recorder: [\u8981\u8FFD\u8A18: \u8A18\u9332\u8005\u540D]
195
+
196
+ ## Agenda
197
+
198
+ 1. Pick the new app name from three ideas
199
+ 2. Set the launch date
200
+
201
+ ### Topic 1: Pick the new app name from three ideas
202
+
203
+ Yamada will bring the name ideas.
204
+
205
+ ### Topic 2: Set the launch date
206
+
207
+ Launch is being planned for mid-November.
208
+
209
+ ## Action Items
210
+
211
+ - Yamada: Bring the name ideas to Thursday meeting
212
+
213
+ ### Next Meeting
214
+
215
+ Thursday at 3pm
216
+ `}},baton:{ja:{\u983C\u307F:"\u4E0A\u304B\u3089\u898B\u4E0B\u308D\u3059\u30A2\u30AF\u30B7\u30E7\u30F3\u30B2\u30FC\u30E0\u3002\u8FEB\u3063\u3066\u304F\u308B\u6575\u3092\u5012\u3057\u306A\u304C\u3089\u3001\u3067\u304D\u308B\u3060\u3051\u9577\u304F\u751F\u304D\u6B8B\u308B\u3002\u6700\u521D\u306B\u6B66\u5668\u3092\u9078\u3079\u308B\u3002\u30D6\u30E9\u30A6\u30B6\u3067\u904A\u3079\u308B 1 \u679A\u306E HTML \u3067\u4F5C\u308A\u305F\u3044\u3002\uFF08\u3053\u306E\u3042\u3068\u554F\u3044\u306B 3 \u56DE\u7B54\u3048\u3066\u3001\u5408\u683C\u306E\u6848\u3092\u9078\u3093\u3060\uFF09",markdown:`# \u4F5C\u3063\u3066\u307B\u3057\u3044\u3082\u306E
217
+
218
+ \u4E0A\u304B\u3089\u898B\u4E0B\u308D\u3059\u30A2\u30AF\u30B7\u30E7\u30F3\u30B2\u30FC\u30E0\u3002\u8FEB\u3063\u3066\u304F\u308B\u6575\u3092\u5012\u3057\u306A\u304C\u3089\u3001\u3067\u304D\u308B\u3060\u3051\u9577\u304F\u751F\u304D\u6B8B\u308B\u3002\u6700\u521D\u306B\u6B66\u5668\u3092\u9078\u3079\u308B\u3002\u30D6\u30E9\u30A6\u30B6\u3067\u904A\u3079\u308B 1 \u679A\u306E HTML \u3067\u4F5C\u308A\u305F\u3044\u3002
219
+
220
+ ## \u2605\u3053\u308C\u304C\u3067\u304D\u305F\u3089\u5408\u683C
221
+
222
+ \u77ED\u5263\u30FB\u65A7\u30FB\u5F13\u306E 3 \u3064\u306E\u6B66\u5668\u304B\u3089\u9078\u3093\u3067\u3001\u305D\u308C\u305E\u308C\u306E\u653B\u6483\u7BC4\u56F2\u3068\u653B\u6483\u901F\u5EA6\u306E\u9055\u3044\u3092\u611F\u3058\u306A\u304C\u3089\u6575\u3092\u5012\u3059\u3002\u6642\u9593\u304C\u7D4C\u3064\u306B\u3064\u308C\u3001\u6575\u304C\u5897\u3048\u3066\u901F\u304F\u306A\u308B\u3002
223
+
224
+ \u203B\u3053\u306E\u4E00\u6587\u306F\u3001Baton \u304C\u51FA\u3057\u305F\u6848\u304B\u3089\u9078\u3093\u3060\u3082\u306E\u3067\u3059\u3002
225
+
226
+ \u2605**\u3053\u308C\u304C\u3001\u3053\u306E\u9053\u5177\u306E\u3044\u3061\u3070\u3093\u5927\u4E8B\u306A\u3068\u3053\u308D\u3067\u3059\u3002**
227
+ \u3053\u3053\u304C\u6C17\u6301\u3061\u3088\u304F\u52D5\u304F\u307E\u3067\u306F\u3001\u307B\u304B\u3092\u4F5C\u308A\u8FBC\u307E\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
228
+
229
+ ## \u524D\u63D0 \u2015 \u4F7F\u3046\u4EBA\u30FB\u5834\u9762\uFF08\u89E6\u3063\u3066\u78BA\u304B\u3081\u308B\u884C\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09
230
+
231
+ **\u8AB0\u304C\u30FB\u3069\u3093\u306A\u5834\u9762\u3067\u30FB\u3069\u308C\u304F\u3089\u3044\u4F7F\u3046\u304B\u3002**\u4F5C\u308A\u65B9\u3092\u6C7A\u3081\u308B\u624B\u304C\u304B\u308A\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
232
+ \u30A2\u30D7\u30EA\u3092\u89E6\u3063\u3066\u3082\u78BA\u304B\u3081\u3088\u3046\u304C\u306A\u3044\u306E\u3067\u3001\u78BA\u304B\u3081\u308B\u8868\u306B\u306F\u8F09\u305B\u307E\u305B\u3093\u3002
233
+
234
+ - \u753B\u9762\u306E\u5927\u304D\u3055\u306F\u3001\u3069\u306E\u304F\u3089\u3044\u3092\u60F3\u5B9A\u3057\u3066\u3044\u307E\u3059\u304B: **\u30D1\u30BD\u30B3\u30F3\u306E\u753B\u9762\uFF08\u5E45 800px \u4EE5\u4E0A\uFF09**
235
+ - \u6575\u306E\u7A2E\u985E\u306F\u4F55\u7A2E\u985E\u3044\u307E\u3059\u304B: **2\uFF5E3\u7A2E\u985E**
236
+
237
+ ## \u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068 \u2015 \u30B3\u30A2\uFF08\u4F53\u9A13\uFF09
238
+
239
+ **\u3053\u306E\u9053\u5177\u3092\u4F7F\u3063\u3066\u3044\u308B\u3001\u3044\u3061\u3070\u3093\u77ED\u3044\u6642\u9593\u306B\u8D77\u304D\u308B\u3053\u3068\u3002**
240
+ \u307E\u305A\u3053\u3053\u3060\u3051\u3092\u4F5C\u308A\u307E\u3059\u3002
241
+
242
+ - \u6575\u306F\u3069\u306E\u30DA\u30FC\u30B9\u3067\u8FEB\u3063\u3066\u304D\u307E\u3059\u304B: **\u6642\u9593\u7D4C\u904E\u3068\u3068\u3082\u306B\u3001\u6BB5\u968E\u7684\u306B\u96E3\u3057\u304F\u306A\u308B**
243
+ - \u6575\u3092\u5012\u3059\u306B\u306F\u3001\u3069\u3046\u64CD\u4F5C\u3057\u307E\u3059\u304B: **\u6575\u306B\u8FD1\u3065\u304F\u3068\u81EA\u52D5\u3067\u653B\u6483\u3059\u308B**
244
+ - \u653B\u6483\u306E\u7BC4\u56F2\u306F\u3001\u3069\u306E\u6B66\u5668\u3092\u9078\u3093\u3067\u3082\u540C\u3058\u3067\u3059\u304B: **\u9078\u3093\u3060\u6B66\u5668\u3067\u7BC4\u56F2\u304C\u5909\u308F\u308B**
245
+ - \u30D7\u30EC\u30A4\u30E4\u30FC\u304C\u6575\u306B\u5F53\u305F\u308B\u3068\u3069\u3046\u306A\u308A\u307E\u3059\u304B: **\u5F53\u305F\u308B\u305F\u3073\u306BHP \u304C\u6E1B\u308A\u30010 \u306B\u306A\u308B\u3068\u30B2\u30FC\u30E0\u30AA\u30FC\u30D0\u30FC**
246
+ - \u30B2\u30FC\u30E0\u30AA\u30FC\u30D0\u30FC\u306B\u306A\u3063\u305F\u3089\u3001\u6B21\u306F\u4F55\u304C\u3067\u304D\u307E\u3059\u304B: **\u3082\u3046\u4E00\u5EA6\u3001\u6B66\u5668\u3092\u9078\u3093\u3067\u304B\u3089\u518D\u30B9\u30BF\u30FC\u30C8**
247
+ - \u30B9\u30B3\u30A2\uFF08\u751F\u304D\u6B8B\u3063\u305F\u6642\u9593\u3084\u30B9\u30B3\u30A2\uFF09\u3092\u753B\u9762\u306B\u8868\u793A\u3057\u307E\u3059\u304B: **\u5E38\u306B\u8868\u793A\u3059\u308B**
248
+ - \u30AD\u30FC\u64CD\u4F5C\u3068\u30DE\u30A6\u30B9\u64CD\u4F5C\u3001\u3069\u3061\u3089\u3067\u52D5\u304B\u3057\u307E\u3059\u304B: **\u30AD\u30FC\u30DC\u30FC\u30C9\uFF08\u77E2\u5370\u30AD\u30FC\u3084 WASD\uFF09**
249
+ - \u6B66\u5668\u306E\u9055\u3044\u306F\u3001\u653B\u6483\u7BC4\u56F2\u3060\u3051\u3067\u3059\u304B: **\u7BC4\u56F2\u3068\u3001\u6575\u3092\u5012\u3059\u901F\u3055\uFF08\u653B\u6483\u529B\uFF09\u3082\u9055\u3046**
250
+ - \u6575\u306F\u4F55\u65B9\u5411\u304B\u3089\u8FEB\u3063\u3066\u304D\u307E\u3059\u304B: **\u753B\u9762\u306E\u5168\u65B9\u5411\u304B\u3089**
251
+ - \u6575\u304C\u5012\u3055\u308C\u305F\u3068\u304D\u3001\u6575\u306E\u4F53\u304C\u6D88\u3048\u308B\u307E\u3067\u306E\u6642\u9593\u306F: **\u5C11\u3057\u6B8B\u3063\u3066\u304B\u3089\u6D88\u3048\u308B\uFF080.5\u79D2\u306A\u3069\uFF09**
252
+ - \u6575\u306F\u3059\u3079\u3066\u540C\u3058\u901F\u3055\u3067\u8FEB\u3063\u3066\u304D\u307E\u3059\u304B: **\u6575\u306E\u7A2E\u985E\u3067\u901F\u3055\u304C\u9055\u3046**
253
+ - \u30B2\u30FC\u30E0\u3092\u4E00\u6642\u505C\u6B62\u3067\u304D\u307E\u3059\u304B: **\u30AD\u30FC\u3092\u62BC\u3059\u3068\u4E00\u6642\u505C\u6B62\u3067\u304D\u308B**
254
+ - \u96E3\u3057\u304F\u306A\u308B\u30DA\u30FC\u30B9\u306F\u3001\u3069\u306E\u304F\u3089\u3044\u306E\u901F\u3055\u3067\u3059\u304B: **30\u79D2\u3054\u3068\u3001\u307E\u305F\u306F\u6575\u306E\u6570\u3067\u6BB5\u968E\u7684\u306B**
255
+ - \u6B66\u5668\u306F\u4F55\u7A2E\u985E\u304B\u3089\u9078\u3079\u307E\u3059\u304B: **3\u7A2E\u985E**
256
+ - \u30B2\u30FC\u30E0\u958B\u59CB\u6642\u306B\u3001\u9078\u3093\u3060\u6B66\u5668\u306E\u60C5\u5831\uFF08\u7BC4\u56F2\u3084\u653B\u6483\u529B\uFF09\u3092\u753B\u9762\u306B\u8868\u793A\u3057\u307E\u3059\u304B: **\u8868\u793A\u3059\u308B**
257
+ - \u6575\u304C\u540C\u6642\u306B\u753B\u9762\u4E0A\u306B\u4F55\u4F53\u304F\u3089\u3044\u3044\u307E\u3059\u304B: **\u6570\u5341\u4F53\u4EE5\u4E0A**
258
+ - \u96E3\u6613\u5EA6\u304C\u4E0A\u304C\u308B\u3068\u304D\u3001\u6575\u306E\u6570\u3092\u5897\u3084\u3057\u307E\u3059\u304B\u3001\u6575\u306E\u30B9\u30D4\u30FC\u30C9\u3092\u4E0A\u3052\u307E\u3059\u304B\u3001\u305D\u308C\u3068\u3082\u4E21\u65B9\u3067\u3059\u304B: **\u4E21\u65B9\u5897\u3084\u3059**
259
+ - \u6B66\u5668\u3054\u3068\u306E\u653B\u6483\u7BC4\u56F2\u306E\u9055\u3044\u3092\u3001\u6570\u5B57\u3067\u6559\u3048\u3066\u3082\u3089\u3048\u307E\u3059\u304B\uFF08\u4F8B\uFF1A\u5E83\u3044\uFF1D\u534A\u5F84100px\u3001\u72ED\u3044\uFF1D\u534A\u5F8450px\uFF09: **\u5927\u304D\u304F\u7570\u306A\u308B\uFF08\u4F8B\uFF1A\u534A\u5F8450px vs 100px\uFF09**
260
+ - \u6B66\u5668\u306E\u653B\u6483\u901F\u5EA6\uFF08\u6575\u3092\u5012\u3059\u307E\u3067\u306E\u6642\u9593\uFF09\u306E\u9055\u3044\u3092\u3001\u6570\u5B57\u3067\u6559\u3048\u3066\u3082\u3089\u3048\u307E\u3059\u304B: **\u901F\u3044\u6B66\u5668\u306F0.5\u79D2\u3001\u9045\u3044\u6B66\u5668\u306F1\u79D2\u306A\u3069\u3001\u660E\u78BA\u306B\u7570\u306A\u308B**
261
+ - \u30B2\u30FC\u30E0\u753B\u9762\u306E\u80CC\u666F\u306F\u3001\u4F55\u304B\u8868\u793A\u3057\u307E\u3059\u304B\uFF08\u4F8B\uFF1A\u30B0\u30EA\u30C3\u30C9\u3001\u5730\u9762\u306E\u30C6\u30AF\u30B9\u30C1\u30E3\u3001\u4F55\u3082\u306A\u3044\uFF09: **\u30B0\u30EA\u30C3\u30C9\u3084\u5E8A\u306E\u30C6\u30AF\u30B9\u30C1\u30E3\u3092\u8868\u793A**
262
+
263
+ \uFF08\u3053\u3053\u307E\u3067\u304C\u629C\u7C8B\u3067\u3059\u3002\u5B9F\u7269\u306B\u306F\u3001\u3053\u306E\u3042\u3068\u300C\u307E\u3060\u6C7A\u307E\u3063\u3066\u3044\u306A\u3044\u3053\u3068\u300D\u300C\u8ABF\u6574\u3059\u308B\u6570\u306E\u7F6E\u304D\u5834\u6240\u300D\u300C\u4F5C\u308B\u9806\u756A\u300D\u300C\u78BA\u304B\u3081\u65B9\u300D\u306A\u3069\u306E\u7BC0\u304C\u7D9A\u304D\u307E\u3059\u3002\uFF09
264
+ `}}};function ye(n,e){let t=be[n];return{\u898B\u672C:t[e]??t.ja,\u8A00\u8449:t[e]?e:"ja"}}function On(n,e,t,s,r){return s==="en"?["This is a SAMPLE. No AI was run, nothing was sent, and it cost nothing.",`Request used for this sample: ${e}`,...r?["(This sample is only available in Japanese.)"]:[],`Wrote: ${t.join(", ")}`,`To make your own, set ANTHROPIC_API_KEY (your own Anthropic key) and run: ${n.en}`].join(`
265
+ `):["\u3053\u308C\u306F\u898B\u672C\u3067\u3059\u3002AI \u306F\u52D5\u3044\u3066\u3044\u307E\u305B\u3093\uFF08\u3069\u3053\u306B\u3082\u9001\u3063\u3066\u3044\u307E\u305B\u3093\u30FB\u8CBB\u7528 0\uFF09\u3002",`\u3053\u306E\u898B\u672C\u306E\u983C\u307F: ${e}`,`\u66F8\u3044\u305F\u30D5\u30A1\u30A4\u30EB: ${t.join("\u3001")}`,`\u81EA\u5206\u306E\u983C\u307F\u3067\u4F5C\u308B\u3068\u304D\u306F\u3001ANTHROPIC_API_KEY\uFF08\u3054\u81EA\u5206\u306E Anthropic \u306E\u30AD\u30FC\uFF09\u3092\u5165\u308C\u3066\u304B\u3089: ${n.ja}`].join(`
266
+ `)}function _n(n,e,t,s){let{\u898B\u672C:r,\u8A00\u8449:i}=ye(n,e),u=n==="baton"?"kokoro-spec":`kokoro-${n}`,o=e==="en"?"-sample":"\uFF08\u898B\u672C\uFF09",c=p=>{let g=`${u}${o}${p}`;for(let m=2;s(g);m+=1)g=`${u}${o}-${m}${p}`;return g},l=[],a=c(".md");if(t(a,r.markdown),l.push(a),r.csv){let p=c(".csv");t(p,"\uFEFF"+r.csv),l.push(p)}return{\u66F8\u3044\u305F:l,\u898B\u672C:r,\u65E5\u672C\u8A9E\u3060\u3051:i!==e}}function Wn(n,e){return e==="en"?`To see a sample first (no key, no cost): ${n} --demo`:`\u307E\u305A\u898B\u672C\u3092\u898B\u308B\u3068\u304D\u306F\uFF08\u30AD\u30FC\u4E0D\u8981\u30FB\u8CBB\u7528 0\uFF09: ${n} --demo`}var T=q(require("node:fs")),P=q(require("node:path"));var tn="kokoro-spec.md";function we(n){return/ください[。..」*\s]*$/.test(n.trim())}function pn(n){return/^#\s+What to build\s*$|^##\s+(Decided\b|Not decided yet\b|How to check what was decided|.*Decisions made while building)/m.test(n)?n.split(`
267
+ `).map(t=>{let s=t.endsWith("\r")?"\r":"",r=s?t.slice(0,-1):t;return/^#\s+What to build\s*$/.test(r)?r="# \u4F5C\u3063\u3066\u307B\u3057\u3044\u3082\u306E":/^##\s+Decided\b.*periphery/i.test(r)?r="## \u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068 \u2015 \u5468\u7E01\uFF08\u6A5F\u80FD\uFF09":/^##\s+Decided\b/.test(r)?r="## \u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068 \u2015 \u30B3\u30A2\uFF08\u4F53\u9A13\uFF09":/^##\s+Not decided yet\b/.test(r)?r="## \u307E\u3060\u6C7A\u307E\u3063\u3066\u3044\u306A\u3044\u3053\u3068 \u2015 \u52DD\u624B\u306B\u6C7A\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044":/^##\s+How to check what was decided/.test(r)?r="## \u52D5\u4F5C\u78BA\u8A8D \u2015 \u6C7A\u3081\u305F\u3053\u3068\u306E\u78BA\u304B\u3081\u65B9":/^##\s+.*Decisions made while building/.test(r)?r="## \u2605\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068\u3092\u3001\u3053\u3053\u306B\u66F8\u304D\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044":/^##\s+Assumptions\b/.test(r)?r="## \u524D\u63D0 \u2015 \u4F7F\u3046\u4EBA\u30FB\u5834\u9762\uFF08\u89E6\u3063\u3066\u78BA\u304B\u3081\u308B\u884C\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09":/^###\s+Periphery\b/i.test(r)?r="### \u5468\u7E01\uFF08\u6A5F\u80FD\uFF09\u2015 \u7B2C 2 \u6BB5\u968E\u3067\u78BA\u304B\u3081\u308B":/^###\s+Core\b/i.test(r)?r="### \u30B3\u30A2\uFF08\u4F53\u9A13\uFF09":/^###\s/.test(r)?r=r.replace(/\bReport\s*:/,"\u5831\u544A:").replace(/\bAgreement\s*:/,"\u53D6\u308A\u6C7A\u3081:").replace(/\bCheck record\s*:/,"\u78BA\u8A8D\u8A18\u9332:").replace(/\(for the requester\)/i,"\uFF08\u4F9D\u983C\u3057\u305F\u4EBA\u304C\u3084\u308B\u5206\uFF09"):(r=r.replace(/^(\s+-\s+)Option\s*:/,"$1\u5019\u88DC:").replace(/^(\s+-\s+)Try\s*:/,"$1\u3084\u3063\u3066\u307F\u308B:").replace(/^(\s+-\s+)Original decision\s*:/,"$1\u3082\u3068\u306E\u6C7A\u3081\u3054\u3068:").replace(/^-\s*Decided\s*:/,"- \u6C7A\u3081\u305F\u3053\u3068:").replace(/^-\s*Why\s*:/,"- \u306A\u305C:").replace(/^-\s*Who\s*:/,"- \u8AB0\u304C:").replace(/^-\s*How\s*:/,"- \u3069\u3046\u3084\u3063\u3066:"),/^\s*[-*]\s*\[[ xX]\]/.test(r)&&(r=r.replace(/\bHow\s*:/,"\u3069\u3046\u3084\u3063\u3066:"))),r+s}).join(`
268
+ `):n}function En(n){return n.replace(/報告\s*[::]/g,"Report:").replace(/取り決め\s*[::]/g,"Agreement:").replace(/確認記録\s*[::]/g,"Check record:").replace(/(依頼した人がやる分)/g,"(for the requester)")}function Fn(n){let e={\u4F5C\u308A\u305F\u3044\u3082\u306E:null,\u4EF6\u6570:null,\u4EF6\u6570\u306E\u5143:null,\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068:[],\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068:[],\u5468\u7E01\u306E\u6C7A\u3081\u3054\u3068:[],\u59CB\u3081\u65B9:null,\u7D42\u308F\u308A\u65B9:null,\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068:[]};if(!n)return e;n=pn(n),n=n.replace(/\r\n?/g,`
269
+ `);let t=(()=>{let o=n.split(`
270
+ `),c=!1;return o.map(l=>/^\s*```/.test(l)?(c=!c,""):c?"":l)})();{let o=!1;for(let c of t){if(/^#\s/.test(c)){o=/作ってほしいもの|作りたいもの/.test(c);continue}if(/^#{2,6}\s|^---\s*$/.test(c)){if(o)break;continue}if(!o)continue;let l=c.trim();if(l){e.\u4F5C\u308A\u305F\u3044\u3082\u306E=l;break}}}for(let o of t){if(!/何件|件数|扱う|規模|曲数|人数|how many|number of|amount|volume|scale/i.test(o))continue;let c=o.match(/([0-9][0-9,,]*)\s*(件|曲|人|行|個|枚)/)??(/[぀-ヿ一-鿿]/.test(o)?null:o.match(/([0-9][0-9,]*)\+?\s*[A-Za-z]+/));if(!c)continue;let l=Number(c[1].replace(/[,,]/g,""));!Number.isFinite(l)||l<=0||(e.\u4EF6\u6570===null||l>e.\u4EF6\u6570)&&(e.\u4EF6\u6570=l,e.\u4EF6\u6570\u306E\u5143=o.trim())}let s=o=>{let c=o.match(/\*\*(.+?)\*\*/);if(c)return c[1].trim();let l=o.split(/[::]/);return(l.length>1?l.slice(1).join(":"):o).replace(/^[-\s]+/,"").trim()},r=/(どうすると始め|始められるか|始め方|どこをどう|(には|するには)[、,]?\s*どう(しますか|やって|すれば))/;for(let o of t)/^-\s/.test(o)&&(e.\u59CB\u3081\u65B9===null&&r.test(o)&&(e.\u59CB\u3081\u65B9=s(o)),e.\u7D42\u308F\u308A\u65B9===null&&/終わったら|終わりに|次に何が起き/.test(o)&&(e.\u7D42\u308F\u308A\u65B9=s(o)));let i=!1;for(let o of t){if(/^##\s/.test(o)){i=/まだ決まっていないこと/.test(o);continue}if(!i)continue;let c=o.match(/^-\s+(?!\s*候補)(.+)$/);!c||/^\s*-\s*候補/.test(o)||we(c[1])||e.\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068.push(c[1].trim())}i=!1;let u=!1;for(let o of t){if(/^##\s/.test(o)){i=/決まっていること/.test(o),u=i&&/周縁/.test(o);continue}if(!i)continue;let c=o.match(/^-\s+(.+)$/);c&&(e.\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068.push(c[1].trim()),u&&e.\u5468\u7E01\u306E\u6C7A\u3081\u3054\u3068.push(c[1].trim()))}e.\u4F5C\u308A\u305F\u3044\u3082\u306E&&e.\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068.length===1&&e.\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068[0]===e.\u4F5C\u308A\u305F\u3044\u3082\u306E&&(e.\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068=[],e.\u5468\u7E01\u306E\u6C7A\u3081\u3054\u3068=[]);{let o=[],c=!1,l=!1;for(let a of t){if(/^##\s/.test(a)){c=/動作確認/.test(a),l=!1;continue}if(!c)continue;if(/^###\s/.test(a)){l=/周縁/.test(a);continue}let p=a.match(/^-\s+\[( |x|X)\]\s+(.+)$/);if(p){o.push({\u984C:p[2].trim(),\u3084\u3063\u3066\u307F\u308B:"",\u3082\u3068:"",\u5468\u7E01:l,\u6E08:p[1]!==" "});continue}let g=a.match(/^\s+-\s+(やってみる|もとの決めごと)\s*[::]\s*(.+)$/),m=o[o.length-1];g&&m&&(g[1]==="\u3084\u3063\u3066\u307F\u308B"?m.\u3084\u3063\u3066\u307F\u308B=g[2].trim():m.\u3082\u3068=g[2].trim())}o.length&&(e.\u52D5\u4F5C\u78BA\u8A8D=o.filter(a=>a.\u984C&&a.\u3084\u3063\u3066\u307F\u308B))}{let o=!1,c=null,l=()=>{c&&(c.\u6C7A\u3081\u305F\u3053\u3068||c.\u9805\u76EE.length)&&e.\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068.push(c),c=null};for(let a of t){if(/^##\s/.test(a)){l(),o=/作りながら決めた/.test(a);continue}if(!o)continue;let p=a.match(/^###\s+(.+)$/);if(p){l(),c={\u898B\u51FA\u3057:p[1].trim(),\u6C7A\u3081\u305F\u3053\u3068:"",\u306A\u305C:"",\u88DC\u8DB3:[],\u9805\u76EE:[]};continue}if(!c)continue;let g=a.match(/^[ \t]*[-*]\s*\[([ xX])\]\s*(.+)$/);if(g){let b=g[2].replace(/^\d+[.、)]\s*/,"").trim().split(/どうやって\s*[::]/),I=b[0].replace(/[…・||\s]+$/,"").replace(/\*\*/g,"").trim();I&&c.\u9805\u76EE.push({\u6E08:g[1].toLowerCase()==="x",\u984C:I,\u3069\u3046\u3084\u3063\u3066:(b[1]??"").trim()});continue}let m=a.match(/^-\s*決めたこと\s*[::]\s*(.+)$/);if(m){c.\u6C7A\u3081\u305F\u3053\u3068=m[1].trim();continue}let h=a.match(/^-\s*なぜ\s*[::]\s*(.+)$/);if(h){c.\u306A\u305C=h[1].trim();continue}let $=a.match(/^-\s*([^::]{1,24})\s*[::]\s*(.+)$/);if($){c.\u88DC\u8DB3.push(`${$[1].trim()}: ${$[2].trim()}`);continue}let j=a.match(/^\s+(?:[-*]|\d+[.)])\s*(.+)$/);j&&c.\u88DC\u8DB3.push(j[1].trim())}l()}for(let o of e.\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068){let c=`${o.\u898B\u51FA\u3057} ${o.\u6C7A\u3081\u305F\u3053\u3068}`,l=/(件数|何件|扱う量|規模|上限|持っている|数えた|総数)/,a=/(ページ|ずつ|一度に|まとめて|分け|区切|スクロール|読み込み足)/,p=o.\u6C7A\u3081\u305F\u3053\u3068.match(/([0-9][0-9,,]*)\s*(件|曲|人|行|個|枚)/);if(p&&l.test(o.\u898B\u51FA\u3057)&&!a.test(o.\u6C7A\u3081\u305F\u3053\u3068)&&!a.test(o.\u898B\u51FA\u3057)){let $=Number(p[1].replace(/[,,]/g,""));Number.isFinite($)&&$>0&&(e.\u4EF6\u6570=$,e.\u4EF6\u6570\u306E\u5143=`\uFF08\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\uFF09${o.\u6C7A\u3081\u305F\u3053\u3068}`)}let g=o.\u898B\u51FA\u3057;o.\u6C7A\u3081\u305F\u3053\u3068&&/始め方|入口|どう始め|開き方/.test(g)&&(e.\u59CB\u3081\u65B9=o.\u6C7A\u3081\u305F\u3053\u3068),o.\u6C7A\u3081\u305F\u3053\u3068&&/終わ(り|った)|保存|セーブ|残る|残す/.test(g)&&(e.\u7D42\u308F\u308A\u65B9=o.\u6C7A\u3081\u305F\u3053\u3068);let m=$=>$.replace(/\d{4}[-/]\d{1,2}[-/]\d{1,2}/g,"").replace(/[はがをにでとのか??、。\s・「」()()]/g,""),h=m(o.\u898B\u51FA\u3057);e.\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068=e.\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068.filter($=>{let j=m($);return j.length<3?!0:h.includes(j)||j.includes(h)?!1:!m(c).includes(j)})}return e}var Nn=/^## ★(依頼した人のデザインの法則|The requester's design laws)/m;var U="// ==== PARAMS START ====",sn="// ==== PARAMS END ====",ke={ja:{\u5370\u304C\u7121\u3044:n=>`${n} \u306B\u300C${U}\u300D\u301C\u300C${sn}\u300D\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u8ABF\u6574\u3059\u308B\u6570\u3092\u3001\u3053\u306E 2 \u884C\u306E\u3042\u3044\u3060\u306E const PARAMS = { \u2026 } \u306B\u307E\u3068\u3081\u3066\u304F\u3060\u3055\u3044\uFF08kokoro-baton \u306E\u6307\u793A\u66F8\u306E\u300C\u8ABF\u6574\u3059\u308B\u6570\u306E\u7F6E\u304D\u5834\u6240\u300D\u3068\u540C\u3058\u6C7A\u307E\u308A\uFF09\u3002`,\u8AAD\u3081\u306A\u3044:(n,e)=>`${n} \u306E PARAMS \u3092\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${e}\uFF09\u30022 \u884C\u306E\u3042\u3044\u3060\u304C\u3001const PARAMS = { \u2026 } \u3060\u3051\u306B\u306A\u3063\u3066\u3044\u308B\u304B\u898B\u3066\u304F\u3060\u3055\u3044\u3002`},en:{\u5370\u304C\u7121\u3044:n=>`${n} has no "${U}" \u2026 "${sn}" block. Put the tunable numbers in const PARAMS = { \u2026 } between those two lines (the same rule as "Where tunable numbers live" in a kokoro-baton spec).`,\u8AAD\u3081\u306A\u3044:(n,e)=>`Could not read PARAMS in ${n} (${e}). Check that only const PARAMS = { \u2026 } sits between the two lines.`}},Q=n=>{let e=n.indexOf(U),t=n.indexOf(sn);return e>=0&&t>e};function on(n,e,t){let s=ke[t],r=n.indexOf(U),i=n.indexOf(sn);if(r<0||i<r)throw new Error(s.\u5370\u304C\u7121\u3044(e));let u=r+U.length,o=n.slice(u,i),c,l;try{({PARAMS:c,PARAM_LABELS:l}=new Function(`${o}
271
+ ;return { PARAMS, PARAM_LABELS: typeof PARAM_LABELS === 'undefined' ? {} : PARAM_LABELS };`)())}catch(d){throw new Error(s.\u8AAD\u3081\u306A\u3044(e,d instanceof Error?d.message:String(d)))}let a=new Map,p={},g=o.search(/const\s+PARAMS\s*=\s*\{/);g=o.indexOf("{",g);let m=[],h=null,$=null,j=0;for(;g<o.length;g++){let d=o[g];if(/\s/.test(d)||d===","){d===","&&(h=null);continue}if(o.startsWith("/*",g)){let y=o.indexOf("*/",g+2),M=o.slice(g+2,y).replace(/^\*/,"").split(`
272
+ `).map(O=>O.replace(/^\s*\*\s?/,"").trim()).filter(Boolean).join(" ");o.startsWith("/**",g)&&($=M),g=y+1;continue}if(o.startsWith("//",g)){g=o.indexOf(`
273
+ `,g);continue}if(d==="'"||d==='"'||d==="`"){g=o.indexOf(d,g+1),h=null;continue}if(d==="{"){j++,j>1&&(m.push(h),$&&(p[m.join(".")]=$,$=null)),h=null;continue}if(d==="}"){if(j--,j===0)break;m.pop(),h=null;continue}let b=o.slice(g).match(/^['"]?([A-Za-z_$][\w$]*)['"]?\s*:/);if(b&&!h){h=b[1],g+=b[0].length-1;continue}let I=o.slice(g).match(/^-?\d+(\.\d+)?(e-?\d+)?/i);if(I&&h){let y=[...m,h].join(".");a.set(y,[u+g,u+g+I[0].length]),$&&(p[y]=$,$=null),g+=I[0].length-1,h=null;continue}}return{PARAMS:c,PARAM_LABELS:l,\u4F4D\u7F6E:a,\u7406\u7531:p}}var D=(n,e)=>e.split(".").reduce((t,s)=>t==null?t:t[s],n);function fn(n,e="",t=[]){for(let[s,r]of Object.entries(n)){let i=e?`${e}.${s}`:s;typeof r=="number"?t.push([i,r]):r&&typeof r=="object"&&fn(r,i,t)}return t}function mn(n,e="",t=[]){let s=Object.entries(n).filter(([,r])=>r&&typeof r=="object");if(s.length>=2&&s.length===Object.keys(n).length){let r=Object.keys(s[0][1]).filter(i=>s.every(([,u])=>typeof u[i]=="number"));r.length&&t.push({\u9053:e,\u5B50:s.map(([i])=>i),\u9375:r})}for(let[r,i]of s)mn(i,e?`${e}.${r}`:r,t);return t}function Kn(n,e){let t=n.split(`
274
+ `),s=t.findIndex(i=>/^##\s/.test(i)&&e.test(i));if(s<0)return"";let r=t.findIndex((i,u)=>u>s&&/^##\s/.test(i));return t.slice(s+1,r<0?void 0:r).join(`
275
+ `)}function rn(n){let e=/^#\s+What to build\s*$/m.test(n),t=pn(n.replace(/\r\n/g,`
276
+ `)),s=Fn(t),i=(Kn(t,/★これができたら合格|★Done when this works/).trim().split(/\n\s*\n/)[0]??"").trim(),u=i&&!/^[※★((]/.test(i)?i:"",o=Kn(t,/^##\s+前提/).split(`
277
+ `).map(a=>a.match(/^- (.+)$/)?.[1]?.trim()).filter(a=>!!a),c=(()=>{let a=t.search(Nn);if(a<0)return[];let p=t.slice(a+3),g=p.search(/^## /m);return(g<0?p:p.slice(0,g)).split(`
278
+ `).map(m=>m.match(/^\d+\.\s+(.+)$/)?.[1]?.trim()).filter(m=>!!m)})(),l=new Set(s.\u5468\u7E01\u306E\u6C7A\u3081\u3054\u3068);return{\u82F1\u8A9E:e,\u4F5C\u308B\u3082\u306E:s.\u4F5C\u308A\u305F\u3044\u3082\u306E??"",\u5408\u683C:u,\u524D\u63D0:o,\u30B3\u30A2:s.\u6C7A\u307E\u3063\u3066\u3044\u308B\u3053\u3068.filter(a=>!l.has(a)),\u5468\u7E01:s.\u5468\u7E01\u306E\u6C7A\u3081\u3054\u3068,\u672A\u5B9A:s.\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068,\u4F5C\u308A\u306A\u304C\u3089:s.\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068,\u78BA\u304B\u3081\u65B9:(s.\u52D5\u4F5C\u78BA\u8A8D??[]).map(a=>({\u984C:a.\u984C,\u3084\u3063\u3066\u307F\u308B:a.\u3084\u3063\u3066\u307F\u308B,\u5468\u7E01:a.\u5468\u7E01})),\u6CD5\u5247:c}}var Dn=n=>!n.\u5408\u683C&&!n.\u524D\u63D0.length&&!n.\u30B3\u30A2.length&&!n.\u5468\u7E01.length&&!n.\u78BA\u304B\u3081\u65B9.length,Ae=n=>n.replace(/\*\*/g,""),Yn=n=>/見た目の値|Look values/i.test(n);function Bn(n,e){let t=[...n.\u524D\u63D0,...n.\u30B3\u30A2,...n.\u5468\u7E01].map(r=>`\u30FB${Ae(r)}`),s=n.\u4F5C\u308A\u306A\u304C\u3089.filter(r=>!Yn(r.\u898B\u51FA\u3057)&&r.\u6C7A\u3081\u305F\u3053\u3068).map(r=>`\u30FB${r.\u898B\u51FA\u3057}: ${r.\u6C7A\u3081\u305F\u3053\u3068}`);return n.\u82F1\u8A9E?['From the material below, write only two sections of a spec that the client will read: "Overview" and "Design approach".',"The list of decisions, the number tables and the checks are copied as they are into other sections, so do not write them here. Avoid writing numbers as much as you can.","",`What to build: ${n.\u4F5C\u308B\u3082\u306E}`,n.\u5408\u683C?`Done when: ${n.\u5408\u683C}`:"","",t.length?`Decided:
279
+ ${t.join(`
280
+ `)}`:"",s.length?`
281
+ Decided while building:
282
+ ${s.join(`
283
+ `)}`:"",e.length?`
284
+ Why the numbers are what they are (code comments):
285
+ ${e.map(r=>`\u30FB${r}`).join(`
286
+ `)}`:""].filter((r,i,u)=>r!==""||u[i-1]!=="").join(`
287
+ `).trim():["\u6B21\u306E\u6750\u6599\u304B\u3089\u3001\u4F9D\u983C\u4E3B\u304C\u8AAD\u3080\u4ED5\u69D8\u66F8\u306E\u300C\u6982\u8981\u300D\u3068\u300C\u8A2D\u8A08\u306E\u8003\u3048\u65B9\u300D\u306E 2 \u7BC0\u3060\u3051\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002","\u6C7A\u3081\u305F\u3053\u3068\u306E\u4E00\u89A7\u30FB\u6570\u306E\u8868\u30FB\u78BA\u304B\u3081\u308B\u9805\u76EE\u306F\u3001\u5225\u306E\u7BC0\u306B\u305D\u306E\u307E\u307E\u8F09\u305B\u308B\u306E\u3067\u3001\u3053\u3053\u306B\u306F\u66F8\u304B\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\u6570\u5B57\u3082\u3067\u304D\u308B\u3060\u3051\u66F8\u304B\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002","",`\u4F5C\u308B\u3082\u306E: ${n.\u4F5C\u308B\u3082\u306E}`,n.\u5408\u683C?`\u3053\u308C\u304C\u3067\u304D\u305F\u3089\u5408\u683C: ${n.\u5408\u683C}`:"","",t.length?`\u6C7A\u3081\u305F\u3053\u3068:
288
+ ${t.join(`
289
+ `)}`:"",s.length?`
290
+ \u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068:
291
+ ${s.join(`
292
+ `)}`:"",e.length?`
293
+ \u6570\u3092\u6C7A\u3081\u305F\u3068\u304D\u306E\u7406\u7531\uFF08\u30B3\u30FC\u30C9\u306E\u30B3\u30E1\u30F3\u30C8\uFF09:
294
+ ${e.map(r=>`\u30FB${r}`).join(`
295
+ `)}`:""].filter((r,i,u)=>r!==""||u[i-1]!=="").join(`
296
+ `).trim()}function Hn(n,e){let t=n.replace(/\r\n/g,`
297
+ `).split(`
298
+ `).filter(i=>!/^#\s/.test(i)),s=[];for(let i of t){let u=i.match(/^#{2,3}\s+(.+?)\s*$/);if(u&&(/^##\s/.test(i)||!s.length)){s.push({\u898B\u51FA\u3057:u[1].replace(/^[0-90-9]+[..、\s]\s*/,"").trim(),\u672C\u6587:[]});continue}if(!s.length){i.trim()&&s.push({\u898B\u51FA\u3057:e?"Overview":"\u6982\u8981",\u672C\u6587:[i]});continue}s[s.length-1].\u672C\u6587.push(i)}let r=i=>({\u898B\u51FA\u3057:i.\u898B\u51FA\u3057,\u672C\u6587:i.\u672C\u6587.join(`
299
+ `).trim()});return{\u7BC0:s.slice(0,2).map(r).filter(i=>i.\u672C\u6587),\u6368\u3066\u305F:s.slice(2).map(i=>i.\u898B\u51FA\u3057)}}function zn(n,e,t){let s=o=>e[o]??o,r=[],i=new Set;for(let o of mn(n)){let c=D(n,o.\u9053);r.push({\u984C:String(s(o.\u9053.split(".").pop())),\u898B\u51FA\u3057:[t?"Field":"\u9805\u76EE",...o.\u5B50.map(l=>String(c[l].name??l))],\u884C:o.\u9375.map(l=>[s(l),...o.\u5B50.map(a=>(i.add(`${o.\u9053}.${a}.${l}`),c[a][l]))])})}let u=fn(n).filter(([o])=>!i.has(o));return u.length&&r.push({\u984C:t?"Other numbers":"\u305D\u306E\u307B\u304B\u306E\u6570",\u898B\u51FA\u3057:t?["Group","Name","Value"]:["\u307E\u3068\u307E\u308A","\u540D\u524D","\u5024"],\u884C:u.map(([o,c])=>{let l=o.split("."),a=l.length>2?D(n,l.slice(0,-1).join("."))?.name??l[l.length-2]:"";return[l.length>1?s(l[0]):"",`${a?`${a} `:""}${s(l[l.length-1])}`,c]})}),r}var Cn=n=>String(n).replace(/\|/g,"\\|").replace(/\n/g," "),dn=(n,e)=>[`| ${n.map(Cn).join(" | ")} |`,`|${n.map(()=>" --- ").join("|")}|`,...e.map(t=>`| ${t.map(Cn).join(" | ")} |`)].join(`
300
+ `);function $n(n){let e=!1,t=[];for(let s of n.replace(/\r\n/g,`
301
+ `).split(`
302
+ `)){if(/^\s*```/.test(s)){e=!e;continue}if(e)continue;let r=s.match(/^- (.+: \*\*.+\*\*)\s*$/);r&&!t.includes(r[1])&&t.push(r[1])}return t}var bn=n=>[...new Set(n.replace(/[0-9]/g,e=>String.fromCharCode(e.charCodeAt(0)-65248)).replace(/^(\s*)\d+[.).)]\s+/gm,"$1").match(/\d+(?:\.\d+)?/g)??[])],Ln=bn;function xe(n){let{\u6750\u6599:e}=n,t=e.\u82F1\u8A9E,s=[],r=0,i=c=>{r+=1,s.push("",`## ${r} ${c}`,"")},u=c=>s.push("",`### ${c}`,""),o=c=>c.forEach(l=>s.push(`- ${l}`));for(let c of n.Writer\u7BC0)i(c.\u898B\u51FA\u3057),s.push(c.\u672C\u6587);if(i(t?"Done when this works":"\u3053\u308C\u304C\u3067\u304D\u305F\u3089\u5408\u683C"),s.push(e.\u5408\u683C?`**${e.\u5408\u683C}**`:t?"(Not written in the spec yet.)":"\uFF08\u6307\u793A\u66F8\u306B\u307E\u3060\u66F8\u304B\u308C\u3066\u3044\u307E\u305B\u3093\uFF09"),i(t?"Decisions":"\u6C7A\u3081\u305F\u3053\u3068"),e.\u524D\u63D0.length&&(u(t?"Who uses it and where (assumptions)":"\u4F7F\u3046\u4EBA\u30FB\u5834\u9762\uFF08\u524D\u63D0\uFF09"),o(e.\u524D\u63D0)),e.\u30B3\u30A2.length&&(u(t?"Built first (core = the experience)":"\u3044\u3061\u3070\u3093\u5148\u306B\u4F5C\u308B\u90E8\u5206\uFF08\u30B3\u30A2\uFF1D\u4F53\u9A13\uFF09"),o(e.\u30B3\u30A2)),e.\u5468\u7E01.length&&(u(t?"Built later (periphery = features)":"\u3042\u3068\u3067\u4F5C\u308B\u90E8\u5206\uFF08\u5468\u7E01\uFF1D\u6A5F\u80FD\uFF09"),o(e.\u5468\u7E01)),e.\u4F5C\u308A\u306A\u304C\u3089.length){u(t?"Decided while building":"\u4F5C\u308A\u306A\u304C\u3089\u6C7A\u3081\u305F\u3053\u3068");for(let c of e.\u4F5C\u308A\u306A\u304C\u3089){let l=t?En(c.\u898B\u51FA\u3057):c.\u898B\u51FA\u3057;if(s.push(`**${l}**`,""),Yn(c.\u898B\u51FA\u3057)){s.push(t?'- The look values (see "Look" below)':"- \u898B\u305F\u76EE\u306E\u5024\uFF08\u300C\u898B\u305F\u76EE\u300D\u306E\u7BC0\uFF09","");continue}c.\u6C7A\u3081\u305F\u3053\u3068&&s.push(`- ${t?"Decided":"\u6C7A\u3081\u305F\u3053\u3068"}: ${c.\u6C7A\u3081\u305F\u3053\u3068}`),c.\u306A\u305C&&s.push(`- ${t?"Why":"\u306A\u305C"}: ${c.\u306A\u305C}`),c.\u88DC\u8DB3.filter(a=>!/^```|STYLE (START|END)|^--[\w-]+\s*:/.test(a.trim())).forEach(a=>s.push(`- ${a.replace(/^-\s*/,"")}`)),c.\u9805\u76EE.forEach(a=>s.push(`- [${a.\u6E08?"x":" "}] ${a.\u984C}${a.\u3069\u3046\u3084\u3063\u3066?` \u2014 ${a.\u3069\u3046\u3084\u3063\u3066}`:""}`)),s.push("")}}if(i(t?"Not decided yet":"\u307E\u3060\u6C7A\u3081\u3066\u3044\u306A\u3044\u3053\u3068"),e.\u672A\u5B9A.length?o(e.\u672A\u5B9A):s.push(t?"Nothing is listed. Things may simply not have been asked yet.":"\u4E00\u89A7\u306B\u6319\u304C\u3063\u3066\u3044\u308B\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u305F\u3060\u3057\u300C\u805E\u304B\u308C\u3066\u3044\u306A\u3044\u3060\u3051\u300D\u306E\u3053\u3068\u306F\u3042\u308A\u3048\u307E\u3059\u3002"),(n.\u898B\u305F\u76EE?.\u5024\u305F\u3061.length||e.\u6CD5\u5247.length)&&(i(t?"Look":"\u898B\u305F\u76EE"),n.\u898B\u305F\u76EE?.\u5024\u305F\u3061.length&&(u(t?`Look values (from ${n.\u898B\u305F\u76EE.\u3082\u3068})`:`\u898B\u305F\u76EE\u306E\u5024\uFF08\u3082\u3068: ${n.\u898B\u305F\u76EE.\u3082\u3068}\uFF09`),s.push(dn(t?["Name","Value","Used for"]:["\u540D\u524D","\u5024","\u4F55\u306B\u4F7F\u3046\u304B"],n.\u898B\u305F\u76EE.\u5024\u305F\u3061.map(c=>[`--${c.\u540D\u524D}`,c.\u5024,c.\u610F\u5473])))),e.\u6CD5\u5247.length&&(u(t?"The requester's design laws":"\u4F9D\u983C\u3057\u305F\u4EBA\u306E\u30C7\u30B6\u30A4\u30F3\u306E\u6CD5\u5247"),e.\u6CD5\u5247.forEach((c,l)=>s.push(`${l+1}. ${c}`)))),n.\u6570?.\u8868\u305F\u3061.length){i(t?"Numbers (parameters)":"\u6570\uFF08\u30D1\u30E9\u30E1\u30FC\u30BF\uFF09"),s.push(t?`> The values of PARAMS in ${n.\u6570.\u30D5\u30A1\u30A4\u30EB}, as they are. To change a number, use \`npx kokoro-kami params ${n.\u6570.\u30D5\u30A1\u30A4\u30EB}\` (edit the table and send it back), or edit ${n.\u6570.\u30D5\u30A1\u30A4\u30EB}.`:`> ${n.\u6570.\u30D5\u30A1\u30A4\u30EB} \u306E PARAMS \u306E\u5024\u3092\u305D\u306E\u307E\u307E\u4E26\u3079\u3066\u3044\u307E\u3059\u3002\u6570\u3092\u5909\u3048\u308B\u3068\u304D\u306F\u3001\`npx kokoro-kami params ${n.\u6570.\u30D5\u30A1\u30A4\u30EB}\` \u306E\u8868\u3067\u76F4\u3057\u3066\u623B\u3059\u304B\u3001${n.\u6570.\u30D5\u30A1\u30A4\u30EB} \u3092\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);for(let c of n.\u6570.\u8868\u305F\u3061)u(c.\u984C),s.push(dn(c.\u898B\u51FA\u3057,c.\u884C))}if(e.\u78BA\u304B\u3081\u65B9.length){i(t?"How to check it is done":"\u3067\u304D\u305F\u304B\u3069\u3046\u304B\u306E\u78BA\u304B\u3081\u65B9"),s.push(t?"After building, check by doing these.":"\u4F5C\u3063\u305F\u3042\u3068\u306B\u3001\u3053\u306E\u624B\u9806\u3067\u62BC\u3057\u3066\u78BA\u304B\u3081\u307E\u3059\u3002","");let c=t?" (periphery)":"\uFF08\u5468\u7E01\uFF09";s.push(dn(t?["What you should see","What to do"]:["\u898B\u3048\u308C\u3070\u3088\u3044\u3053\u3068","\u3084\u3063\u3066\u307F\u308B\u3053\u3068"],e.\u78BA\u304B\u3081\u65B9.map(l=>[`${l.\u984C}${l.\u5468\u7E01?c:""}`,l.\u3084\u3063\u3066\u307F\u308B])))}return s.join(`
303
+ `).replace(/\n{3,}/g,`
304
+
305
+ `).trim()}function qn(n,e,t=[]){let{\u6750\u6599:s}=n,r=s.\u82F1\u8A9E,i=xe(n),u=[s.\u5408\u683C,...$n(n.\u6307\u793A\u66F8)].filter(m=>m&&!i.includes(m)),o=new Set(Ln(e)),c=Ln(n.Writer\u7BC0.map(m=>m.\u672C\u6587).join(`
306
+ `)).filter(m=>!o.has(m)),l={\u629C\u3051:u,\u6750\u6599\u306B\u7121\u3044\u6570:c,\u6368\u3066\u305F\u7BC0:t},a=[n.\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB,n.\u6570?.\u30D5\u30A1\u30A4\u30EB,n.\u898B\u305F\u76EE&&n.\u898B\u305F\u76EE.\u3082\u3068!==n.\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB?n.\u898B\u305F\u76EE.\u3082\u3068:null].filter((m,h,$)=>!!m&&$.indexOf(m)===h).join("\u30FB"),p=[r?"# Spec (for people to read)":"# \u4ED5\u69D8\u66F8\uFF08\u4EBA\u304C\u8AAD\u3080\u7248\uFF09",""];p.push(r?`> Made on: ${n.\u65E5\u4ED8} / from: ${a}
307
+ > This document is for reading. To change something, edit ${n.\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB} and the code, then make it again (\`npx kokoro-writer spec-doc\`).
308
+ > \u2605The first ${n.Writer\u7BC0.length} section${n.Writer\u7BC0.length===1?"":"s"} ${n.Writer\u7BC0.length===1?"was":"were"} written by AI (Kokoro OS Writer). Everything after that is copied from the spec and the code without going through AI.`:`> \u4F5C\u3063\u305F\u65E5: ${n.\u65E5\u4ED8} \uFF0F \u3082\u3068: ${a}
309
+ > \u3053\u306E\u6587\u66F8\u306F\u8AAD\u3080\u305F\u3081\u306E\u3082\u306E\u3067\u3059\u3002\u76F4\u3059\u3068\u304D\u306F ${n.\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB} \u3068\u30B3\u30FC\u30C9\u3092\u76F4\u3057\u3066\u3001\u4F5C\u308A\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\`npx kokoro-writer spec-doc\`\uFF09\u3002
310
+ > \u2605${n.Writer\u7BC0.map((m,h)=>`\u300C${h+1} ${n.Writer\u7BC0[h].\u898B\u51FA\u3057}\u300D`).join("")}\u306F AI\uFF08Kokoro OS \u306E Writer\uFF09\u304C\u66F8\u3044\u305F\u6587\u7AE0\u3067\u3059\u3002\u305D\u3053\u304B\u3089\u5F8C\u306F\u3001\u6307\u793A\u66F8\u3068\u30B3\u30FC\u30C9\u304B\u3089 AI \u3092\u901A\u3055\u305A\u306B\u5199\u3057\u3066\u3044\u307E\u3059\u3002`);let g=[];return u.length&&g.push(r?`Decisions from the spec that are not in this document word for word: ${u.join(" / ")}`:`\u6307\u793A\u66F8\u306E\u6C7A\u3081\u305F\u3053\u3068\u306E\u3046\u3061\u3001\u3053\u306E\u6587\u66F8\u306B\u6587\u5B57\u3069\u304A\u308A\u5165\u3063\u3066\u3044\u306A\u3044\u3082\u306E: ${u.join("\uFF0F")}`),c.length&&g.push(r?`Numbers in the AI-written text that are not in the material: ${c.join(", ")} (it may be a rewording, like 0.5 \u2192 50%; check the sentence)`:`AI \u304C\u66F8\u3044\u305F\u6587\u7AE0\u306E\u4E2D\u306E\u3001\u6750\u6599\u306B\u7121\u3044\u6570: ${c.join("\u30FB")}\uFF08\u300C0.5\u300D\u3092\u300C50%\u300D\u3068\u8A00\u3044\u63DB\u3048\u305F\u3060\u3051\u306E\u3053\u3068\u3082\u3042\u308A\u307E\u3059\u3002\u305D\u306E\u6587\u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\uFF09`),t.length&&g.push(r?`The AI also wrote other sections; they were left out (they would repeat the copied sections): ${t.join(" / ")}`:`AI \u304C\u307B\u304B\u306E\u7BC0\u3082\u66F8\u3044\u3066\u3044\u305F\u306E\u3067\u3001\u8F09\u305B\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5199\u3057\u305F\u7BC0\u3068\u4E8C\u91CD\u306B\u306A\u308B\u305F\u3081\uFF09: ${t.join("\uFF0F")}`),g.length&&p.push("",`> \u2605${r?"Found when checking (no AI)":"\u7167\u3089\u3057\u5408\u308F\u305B\u3067\u5F15\u3063\u304B\u304B\u3063\u305F\u3053\u3068\uFF08AI \u306A\u3057\uFF09"}:`,...g.map(m=>`> - ${m}`)),s.\u4F5C\u308B\u3082\u306E&&p.push("",`**${r?"What to build":"\u4F5C\u308B\u3082\u306E"}:** ${s.\u4F5C\u308B\u3082\u306E}`),{md:`${p.join(`
311
+ `)}
312
+
313
+ ${i}
314
+ `,\u7167\u3089\u3057\u5408\u308F\u305B:l}}var J="/* ==== STYLE START ==== */",Gn="/* ==== STYLE END ==== */";function cn(n){let e=new Map,t=!1,s=0;for(;;){let r=n.indexOf(J,s);if(r<0)break;let i=n.indexOf(Gn,r+J.length);if(i<0)break;t=!0;let u=n.slice(r+J.length,i);for(let o of u.matchAll(/--([A-Za-z0-9_-]+)\s*:\s*([^;]+?)\s*;[ \t]*(?:\/\*\s*([\s\S]*?)\s*\*\/)?/g))e.set(o[1],{\u540D\u524D:o[1],\u5024:o[2].trim(),\u610F\u5473:(o[3]??"").trim()});s=i+Gn.length}return t?[...e.values()]:null}var Se="<!-- kokoro-made: ";function an(n){let e=n.replace(/\r\n/g,`
315
+ `),t=s=>{let r=s>>>0;for(let i=0;i<e.length;i++)r^=e.charCodeAt(i),r=Math.imul(r,16777619)>>>0;return r.toString(16).padStart(8,"0")};return t(2166136261)+t(2538058380)}var je=n=>`${Se}${JSON.stringify(n)} -->`;function ln(n,e){return`${je(e)}
316
+ ${Ie(n)}`}function Ie(n){return n.replace(/^?<!-- kokoro-made: [\s\S]*? -->\r?\n?/,"")}var un=()=>new Date().toLocaleDateString("sv-SE");var Re={ja:{\u4ED5\u69D8\u304C\u7121\u3044:n=>`\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: ${n}
317
+ \uFF08npx kokoro-baton \u3067\u4F5C\u3063\u305F kokoro-spec.md \u306E\u3042\u308B\u30D5\u30A9\u30EB\u30C0\u3067\u52D5\u304B\u3059\u304B\u3001\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u3057\u3066\u304F\u3060\u3055\u3044\uFF09`,\u8AAD\u3081\u306A\u3044:n=>`${n} \u304B\u3089\u3001\u5408\u683C\u30FB\u6C7A\u3081\u305F\u3053\u3068\u30FB\u78BA\u304B\u3081\u65B9\u306E\u3069\u308C\u3082\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F\u3002kokoro-baton \u306E\u6307\u793A\u66F8\u306E\u5F62\u304B\u898B\u3066\u304F\u3060\u3055\u3044\uFF08AI \u306B\u306F\u983C\u3093\u3067\u3044\u307E\u305B\u3093\uFF09\u3002`,\u6570:(n,e,t)=>`\u6570\uFF08PARAMS\uFF09: ${n}\uFF08\u8868 ${e} \u3064\uFF09${t.length?`\u3000\u307B\u304B\u306B\u3082 PARAMS \u306E\u3042\u308B\u30D5\u30A1\u30A4\u30EB: ${t.join("\u30FB")}\uFF08--code \u3067\u9078\u3079\u307E\u3059\uFF09`:""}`,\u6570\u306A\u3057:"\u6570\uFF08PARAMS\uFF09: \u898B\u3064\u304B\u3089\u306A\u3044\u306E\u3067\u3001\u6570\u306E\u7BC0\u306F\u51FA\u3057\u307E\u305B\u3093",\u6570\u304C\u8AAD\u3081\u306A\u3044:n=>`\u2605${n}\uFF08\u6570\u306E\u7BC0\u306F\u51FA\u3057\u307E\u305B\u3093\uFF09`,\u898B\u305F\u76EE:(n,e)=>`\u898B\u305F\u76EE\u306E\u5024: ${n}\uFF08${e} \u500B\uFF09`,\u898B\u305F\u76EE\u306A\u3057:"\u898B\u305F\u76EE\u306E\u5024: \u898B\u3064\u304B\u3089\u306A\u3044\u306E\u3067\u3001\u898B\u305F\u76EE\u306E\u5024\u306F\u51FA\u3057\u307E\u305B\u3093",\u983C\u3080:n=>`Writer \u306B\u300C\u6982\u8981\u300D\u300C\u8A2D\u8A08\u306E\u8003\u3048\u65B9\u300D\u3092\u983C\u3093\u3067\u3044\u307E\u3059\u2026\uFF08\u6750\u6599 ${n} \u5B57\uFF09`,\u66F8\u3044\u305F:n=>`\u66F8\u304D\u307E\u3057\u305F: ${n}`,\u5185\u8A33:(n,e)=>`\u5199\u3057\u305F\u3082\u306E: \u6C7A\u3081\u305F\u3053\u3068 ${n}\u30FB\u78BA\u304B\u3081\u65B9 ${e}\uFF08AI \u3092\u901A\u3057\u3066\u3044\u307E\u305B\u3093\uFF09`,\u7167ok:"\u7167\u3089\u3057\u5408\u308F\u305B\uFF08AI \u306A\u3057\uFF09: \u6C7A\u3081\u305F\u3053\u3068\u306F\u5168\u90E8\u3001\u6587\u5B57\u3069\u304A\u308A\u5165\u3063\u3066\u3044\u307E\u3059\u3002AI \u306E\u6587\u306B\u3001\u6750\u6599\u306B\u7121\u3044\u6570\u306F\u3042\u308A\u307E\u305B\u3093\u3002",\u7167ng:"\u2605\u7167\u3089\u3057\u5408\u308F\u305B\u3067\u5F15\u3063\u304B\u304B\u3063\u305F\u3053\u3068\uFF08\u6587\u66F8\u306E\u5148\u982D\u306B\u3082\u66F8\u304D\u307E\u3057\u305F\uFF09:",\u629C\u3051:n=>` \u30FB\u6587\u5B57\u3069\u304A\u308A\u5165\u3063\u3066\u3044\u306A\u3044\u6C7A\u3081\u305F\u3053\u3068: ${n.join("\uFF0F")}`,\u7121\u3044\u6570:n=>` \u30FBAI \u306E\u6587\u306E\u4E2D\u306E\u3001\u6750\u6599\u306B\u7121\u3044\u6570: ${n.join("\u30FB")}\uFF08\u8A00\u3044\u63DB\u3048\u306E\u3053\u3068\u3082\u3042\u308A\u307E\u3059\u3002\u305D\u306E\u6587\u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\uFF09`,\u6368\u3066\u305F:n=>` \u30FBAI \u304C\u307B\u304B\u306E\u7BC0\u3082\u66F8\u3044\u3066\u3044\u305F\u306E\u3067\u8F09\u305B\u307E\u305B\u3093\u3067\u3057\u305F: ${n.join("\uFF0F")}`,\u78BA\u304B\u3081\u3069\u3053\u308D:"\u2605Writer \u304C\u300C\u5165\u308C\u305F\u6750\u6599\u306B\u7121\u3044\u3053\u3068\u300D\u3068\u3057\u3066\u6319\u3052\u305F\u3082\u306E:"},en:{\u4ED5\u69D8\u304C\u7121\u3044:n=>`Spec file not found: ${n}
318
+ (Run in the folder that has the kokoro-spec.md made with npx kokoro-baton, or point to the file.)`,\u8AAD\u3081\u306A\u3044:n=>`Could not read the done-when line, decisions or checks from ${n}. Check that it is a kokoro-baton spec (nothing was sent to AI).`,\u6570:(n,e,t)=>`Numbers (PARAMS): ${n} (${e} table${e===1?"":"s"})${t.length?` Other files with PARAMS: ${t.join(", ")} (choose with --code)`:""}`,\u6570\u306A\u3057:"Numbers (PARAMS): none found, so there is no numbers section",\u6570\u304C\u8AAD\u3081\u306A\u3044:n=>`\u2605${n} (no numbers section)`,\u898B\u305F\u76EE:(n,e)=>`Look values: ${n} (${e})`,\u898B\u305F\u76EE\u306A\u3057:"Look values: none found, so they are left out",\u983C\u3080:n=>`Asking Writer for "Overview" and "Design approach"\u2026 (material: ${n} characters)`,\u66F8\u3044\u305F:n=>`Written: ${n}`,\u5185\u8A33:(n,e)=>`Copied: ${n} decisions, ${e} checks (not through AI)`,\u7167ok:"Check (no AI): every decision is in, word for word. No numbers in the AI text that are not in the material.",\u7167ng:"\u2605Found when checking (also written at the top of the document):",\u629C\u3051:n=>` - Decisions not in word for word: ${n.join(" / ")}`,\u7121\u3044\u6570:n=>` - Numbers in the AI text that are not in the material: ${n.join(", ")} (it may be a rewording; check the sentence)`,\u6368\u3066\u305F:n=>` - The AI also wrote other sections; left out: ${n.join(" / ")}`,\u78BA\u304B\u3081\u3069\u3053\u308D:"\u2605Things Writer flagged as not in the material:"}},Pe=new Set(["node_modules",".git",".next","dist","build","out",".vercel","coverage",".turbo",".cache"]),Te=/\.(css|scss|sass|less|html?|tsx?|jsx?|mjs|cjs|vue|svelte|astro)$/i;function Jn(n,e){let t=[],s=0,r=(u,o)=>{if(!(o>5))for(let c of T.default.readdirSync(u,{withFileTypes:!0}).sort((l,a)=>l.name.localeCompare(a.name))){if(++s>2e4)return;let l=P.default.join(u,c.name);if(c.isDirectory()){!Pe.has(c.name)&&!c.name.startsWith(".")&&r(l,o+1);continue}if(Te.test(c.name))try{T.default.statSync(l).size<3e6&&e(T.default.readFileSync(l,"utf8"))&&t.push(l)}catch{}}};r(n,0);let i=u=>/^check\.html?$/i.test(P.default.basename(u));return[...t.filter(u=>!i(u)),...t.filter(i)]}async function Zn(n){let e=Re[n.\u8A00\u8449],t=P.default.resolve(n.\u7D20||"."),s=T.default.existsSync(t)&&T.default.statSync(t).isFile()?t:P.default.join(t,tn);if(!T.default.existsSync(s))throw new Error(e.\u4ED5\u69D8\u304C\u7121\u3044(s));let r=P.default.dirname(s),i=w=>P.default.relative(r,w).replace(/\\/g,"/")||P.default.basename(w),u=T.default.readFileSync(s,"utf8"),o=rn(u);if(Dn(o))throw new Error(e.\u8AAD\u3081\u306A\u3044(i(s)));let c=null,l=[],a=n.\u5024("--code")?[P.default.resolve(n.\u5024("--code"))]:Jn(r,Q);if(a.length)try{let w=on(T.default.readFileSync(a[0],"utf8"),P.default.basename(a[0]),n.\u8A00\u8449);c={\u8868\u305F\u3061:zn(w.PARAMS,w.PARAM_LABELS,o.\u82F1\u8A9E),\u30D5\u30A1\u30A4\u30EB:i(a[0])},l=Object.values(w.\u7406\u7531),console.log(e.\u6570(c.\u30D5\u30A1\u30A4\u30EB,c.\u8868\u305F\u3061.length,a.slice(1).map(i)))}catch(w){console.log(e.\u6570\u304C\u8AAD\u3081\u306A\u3044(w instanceof Error?w.message:String(w)))}else console.log(e.\u6570\u306A\u3057);let p=n.\u5024("--code")&&T.default.readFileSync(P.default.resolve(n.\u5024("--code")),"utf8").includes(J)?P.default.resolve(n.\u5024("--code")):Jn(r,w=>w.includes(J)&&!!cn(w)?.length)[0],g=cn(u)??[],m=p?{\u5024\u305F\u3061:cn(T.default.readFileSync(p,"utf8"))??[],\u3082\u3068:i(p)}:g.length?{\u5024\u305F\u3061:g,\u3082\u3068:i(s)}:null;console.log(m?e.\u898B\u305F\u76EE(m.\u3082\u3068,m.\u5024\u305F\u3061.length):e.\u898B\u305F\u76EE\u306A\u3057);let h=P.default.resolve(n.\u5024("--out")??P.default.join(r,"spec-for-readers.md"));if(T.default.existsSync(h)){if(n.\u5F15\u6570.includes("--yes")){let{dir:w,name:K,ext:Z}=P.default.parse(h);for(let X=2;T.default.existsSync(h);X+=1)h=P.default.join(w,`${K}-${X}${Z}`)}else if(!(await n.\u805E\u304F(n.t.\u4E0A\u66F8\u304D(h))).trim().toLowerCase().startsWith("y")){console.log(n.t.\u3084\u3081\u305F);return}}let $=Bn(o,l);console.log(`
319
+ `+e.\u983C\u3080($.length));let j=n.\u5024("--model"),d=await fetch(`${n.\u7A93\u53E3\u306E\u5143}/api/v1/writer`,{method:"POST",headers:{"Content-Type":"application/json",...n.\u30AD\u30FC.\u898B\u51FA\u3057,"user-agent":`kokoro-writer/${n.\u7248}`},body:JSON.stringify({text:$,lang:o.\u82F1\u8A9E?"en":"ja",format:"spec",...j?{model:j}:{}}),signal:AbortSignal.timeout(3e5)}),b=await d.json().catch(()=>({}));if(!d.ok||!b.markdown){let w=typeof b.error=="string"?b.error:b.error?.message;throw new Error(w||`HTTP ${d.status}`)}let I=en(b,o.\u82F1\u8A9E?"en":"ja");I&&console.log(I);let y=Hn(b.markdown,o.\u82F1\u8A9E),M=qn({\u6750\u6599:o,Writer\u7BC0:y.\u7BC0,\u898B\u305F\u76EE:m,\u6570:c,\u6307\u793A\u66F8:u,\u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB:i(s),\u65E5\u4ED8:new Date().toLocaleDateString("sv-SE")},$,y.\u6368\u3066\u305F),O=[s,c?P.default.resolve(r,c.\u30D5\u30A1\u30A4\u30EB):null,p??null].filter((w,K,Z)=>!!w&&Z.indexOf(w)===K&&T.default.existsSync(w)).map(w=>({\u540D:i(w),\u6307\u7D0B:an(T.default.readFileSync(w,"utf8"))}));T.default.writeFileSync(h,ln(M.md,{\u9053\u5177:"spec-doc",\u65E5:un(),\u3082\u3068:O}));let _=M.\u7167\u3089\u3057\u5408\u308F\u305B;console.log(`
320
+ `+e.\u66F8\u3044\u305F(h)),console.log(e.\u5185\u8A33(o.\u524D\u63D0.length+o.\u30B3\u30A2.length+o.\u5468\u7E01.length,o.\u78BA\u304B\u3081\u65B9.length)),!_.\u629C\u3051.length&&!_.\u6750\u6599\u306B\u7121\u3044\u6570.length&&!_.\u6368\u3066\u305F\u7BC0.length?console.log(e.\u7167ok):(console.log(e.\u7167ng),_.\u629C\u3051.length&&console.log(e.\u629C\u3051(_.\u629C\u3051)),_.\u6750\u6599\u306B\u7121\u3044\u6570.length&&console.log(e.\u7121\u3044\u6570(_.\u6750\u6599\u306B\u7121\u3044\u6570)),_.\u6368\u3066\u305F\u7BC0.length&&console.log(e.\u6368\u3066\u305F(_.\u6368\u3066\u305F\u7BC0))),b.addedFacts?.length&&(console.log(`
321
+ `+e.\u78BA\u304B\u3081\u3069\u3053\u308D),b.addedFacts.forEach(w=>console.log(` \u30FB${w}`)))}var R=q(require("node:fs")),W=q(require("node:path"));var ve="[A-Za-z_$\\u3040-\\u9fff][\\w$\\u3040-\\u9fff]*",wn="((?:\\.[A-Za-z_$][\\w$]*|\\[[^\\]\\n]+\\])+)",kn=n=>[...n.matchAll(/\.([A-Za-z_$][\w$]*)|\[([^\]\n]+)\]/g)].map(e=>{if(e[1])return e[1];let s=e[2].trim().match(/^['"`]([A-Za-z_$][\w$]*)['"`]$/);return s?s[1]:"*"});function Qn(n,e){let t=n;for(let s of e){if(!t||typeof t!="object")return!1;if(s==="*"){let r=Object.values(t);t=r.find(i=>i&&typeof i=="object")??r[0]}else t=t[s]}return typeof t=="number"}function Vn(n){let e={};for(let t of n.matchAll(new RegExp(`(?:const|let|var)\\s+(${ve})\\s*=\\s*PARAMS${wn}`,"g")))e[t[1]]??=kn(t[2]);return e}function Xn(n,e,t){let s=new Set,r=i=>{Qn(e,i)&&s.add(i.join("."))};for(let i of n.matchAll(new RegExp(`(?<![\\w$\\u3040-\\u9fff.])PARAMS${wn}`,"g")))r(kn(i[1]));for(let[i,u]of Object.entries(t)){let o=new RegExp(`(?<![\\w$\\u3040-\\u9fff.])${i.replace(/[$]/g,"\\$")}${wn}`,"g");for(let c of n.matchAll(o))r([...u,...kn(c[1])])}return[...s].sort()}function ne(n,e){let t=["PARAMS",...Object.keys(e)].map(r=>r.replace(/[$]/g,"\\$")),s=new RegExp(`(?<![\\w$\\u3040-\\u9fff.])(${t.join("|")})[.\\[]`);return[...new Set(n.split(`
322
+ `).map(r=>r.trim()).filter(r=>r&&!/^(\/\/|\/\*|\*)/.test(r)&&s.test(r)&&/[*/]|Math\.|[<>]=?|[-+]=|\?\s*[^:]+:/.test(r)))].slice(0,20)}function An(n,e,t=[]){if(!e.length)return[t];if(!n||typeof n!="object")return[];let[s,...r]=e;return s==="*"?Object.keys(n).flatMap(i=>An(n[i],r,[...t,i])):An(n[s],r,[...t,s])}function ee(n,e,t,s,r){let i=n.split("."),u=h=>t[h]??h,o=An(e,i).filter(h=>typeof D(e,h.join("."))=="number"),c=h=>{let $=D(e,h.slice(0,-1).join("."));return String($?.name??h[h.length-2]??"")},l=i.includes("*"),a=l?o.map(h=>`${c(h)} ${D(e,h.join("."))}`).join(" \uFF0F "):String(D(e,n)),p=h=>{for(let $=h.length;$>=1;$-=1){let j=s[h.slice(0,$).join(".")];if(j)return{r:j,\u81EA\u5206:$===h.length}}return null},g=l?o.map(h=>{let $=p(h);return $?`${c(h)}: ${$.r}`:""}).filter(Boolean).join(" \uFF0F "):(()=>{let h=p(i);return h?h.\u81EA\u5206?h.r:r?`(why the group) ${h.r}`:`\uFF08\u307E\u3068\u307E\u308A\u306E\u7406\u7531\uFF09${h.r}`:""})(),m=i.length>1?u(i[0]):"";return{\u540D:m?r?`${m} \u2014 ${u(i[i.length-1])}`:`${m}\u306E${u(i[i.length-1])}`:u(i[0]),\u30AD\u30FC:n,\u5024:a,\u7406\u7531:g}}var gn={ja:["\u76EE\u7684","\u30EB\u30FC\u30EB","\u51E6\u7406\u306E\u6D41\u308C","\u4F8B\u5916\uFF08\u7A7A\u30FB\u4E0A\u9650\u30FB\u6B62\u307E\u3063\u305F\u3068\u304D\uFF09","\u753B\u9762\u306B\u51FA\u3059\u3082\u306E","\u8ABF\u6574\u306E\u52D8\u6240"],en:["Purpose","Rules","Flow","Exceptions (empty, limits, when it stops)","What appears on screen","Tuning notes"]},Un={ja:[/目的/,/ルール|規則/,/流れ/,/例外/,/画面/,/勘所|調整/],en:[/purpose/i,/rule/i,/flow/i,/exception/i,/screen/i,/tun/i]};function xn(n){let e=(n.\u82F1\u8A9E?gn.en:gn.ja).filter((s,r)=>n.\u8ABF\u6574\u3042\u308A||r<5),t=n.\u6570\u306E\u884C.map(s=>`\u30FB${s.\u540D}\uFF08${s.\u30AD\u30FC}\uFF09\uFF1D ${s.\u5024}${s.\u7406\u7531?n.\u82F1\u8A9E?` why: ${s.\u7406\u7531}`:`\u3000\u7406\u7531: ${s.\u7406\u7531}`:""}`).join(`
323
+ `);return n.\u82F1\u8A9E?[`Write the system spec for "${n.\u984C}" in ${n.\u4F5C\u54C1?`"${n.\u4F5C\u54C1}"`:"this app"}. The material is the finished code, the numbers that code uses, and the decisions.`,n.\u4E00\u8A00?`What this system does (in one sentence): ${n.\u4E00\u8A00}`:"",`Use these ${e.length} headings, in this order: ${e.join(" / ")}`,'\u2605Do not write numbers (the numbers table is printed separately). When you mention a number, use its name from "Numbers used" below as it is.','\u2605Do not describe behavior that is not in the code. If something cannot be read from the code, write "cannot tell from the code".',"","\u25A0 Decisions that concern it",...n.\u6C7A\u3081\u3054\u3068.length?n.\u6C7A\u3081\u3054\u3068.map(s=>`\u30FB${s}`):["(none)"],"","\u25A0 Numbers used",t||"(none)","","\u25A0 Code (as it is)",n.\u30B3\u30FC\u30C9].filter((s,r,i)=>s!==""||i[r-1]!=="").join(`
324
+ `):[`${n.\u4F5C\u54C1?`\u300C${n.\u4F5C\u54C1}\u300D\u306E`:""}\u300C${n.\u984C}\u300D\u306E\u4ED5\u7D44\u307F\u306E\u4ED5\u69D8\u66F8\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002\u6750\u6599\u306F\u3001\u51FA\u6765\u4E0A\u304C\u3063\u305F\u30B3\u30FC\u30C9\u3068\u3001\u305D\u306E\u30B3\u30FC\u30C9\u304C\u4F7F\u3046\u6570\u3068\u3001\u6C7A\u3081\u305F\u3053\u3068\u3067\u3059\u3002`,n.\u4E00\u8A00?`\u3053\u306E\u4ED5\u7D44\u307F\u304C\u3059\u308B\u3053\u3068\uFF08\u4E00\u6587\uFF09: ${n.\u4E00\u8A00}`:"",`\u6B21\u306E ${e.length} \u3064\u306E\u898B\u51FA\u3057\u3067\u3001\u3053\u306E\u9806\u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044: ${e.join("\uFF0F")}`,"\u2605\u6570\u5B57\u306F\u66F8\u304B\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF08\u6570\u306E\u8868\u306F\u5225\u306B\u8F09\u305B\u307E\u3059\uFF09\u3002\u6570\u306E\u540D\u524D\u3092\u51FA\u3059\u3068\u304D\u306F\u3001\u4E0B\u306E\u300C\u4F7F\u3046\u6570\u300D\u306E\u540D\u524D\u3092\u305D\u306E\u307E\u307E\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002","\u2605\u30B3\u30FC\u30C9\u306B\u7121\u3044\u52D5\u304D\u3092\u66F8\u304B\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\u30B3\u30FC\u30C9\u304B\u3089\u8AAD\u307F\u53D6\u308C\u306A\u3044\u3053\u3068\u306F\u300C\u30B3\u30FC\u30C9\u304B\u3089\u306F\u5206\u304B\u3089\u306A\u3044\u300D\u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002","","\u25A0 \u95A2\u308F\u308B\u6C7A\u3081\u3054\u3068",...n.\u6C7A\u3081\u3054\u3068.length?n.\u6C7A\u3081\u3054\u3068.map(s=>`\u30FB${s}`):["\uFF08\u306A\u3057\uFF09"],"","\u25A0 \u4F7F\u3046\u6570",t||"\uFF08\u306A\u3057\uFF09","","\u25A0 \u30B3\u30FC\u30C9\uFF08\u305D\u306E\u307E\u307E\uFF09",n.\u30B3\u30FC\u30C9].filter((s,r,i)=>s!==""||i[r-1]!=="").join(`
325
+ `)}function te(n,e,t){let s=e?gn.en:gn.ja,r=e?Un.en:Un.ja,i=n.replace(/\r\n/g,`
326
+ `).split(`
327
+ `),u=p=>p.replace(/^[0-90-9]+[..、\s]\s*/,"").trim(),o=[2,3,4].find(p=>i.some(g=>{let m=g.match(new RegExp(`^#{${p}}\\s+(.+?)\\s*$`));return!!m&&r.some(h=>h.test(u(m[1])))}))??2,c=[];for(let p of i){let g=p.match(/^(#+)\s/)?.[1].length??0;if(!(g&&g<o)){if(g===o){c.push({\u898B\u51FA\u3057:u(p.replace(/^#+\s+/,"")),\u672C\u6587:[]});continue}c.length&&c[c.length-1].\u672C\u6587.push(g>o?p.replace(/^#+/,"#".repeat(Math.min(6,g-o+2))):p)}}let l=[],a=[];for(let p of c){let g=r.findIndex(h=>h.test(p.\u898B\u51FA\u3057)),m=p.\u672C\u6587.join(`
328
+ `).trim();if(g<0||g===5&&!t||l.some(h=>h.\u898B\u51FA\u3057===s[g])){a.push(p.\u898B\u51FA\u3057);continue}m&&l.push({\u898B\u51FA\u3057:s[g],\u672C\u6587:m})}return{\u7BC0:l.sort((p,g)=>s.indexOf(p.\u898B\u51FA\u3057)-s.indexOf(g.\u898B\u51FA\u3057)),\u6368\u3066\u305F:a}}function Me(n){let e=[...n.replace(/\s+/g,"").replace(/[「」『』()()*`]/g,"")];if(!e.length)return null;let t="[\\s\u300C\u300D\u300E\u300F\uFF08\uFF09()*`]*";return new RegExp(e.map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(t))}function se(n,e,t){let s=n.map(u=>({...u})),r=[],i=[];for(let u of e){let o=Me(u.\u4ED5\u69D8\u66F8\u306E\u6587),c=o?s.find(m=>o.test(m.\u672C\u6587)):void 0;if(!o||!c){i.push(u);continue}let l=r.length+1,a=c.\u672C\u6587.match(o)[0],p=u.\u76F4\u3057\u305F\u6587.replace(/\*\*/g,"").trim(),g=!p||/\n/.test(p)||(p.match(/(?:^|\s)[0-90-9]+[..]\s/g)??[]).length>=2||p.length>Math.max(a.length*3,a.length+150);c.\u672C\u6587=c.\u672C\u6587.replace(o,g?`~~${a}~~${t?`[fixed ${l}: see the table below]`:`\uFF3B\u76F4\u3057\u305F ${l}\uFF1A\u4E0B\u306E\u8868\uFF3D`}`:`**${p}**${t?`[fixed ${l}]`:`\uFF3B\u76F4\u3057\u305F ${l}\uFF3D`}`),r.push({\u756A\u53F7:l,\u91CD\u3055:u.\u91CD\u3055,\u524D:a,\u5F8C:p||(t?'(cannot be fixed in one sentence \u2014 see "Why")':"\uFF081 \u6587\u3067\u306F\u76F4\u305B\u306A\u3044\u30FB\u300C\u306A\u305C\u300D\u306E\u6B04\u3092\u898B\u3066\u304F\u3060\u3055\u3044\uFF09"),\u306A\u305C:u.\u30B3\u30FC\u30C9\u306E\u5B9F\u969B,\u6839\u62E0:u.\u6839\u62E0\u306E\u30B3\u30FC\u30C9})}return{\u7BC0:s,\u5F53\u3066\u305F:r,\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F:i}}var oe=n=>n.map(e=>`## ${e.\u898B\u51FA\u3057}
329
+
330
+ ${e.\u672C\u6587}`).join(`
331
+
332
+ `),Y=n=>String(n).replace(/\|/g,"\\|").replace(/\n/g," "),yn=bn;function re(n){let e=n.\u6750\u6599,t=e.\u82F1\u8A9E,s=n.Writer\u7BC0.map(a=>a.\u672C\u6587).join(`
333
+ `),r=new Set(yn(n.\u983C\u307F)),i={\u6750\u6599\u306B\u7121\u3044\u6570:yn(s).filter(a=>!r.has(a)),PARAMS\u306B\u7121\u3044:n.PARAMS?e.\u6570\u306E\u884C.filter(a=>!Qn(n.PARAMS,a.\u30AD\u30FC.split("."))).map(a=>a.\u30AD\u30FC):[],\u5206\u304B\u3089\u306A\u3044:(s.match(t?/cannot tell from the code/gi:/コードからは分から/g)??[]).length,\u6368\u3066\u305F\u7BC0:n.\u6368\u3066\u305F\u7BC0},u=n.\u7247.map(a=>a.\u59CB\u3081===a.\u7D42\u308F\u308A?`${a.\u59CB\u3081}`:`${a.\u59CB\u3081}\u2013${a.\u7D42\u308F\u308A}`).join(t?", ":"\u30FB"),o=[];o.push(t?`# System spec ${n.\u756A\u53F7}/${n.\u5168\u90E8}: ${e.\u984C}`:`# \u4ED5\u7D44\u307F\u306E\u4ED5\u69D8\u66F8 ${n.\u756A\u53F7}\uFF0F${n.\u5168\u90E8}\u3000${e.\u984C}`,""),o.push(t?`> Made on: ${n.\u65E5\u4ED8} / written from the finished code (${n.\u30B3\u30FC\u30C9\u306E\u30D5\u30A1\u30A4\u30EB}, lines ${u})${n.\u5168\u4F53\u306E\u4ED5\u69D8\u66F8?` / sits under the overall spec (${n.\u5168\u4F53\u306E\u4ED5\u69D8\u66F8})`:""}`:`> \u4F5C\u3063\u305F\u65E5: ${n.\u65E5\u4ED8} \uFF0F \u51FA\u6765\u4E0A\u304C\u3063\u305F\u30B3\u30FC\u30C9\uFF08${n.\u30B3\u30FC\u30C9\u306E\u30D5\u30A1\u30A4\u30EB} \u306E ${u} \u884C\u76EE\uFF09\u304B\u3089\u66F8\u304D\u8D77\u3053\u3057\u305F\u3082\u306E\u3067\u3059${n.\u5168\u4F53\u306E\u4ED5\u69D8\u66F8?`\u3002\u5168\u4F53\u306E\u4ED5\u69D8\u66F8\uFF08${n.\u5168\u4F53\u306E\u4ED5\u69D8\u66F8}\uFF09\u306E\u4E0B\u306B\u7F6E\u304F\u3001\u4ED5\u7D44\u307F\u3054\u3068\u306E\u4ED5\u69D8\u66F8\u3067\u3059`:""}`),o.push(t?'> \u2605Sections marked "(AI)" were written by AI (Kokoro OS Writer). "Calculations", "Numbers used" and "Decisions" are copied from the code, PARAMS and the spec without going through AI.':"> \u2605\u898B\u51FA\u3057\u306B\u300C\uFF08AI\uFF09\u300D\u3068\u3042\u308B\u7BC0\u306F AI\uFF08Kokoro OS \u306E Writer\uFF09\u304C\u66F8\u3044\u305F\u6587\u7AE0\u3067\u3059\u3002\u300C\u8A08\u7B97\u5F0F\u300D\u300C\u4F7F\u3046\u6570\u300D\u300C\u95A2\u308F\u308B\u6C7A\u3081\u3054\u3068\u300D\u306F\u3001\u30B3\u30FC\u30C9\u30FBPARAMS\u30FB\u6307\u793A\u66F8\u304B\u3089 AI \u3092\u901A\u3055\u305A\u306B\u5199\u3057\u3066\u3044\u307E\u3059\u3002");let c=n.Fable??null;c?o.push(t?`> \u2605Another AI (Claude Fable) checked this spec against the code and fixed the sentences that disagreed (${c.\u5F53\u3066\u305F.length} fixed \u2014 see "Fixed by the check" at the end; fixed sentences are bold and marked [fixed N]). \u2605Not finding a disagreement does not prove there is none.`:`> \u2605\u3053\u306E\u4ED5\u69D8\u66F8\u306F\u3001\u5225\u306E AI\uFF08Claude Fable\uFF09\u304C\u30B3\u30FC\u30C9\u3068\u7167\u3089\u3057\u5408\u308F\u305B\u3001\u98DF\u3044\u9055\u3063\u3066\u3044\u305F\u6587\u3092\u76F4\u3057\u3066\u3042\u308A\u307E\u3059\uFF08\u76F4\u3057\u305F ${c.\u5F53\u3066\u305F.length} \u304B\u6240\u30FB\u672B\u5C3E\u306E\u300C\u7167\u3089\u3057\u5408\u308F\u305B\u3067\u76F4\u3057\u305F\u6240\u300D\u3002\u76F4\u3057\u305F\u6587\u306F\u592A\u5B57\u3067\uFF3B\u76F4\u3057\u305F N\uFF3D\u306E\u5370\uFF09\u3002\u2605\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u3053\u3068\u306F\u3001\u7121\u3044\u3068\u8A3C\u660E\u3057\u305F\u3053\u3068\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002`):o.push(t?"> \u2605The checks below only show that numbers were not changed and that the numbers used exist. **Whether the AI text describes the behavior correctly must be checked by a person reading it** against the app.":"> \u2605\u4E0B\u306E\u7167\u3089\u3057\u5408\u308F\u305B\u3067\u5206\u304B\u308B\u306E\u306F\u300C\u6570\u304C\u5909\u308F\u3063\u3066\u3044\u306A\u3044\u30FB\u4F7F\u3046\u6570\u304C\u5B9F\u5728\u3059\u308B\u300D\u3053\u3068\u307E\u3067\u3067\u3059\u3002**AI \u306E\u6587\u304C\u52D5\u304D\u3068\u3057\u3066\u6B63\u3057\u3044\u304B\u306F\u3001\u4EBA\u304C\u8AAD\u3093\u3067\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002**"),e.\u4E00\u8A00&&o.push("",t?`**What it does:** ${e.\u4E00\u8A00}`:`**\u4F55\u3092\u3059\u308B\u4ED5\u7D44\u307F\u304B:** ${e.\u4E00\u8A00}`);for(let a of n.Writer\u7BC0)o.push("",`## ${a.\u898B\u51FA\u3057}${t?" (AI)":"\uFF08AI\uFF09"}`,"",a.\u672C\u6587);o.push("",t?"## Calculations (code as it is)":"## \u8A08\u7B97\u5F0F\uFF08\u30B3\u30FC\u30C9\u305D\u306E\u307E\u307E\uFF09",""),o.push(n.\u8A08\u7B97.length?["```js",...n.\u8A08\u7B97,"```"].join(`
334
+ `):t?"No line in this system calculates with PARAMS.":"\u3053\u306E\u4ED5\u7D44\u307F\u306B\u306F\u3001PARAMS \u3092\u4F7F\u3063\u3066\u8A08\u7B97\u3059\u308B\u884C\u306F\u3042\u308A\u307E\u305B\u3093\u3002"),o.push("",t?"## Numbers used (PARAMS, current values)":"## \u4F7F\u3046\u6570\uFF08PARAMS\u30FB\u4ECA\u306E\u5024\uFF09",""),e.\u6570\u306E\u884C.length?(o.push(t?"| Name | Key | Current value | Why (code comment) |":"| \u540D\u524D | \u30AD\u30FC | \u4ECA\u306E\u5024 | \u7406\u7531\uFF08\u30B3\u30FC\u30C9\u306E\u30B3\u30E1\u30F3\u30C8\uFF09 |","| --- | --- | --- | --- |"),e.\u6570\u306E\u884C.forEach(a=>o.push(`| ${Y(a.\u540D)} | \`${a.\u30AD\u30FC}\` | ${Y(a.\u5024)} | ${Y(a.\u7406\u7531)} |`))):o.push(t?"This system reads no numbers from PARAMS.":"\u3053\u306E\u4ED5\u7D44\u307F\u306F\u3001PARAMS \u306E\u6570\u3092\u8AAD\u3093\u3067\u3044\u307E\u305B\u3093\u3002"),o.push("",t?"## Decisions that concern it (from the spec)":"## \u95A2\u308F\u308B\u6C7A\u3081\u3054\u3068\uFF08\u6307\u793A\u66F8\u304B\u3089\uFF09",""),o.push(e.\u6C7A\u3081\u3054\u3068.length?e.\u6C7A\u3081\u3054\u3068.map(a=>`- ${a}`).join(`
335
+ `):t?"None were linked to this system.":"\u3053\u306E\u4ED5\u7D44\u307F\u306B\u7D50\u3073\u3064\u3044\u305F\u6C7A\u3081\u3054\u3068\u306F\u3042\u308A\u307E\u305B\u3093\u3002"),o.push("",t?"## Checks (no AI)":"## \u7167\u3089\u3057\u5408\u308F\u305B\u306E\u7D50\u679C\uFF08AI \u306A\u3057\uFF09","");let l=yn(s);return o.push(t?`- Numbers in the AI text: ${l.join(", ")||"none"} \u2192 not in the material: ${i.\u6750\u6599\u306B\u7121\u3044\u6570.join(", ")||"none"}`:`- AI \u306E\u6587\u306E\u4E2D\u306E\u6570: ${l.join("\u30FB")||"\u306A\u3057"} \u2192 \u6750\u6599\u306B\u7121\u3044\u6570: ${i.\u6750\u6599\u306B\u7121\u3044\u6570.join("\u30FB")||"\u306A\u3057"}`),o.push(t?`- Numbers used: ${e.\u6570\u306E\u884C.length} \u2192 not found in PARAMS: ${i.PARAMS\u306B\u7121\u3044.length} / places the AI wrote "cannot tell from the code": ${i.\u5206\u304B\u3089\u306A\u3044}`:`- \u4F7F\u3046\u6570 ${e.\u6570\u306E\u884C.length} \u500B \u2192 PARAMS \u306B\u7121\u3044\u3082\u306E: ${i.PARAMS\u306B\u7121\u3044.length} \u500B\uFF0F\u300C\u30B3\u30FC\u30C9\u304B\u3089\u306F\u5206\u304B\u3089\u306A\u3044\u300D\u3068\u66F8\u3044\u305F\u6240: ${i.\u5206\u304B\u3089\u306A\u3044}`),i.\u6368\u3066\u305F\u7BC0.length&&o.push(t?`- The AI also wrote other sections; left out: ${i.\u6368\u3066\u305F\u7BC0.join(" / ")}`:`- AI \u304C\u307B\u304B\u306E\u7BC0\u3082\u66F8\u3044\u3066\u3044\u305F\u306E\u3067\u3001\u8F09\u305B\u307E\u305B\u3093\u3067\u3057\u305F: ${i.\u6368\u3066\u305F\u7BC0.join("\uFF0F")}`),c&&(o.push("",t?"## Fixed by the check (another AI compared the spec with the code)":"## \u7167\u3089\u3057\u5408\u308F\u305B\u3067\u76F4\u3057\u305F\u6240\uFF08\u5225\u306E AI \u304C\u30B3\u30FC\u30C9\u3068\u7167\u3089\u3057\u5408\u308F\u305B\u305F\uFF09",""),o.push(t?'> Only disagreements whose spec sentence and code quote were both found word for word are fixed here. "Before" is what Writer wrote; "After" is the sentence rewritten to match the code.':"> \u4ED5\u69D8\u66F8\u306E\u6587\u3068\u6839\u62E0\u306E\u30B3\u30FC\u30C9\u304C\u3001\u3069\u3061\u3089\u3082\u6587\u5B57\u3069\u304A\u308A\u306B\u3042\u308B\u3068\u6A5F\u68B0\u3067\u78BA\u304B\u3081\u3089\u308C\u305F\u98DF\u3044\u9055\u3044\u3060\u3051\u3092\u76F4\u3057\u3066\u3044\u307E\u3059\u3002\u300C\u524D\u300D\u306F Writer \u304C\u66F8\u3044\u305F\u6587\u3001\u300C\u5F8C\u300D\u306F\u30B3\u30FC\u30C9\u3069\u304A\u308A\u306B\u76F4\u3057\u305F\u6587\u3067\u3059\u3002"),o.push(""),c.\u5F53\u3066\u305F.length?(o.push(t?"| | Severity | Before (Writer) | After (fixed) | Why (what the code does) | Code |":"| | \u91CD\u3055 | \u524D\uFF08Writer\uFF09 | \u5F8C\uFF08\u76F4\u3057\u305F\u6587\uFF09 | \u306A\u305C\uFF08\u30B3\u30FC\u30C9\u306E\u5B9F\u969B\uFF09 | \u6839\u62E0\u306E\u30B3\u30FC\u30C9 |","| --- | --- | --- | --- | --- | --- |"),c.\u5F53\u3066\u305F.forEach(a=>o.push(`| ${a.\u756A\u53F7} | ${Y(a.\u91CD\u3055)} | ${Y(a.\u524D)} | ${Y(a.\u5F8C)} | ${Y(a.\u306A\u305C)} | \`${Y(a.\u6839\u62E0).replace(/`/g,"'")}\` |`))):o.push(t?"No disagreement was found (\u2605not found \u2014 this does not prove there is none).":"\u98DF\u3044\u9055\u3044\u306F\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u2605\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u3001\u3067\u3042\u3063\u3066\u3001\u7121\u3044\u3068\u8A3C\u660E\u3057\u305F\u308F\u3051\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09\u3002"),c.\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F.length&&(o.push("",t?"### Fixes that could not be placed (the sentence was not found in the text; read and fix by hand)":"### \u5DEE\u3057\u8FBC\u3081\u306A\u304B\u3063\u305F\u76F4\u3057\uFF08\u6587\u306E\u5834\u6240\u304C\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u30FB\u4EBA\u304C\u898B\u3066\u76F4\u3059\uFF09",""),c.\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F.forEach(a=>o.push(`- \u300C${a.\u4ED5\u69D8\u66F8\u306E\u6587}\u300D\u2192\u300C${a.\u76F4\u3057\u305F\u6587}\u300D\uFF08${a.\u30B3\u30FC\u30C9\u306E\u5B9F\u969B}\uFF09`))),c.\u5408\u308F\u306A\u3044.length&&(o.push("",t?"### Findings that could not be confirmed (a quote was not found word for word; the text was not changed)":"### \u78BA\u304B\u3081\u304D\u308C\u306A\u304B\u3063\u305F\u6307\u6458\uFF08\u5F15\u7528\u304C\u6587\u5B57\u3069\u304A\u308A\u306B\u306F\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u30FB\u672C\u6587\u306F\u76F4\u3057\u3066\u3044\u306A\u3044\uFF09",""),c.\u5408\u308F\u306A\u3044.forEach(a=>o.push(t?`- "${a.\u4ED5\u69D8\u66F8\u306E\u6587}" \u2014 finding: ${a.\u30B3\u30FC\u30C9\u306E\u5B9F\u969B} (suggested: "${a.\u76F4\u3057\u305F\u6587}") (spec sentence: ${a.\u6587\u3042\u308A?"found":"not found"} / code quote: ${a.\u6839\u62E0\u3042\u308A?"found":"not found"})`:`- \u300C${a.\u4ED5\u69D8\u66F8\u306E\u6587}\u300D\u2014 \u6307\u6458: ${a.\u30B3\u30FC\u30C9\u306E\u5B9F\u969B}\uFF08\u6848:\u300C${a.\u76F4\u3057\u305F\u6587}\u300D\uFF09\uFF08\u4ED5\u69D8\u66F8\u306E\u6587: ${a.\u6587\u3042\u308A?"\u3042\u308B":"\u7121\u3044"}\u30FB\u6839\u62E0\u306E\u30B3\u30FC\u30C9: ${a.\u6839\u62E0\u3042\u308A?"\u3042\u308B":"\u7121\u3044"}\uFF09`))),c.\u78BA\u304B\u3081\u3089\u308C\u306A\u304B\u3063\u305F.length&&(o.push("",t?"### What the checking AI said it could not confirm":"### \u78BA\u304B\u3081\u3089\u308C\u306A\u304B\u3063\u305F\u3053\u3068\uFF08\u7167\u3089\u3057\u5408\u308F\u305B\u305F AI \u304C\u305D\u3046\u8A00\u3063\u305F\u3053\u3068\uFF09",""),c.\u78BA\u304B\u3081\u3089\u308C\u306A\u304B\u3063\u305F.forEach(a=>o.push(`- ${a}`)))),{md:`${o.join(`
336
+ `).replace(/\n{3,}/g,`
337
+
338
+ `).trim()}
339
+ `,\u7167\u3089\u3057\u5408\u308F\u305B:i}}var ie=n=>n.trim().replace(/\s+/g,"-").replace(/[\\/:*?"<>|]+/g,"").slice(0,40)||"system";var ce=29e3,V={ja:{\u30B3\u30FC\u30C9\u304C\u7121\u3044:n=>`${n} \u306B PARAMS \u306E\u3042\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u4ED5\u7D44\u307F\u306E\u4ED5\u69D8\u66F8\u306B\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u3092 --code \u3067\u6307\u3057\u3066\u304F\u3060\u3055\u3044\uFF081 \u30D5\u30A1\u30A4\u30EB\uFF09\u3002`,\u4ED5\u69D8\u306A\u3057:"\u6307\u793A\u66F8\uFF08kokoro-spec.md\uFF09\u304C\u7121\u3044\u306E\u3067\u3001\u95A2\u308F\u308B\u6C7A\u3081\u3054\u3068\u306F\u51FA\u3057\u307E\u305B\u3093",\u5206\u3051\u3066\u3044\u308B:(n,e)=>`${n} \u3092\u4ED5\u7D44\u307F\u306B\u5206\u3051\u3066\u3044\u307E\u3059\u2026\uFF08${e} \u884C\u30FBAI 1 \u56DE\uFF09`,\u5206\u3051\u3089\u308C\u306A\u3044:"\u4ED5\u7D44\u307F\u306B\u5206\u3051\u3089\u308C\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5F15\u7528\u304C\u30B3\u30FC\u30C9\u3068\u5408\u3044\u307E\u305B\u3093\u3067\u3057\u305F\uFF09\u3002\u3082\u3046\u4E00\u5EA6\u52D5\u304B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",\u4E00\u89A7:n=>`
340
+ \u4ED5\u7D44\u307F ${n} \u3064:`,\u884C:(n,e,t,s)=>` ${n} \u884C\u76EE\uFF08${e} \u884C\uFF09\u30FB\u4F7F\u3046\u6570 ${t}\u30FB\u6C7A\u3081\u3054\u3068 ${s}`,\u6368\u3066\u305F:"\u78BA\u304B\u3081\u3089\u308C\u306A\u304B\u3063\u305F\u306E\u3067\u5916\u3057\u305F\u3082\u306E:",\u805E\u304F:n=>`
341
+ \u3053\u306E\u5206\u3051\u65B9\u3067\u3001\u4ED5\u7D44\u307F\u306E\u4ED5\u69D8\u66F8\u3092 ${n} \u672C\u66F8\u304D\u307E\u3059\u304B\uFF1F\uFF08Writer \u3092 ${n} \u56DE\u4F7F\u3044\u307E\u3059\uFF09[y/n] `,\u3084\u3081\u305F:"\u66F8\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002",\u983C\u3080:n=>`
342
+ Writer \u306B ${n} \u672C\u3092\u983C\u3093\u3067\u3044\u307E\u3059\u2026\uFF08\u540C\u6642\u306B\uFF09`,\u5207\u3063\u305F:n=>`\u2605${n}: \u30B3\u30FC\u30C9\u304C\u9577\u3044\u306E\u3067\u3001\u9014\u4E2D\u307E\u3067\u3092 Writer \u306B\u6E21\u3057\u307E\u3057\u305F`,\u5F85\u3064:(n,e)=>`${n}: Writer \u306E\u56DE\u6570\u306E\u4E0A\u9650\uFF0810 \u5206\u306B 20 \u56DE\uFF09\u306A\u306E\u3067\u3001${e} \u79D2\u5F85\u3063\u3066\u304B\u3089\u983C\u307F\u76F4\u3057\u307E\u3059\u2026`,\u5931\u6557:(n,e)=>`\u2605${n}: Writer \u304C\u6B62\u307E\u308A\u307E\u3057\u305F\uFF08${e}\uFF09\u3002\u3053\u306E 1 \u672C\u306F\u66F8\u3044\u3066\u3044\u307E\u305B\u3093`,\u66F8\u3044\u305F:(n,e)=>`\u66F8\u304D\u307E\u3057\u305F: ${n}
343
+ ${e}`,\u7167:(n,e,t,s)=>`\u6750\u6599\u306B\u7121\u3044\u6570: ${n.join("\u30FB")||"\u306A\u3057"}\uFF0FPARAMS \u306B\u7121\u3044\u6570: ${e}\uFF0F\u300C\u30B3\u30FC\u30C9\u304B\u3089\u306F\u5206\u304B\u3089\u306A\u3044\u300D: ${t}${s.length?`\uFF0F\u8F09\u305B\u306A\u304B\u3063\u305F\u7BC0: ${s.join("\u30FB")}`:""}`,\u6700\u5F8C:"\u2605AI \u306E\u6587\u304C\u52D5\u304D\u3068\u3057\u3066\u6B63\u3057\u3044\u304B\u306F\u3001\u7167\u3089\u3057\u5408\u308F\u305B\u3067\u306F\u5206\u304B\u308A\u307E\u305B\u3093\u3002\u4EBA\u304C\u8AAD\u3093\u3067\u3001\u4F5C\u54C1\u3068\u898B\u6BD4\u3079\u3066\u304F\u3060\u3055\u3044\u3002",\u6700\u5F8C\u7167\u3089\u3057\u305F:"\u2605\u5225\u306E AI \u304C\u30B3\u30FC\u30C9\u3068\u7167\u3089\u3057\u5408\u308F\u305B\u3001\u98DF\u3044\u9055\u3063\u3066\u3044\u305F\u6587\u3092\u76F4\u3057\u307E\u3057\u305F\uFF08\u5404\u4ED5\u69D8\u66F8\u306E\u672B\u5C3E\u306B\u524D\u2192\u5F8C\u306E\u8868\uFF09\u3002\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u3053\u3068\u306F\u3001\u7121\u3044\u3068\u8A3C\u660E\u3057\u305F\u3053\u3068\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",\u805E\u304F\u7167\u3089\u3059:n=>`
344
+ \u3053\u306E\u5206\u3051\u65B9\u3067\u3001\u4ED5\u7D44\u307F\u306E\u4ED5\u69D8\u66F8\u3092 ${n} \u672C\u66F8\u3044\u3066\u3001\u5225\u306E AI\uFF08Fable\uFF09\u3067\u30B3\u30FC\u30C9\u3068\u7167\u3089\u3057\u5408\u308F\u305B\u307E\u3059\u304B\uFF1F
345
+ \uFF08Writer ${n} \u56DE\uFF0BFable ${n} \u56DE\u3002\u7167\u3089\u3057\u5408\u308F\u305B\u306F 1 \u672C\u3042\u305F\u308A\u7D04 35 \u5186\u306E\u898B\u8FBC\u307F\u30FB\u304A\u8A66\u3057\u306E\u5B9F\u6E2C\u3002--no-check \u3067\u7167\u3089\u3057\u5408\u308F\u305B\u3092\u5916\u305B\u307E\u3059\uFF09[y/n] `,\u7167\u3089\u3055\u306A\u3044Kokoro:"\u7167\u3089\u3057\u5408\u308F\u305B\uFF08Fable\uFF09\u306F\u3001\u307E\u3060 Kokoro \u306E\u30AD\u30FC\u3060\u3051\u3067\u306F\u52D5\u304B\u306A\u3044\u306E\u3067\u5916\u3057\u307E\u3059\u3002\u7167\u3089\u3057\u5408\u308F\u305B\u3082\u4ED8\u3051\u308B\u3068\u304D\u306F\u3001ANTHROPIC_API_KEY \u3082\u5165\u308C\u3066\u52D5\u304B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08AI \u306E\u8CBB\u7528\u306F\u305D\u306E\u30AD\u30FC\u306B\u3001\u624B\u6570\u6599\u306F Kokoro \u306E\u6B8B\u9AD8\u304B\u3089\uFF09\u3002",\u983C\u3080\u7167\u3089\u3059:n=>`
346
+ ${n} \u672C\u3092\u66F8\u3044\u3066\u3001\u7167\u3089\u3057\u5408\u308F\u305B\u3066\u3044\u307E\u3059\u2026\uFF08\u4ED5\u7D44\u307F\u3069\u3046\u3057\u306F\u540C\u6642\u306B\u30FB1 \u672C 1\u301C2 \u5206\uFF09`,\u7167\u3089\u3057\u305F:(n,e,t)=>` \u7167\u3089\u3057\u5408\u308F\u305B: \u76F4\u3057\u305F ${n}${e?`\uFF0F\u5DEE\u3057\u8FBC\u3081\u306A\u304B\u3063\u305F ${e}`:""}${t?`\uFF0F\u78BA\u304B\u3081\u304D\u308C\u306A\u304B\u3063\u305F\u6307\u6458 ${t}`:""}`,\u7167\u3089\u3057\u5931\u6557:n=>` \u2605\u7167\u3089\u3057\u5408\u308F\u305B\u304C\u6B62\u307E\u308A\u307E\u3057\u305F\uFF08${n}\uFF09\u3002\u3053\u306E 1 \u672C\u306F\u7167\u3089\u3057\u5408\u308F\u305B\u3066\u3044\u307E\u305B\u3093`,\u8CBB\u7528:n=>`\u7167\u3089\u3057\u5408\u308F\u305B\u306E\u8CBB\u7528: \u7D04 ${n} \u5186\uFF08\u898B\u7A4D\u3082\u308A\u30FB1 \u30C9\u30EB 150 \u5186\uFF09`,\u7F6E\u304D\u5834:"system-specs"},en:{\u30B3\u30FC\u30C9\u304C\u7121\u3044:n=>`No file with PARAMS found in ${n}. Point to the file to document with --code (one file).`,\u4ED5\u69D8\u306A\u3057:"No spec (kokoro-spec.md), so no decisions are linked",\u5206\u3051\u3066\u3044\u308B:(n,e)=>`Splitting ${n} into systems\u2026 (${e} lines, 1 AI call)`,\u5206\u3051\u3089\u308C\u306A\u3044:"Could not split into systems (the quoted lines did not match the code). Please run again.",\u4E00\u89A7:n=>`
347
+ ${n} systems:`,\u884C:(n,e,t,s)=>` lines ${n} (${e} lines), ${t} numbers, ${s} decisions`,\u6368\u3066\u305F:"Left out because they could not be confirmed:",\u805E\u304F:n=>`
348
+ Write ${n} system specs with this split? (uses Writer ${n} times) [y/n] `,\u3084\u3081\u305F:"Nothing was written.",\u983C\u3080:n=>`
349
+ Asking Writer for ${n} specs\u2026 (in parallel)`,\u5207\u3063\u305F:n=>`\u2605${n}: the code is long, so only the first part was sent to Writer`,\u5F85\u3064:(n,e)=>`${n}: Writer's limit (20 runs per 10 minutes) was reached; waiting ${e} seconds, then asking again\u2026`,\u5931\u6557:(n,e)=>`\u2605${n}: Writer stopped (${e}). This one was not written`,\u66F8\u3044\u305F:(n,e)=>`Written: ${n}
350
+ ${e}`,\u7167:(n,e,t,s)=>`numbers not in the material: ${n.join(", ")||"none"} / not in PARAMS: ${e} / "cannot tell from the code": ${t}${s.length?` / sections left out: ${s.join(", ")}`:""}`,\u6700\u5F8C:"\u2605The checks cannot tell whether the AI text describes the behavior correctly. Read them and compare with the app.",\u6700\u5F8C\u7167\u3089\u3057\u305F:"\u2605Another AI checked the specs against the code and fixed the sentences that disagreed (a before \u2192 after table at the end of each spec). Not finding a disagreement does not prove there is none.",\u805E\u304F\u7167\u3089\u3059:n=>`
351
+ Write ${n} system specs with this split and have another AI (Fable) check them against the code?
352
+ (Writer ${n} times + Fable ${n} times. The check is roughly 35 yen (about $0.25) per spec, measured in a trial. --no-check skips it) [y/n] `,\u7167\u3089\u3055\u306A\u3044Kokoro:"The Fable check does not accept a Kokoro key alone yet, so it is left out. To include it, also set ANTHROPIC_API_KEY (AI costs go to that key; a fee is taken from your Kokoro balance).",\u983C\u3080\u7167\u3089\u3059:n=>`
353
+ Writing ${n} specs and checking them\u2026 (in parallel, 1\u20132 minutes each)`,\u7167\u3089\u3057\u305F:(n,e,t)=>` check: fixed ${n}${e?` / could not place ${e}`:""}${t?` / unconfirmed findings ${t}`:""}`,\u7167\u3089\u3057\u5931\u6557:n=>` \u2605The check stopped (${n}). This one was not checked`,\u8CBB\u7528:n=>`Cost of the checks: about ${n} yen (estimate, $1 = 150 yen)`,\u7F6E\u304D\u5834:"system-specs"}},Oe=new Set(["node_modules",".git",".next","dist","build","out",".vercel","coverage",".turbo",".cache"]),_e=/\.(html?|tsx?|jsx?|mjs|cjs|vue|svelte|astro)$/i;function We(n){let e=[],t=0,s=(i,u)=>{if(!(u>5))for(let o of R.default.readdirSync(i,{withFileTypes:!0}).sort((c,l)=>c.name.localeCompare(l.name))){if(++t>2e4)return;let c=W.default.join(i,o.name);if(o.isDirectory()){!Oe.has(o.name)&&!o.name.startsWith(".")&&s(c,u+1);continue}if(_e.test(o.name))try{R.default.statSync(c).size<3e6&&Q(R.default.readFileSync(c,"utf8"))&&e.push(c)}catch{}}};s(n,0);let r=i=>/^check\.html?$/i.test(W.default.basename(i));return[...e.filter(i=>!r(i)),...e.filter(r)]}async function ae(n){let e=W.default.resolve(n.\u7D20||"."),t=R.default.existsSync(e)&&R.default.statSync(e).isFile()?e:W.default.join(e,tn),s=R.default.existsSync(e)&&R.default.statSync(e).isFile()?W.default.dirname(e):e,r=R.default.existsSync(t)?R.default.readFileSync(t,"utf8"):"",i=r?rn(r):null,u=i?i.\u82F1\u8A9E:n.\u8A00\u8449==="en",o={\u5186:0,\u6B8B\u9AD8:null},c=f=>{let k=f?.billing;k&&typeof k.charged_yen=="number"&&(o.\u5186+=k.charged_yen,o.\u6B8B\u9AD8=k.balance_yen??null)},l=V[n.\u8A00\u8449],a=f=>W.default.relative(s,f).replace(/\\/g,"/")||W.default.basename(f),p=n.\u5024("--code")?W.default.resolve(n.\u5024("--code")):We(s)[0];if(!p||!R.default.existsSync(p))throw new Error(l.\u30B3\u30FC\u30C9\u304C\u7121\u3044(s));let g=R.default.readFileSync(p,"utf8").replace(/\r\n/g,`
354
+ `),m=g.split(`
355
+ `),h=$n(r).map(f=>f.replace(/\*\*/g,""));r||console.log(l.\u4ED5\u69D8\u306A\u3057);let $=null;if(Q(g))try{$=on(g,W.default.basename(p),n.\u8A00\u8449)}catch(f){console.log(`\u2605${f instanceof Error?f.message:String(f)}`)}let j=Vn(g);console.log(l.\u5206\u3051\u3066\u3044\u308B(a(p),m.length));let d=await fetch(`${n.\u7A93\u53E3\u306E\u5143}/api/v1/spec/systems`,{method:"POST",headers:{"Content-Type":"application/json",...n.\u30AD\u30FC.\u898B\u51FA\u3057,"user-agent":`kokoro-writer/${n.\u7248}`},body:JSON.stringify({code:g,decisions:h,lang:u?"en":"ja"}),signal:AbortSignal.timeout(15e4)}),b=await d.json().catch(()=>({}));if(!d.ok){let f=typeof b.error=="string"?b.error:b.error?.message;throw new Error(f||`HTTP ${d.status}`)}c(b);let I=(b.systems??[]).filter(f=>f.pieces?.length);if(!I.length)throw new Error(l.\u5206\u3051\u3089\u308C\u306A\u3044);let y=I.map(f=>{let k=f.pieces.map(S=>({\u59CB\u3081:S.startLine,\u7D42\u308F\u308A:S.endLine})),x=k.map(S=>m.slice(S.\u59CB\u3081-1,S.\u7D42\u308F\u308A).join(`
356
+ `)).join(`
357
+ // \u2026
358
+ `),E=$?Xn(x,$.PARAMS,j).map(S=>ee(S,$.PARAMS,$.PARAM_LABELS,$.\u7406\u7531,u)):[];return{\u6750:{\u4F5C\u54C1:i?.\u4F5C\u308B\u3082\u306E&&i.\u4F5C\u308B\u3082\u306E.length<=40?i.\u4F5C\u308B\u3082\u306E:"",\u984C:f.name,\u4E00\u8A00:f.summary,\u30B3\u30FC\u30C9:x,\u6570\u306E\u884C:E,\u6C7A\u3081\u3054\u3068:f.decisions.map(S=>h[S-1]).filter(Boolean),\u8ABF\u6574\u3042\u308A:!!$,\u82F1\u8A9E:u},\u7247:k,\u8A08\u7B97:ne(x,j),\u884C\u6570:k.reduce((S,N)=>S+N.\u7D42\u308F\u308A-N.\u59CB\u3081+1,0)}});console.log(l.\u4E00\u89A7(y.length)),y.forEach((f,k)=>{console.log(` ${k+1}. ${f.\u6750.\u984C}${f.\u6750.\u4E00\u8A00?` \u2014 ${f.\u6750.\u4E00\u8A00}`:""}`),console.log(l.\u884C(f.\u7247.map(x=>x.\u59CB\u3081===x.\u7D42\u308F\u308A?`${x.\u59CB\u3081}`:`${x.\u59CB\u3081}\u2013${x.\u7D42\u308F\u308A}`).join(u?", ":"\u30FB"),f.\u884C\u6570,f.\u6750.\u6570\u306E\u884C.length,f.\u6750.\u6C7A\u3081\u3054\u3068.length))}),b.dropped?.length&&(console.log(l.\u6368\u3066\u305F),b.dropped.forEach(f=>console.log(` \u30FB${f}`))),n.\u30AD\u30FC.\u7A2E\u985E==="Kokoro"&&!n.\u5F15\u6570.includes("--no-check")&&console.log(l.\u7167\u3089\u3055\u306A\u3044Kokoro);let M=!n.\u5F15\u6570.includes("--no-check")&&n.\u30AD\u30FC.\u7A2E\u985E!=="Kokoro";if(!n.\u5F15\u6570.includes("--yes")&&!(await n.\u805E\u304F(M?l.\u805E\u304F\u7167\u3089\u3059(y.length):l.\u805E\u304F(y.length))).trim().toLowerCase().startsWith("y")){console.log(l.\u3084\u3081\u305F);return}let O=W.default.join(s,u?V.en.\u7F6E\u304D\u5834:V.ja.\u7F6E\u304D\u5834);for(let f=2;R.default.existsSync(O);f+=1)O=W.default.join(s,`${u?V.en.\u7F6E\u304D\u5834:V.ja.\u7F6E\u304D\u5834}-${f}`);let _=n.\u5024("--model"),w=async(f,k,x)=>{let E=()=>fetch(`${n.\u7A93\u53E3\u306E\u5143}/api/v1/${f}`,{method:"POST",headers:{"Content-Type":"application/json",...n.\u30AD\u30FC.\u898B\u51FA\u3057,"user-agent":`kokoro-writer/${n.\u7248}`},body:JSON.stringify(k),signal:AbortSignal.timeout(31e4)}),A=await E(),S=await A.json().catch(()=>({}));if(A.status===429&&(S.retryAfterSeconds??0)>0&&(S.retryAfterSeconds??0)<=600&&(console.log(l.\u5F85\u3064(x,S.retryAfterSeconds)),await new Promise(N=>setTimeout(N,(S.retryAfterSeconds+2)*1e3)),A=await E(),S=await A.json().catch(()=>({}))),!A.ok)throw new Error((typeof S.error=="string"?S.error:S.error?.message)||`HTTP ${A.status}`);return c(S),S};console.log(M?l.\u983C\u3080\u7167\u3089\u3059(y.length):l.\u983C\u3080(y.length));let K=await Promise.all(y.map(async f=>{let k=xn(f.\u6750);if(k.length>ce){let A=k.length-ce+200;f.\u6750={...f.\u6750,\u30B3\u30FC\u30C9:`${f.\u6750.\u30B3\u30FC\u30C9.slice(0,Math.max(0,f.\u6750.\u30B3\u30FC\u30C9.length-A))}
359
+ // \u2026${u?"(cut here because it is long)":"\uFF08\u9577\u3044\u306E\u3067\u3001\u3053\u3053\u304B\u3089\u5148\u306F\u7701\u3044\u305F\uFF09"}`},k=xn(f.\u6750),console.log(l.\u5207\u3063\u305F(f.\u6750.\u984C))}let x="";try{let A=await w("writer",{text:k,lang:u?"en":"ja",format:"spec",..._?{model:_}:{}},f.\u6750.\u984C);if(x=typeof A.markdown=="string"?A.markdown:"",!x)throw new Error("empty")}catch(A){return{\u983C\u307F:k,\u7BC0:null,Fable:null,\u5931\u6557:A instanceof Error?A.message:String(A),\u7167\u3089\u3057\u5931\u6557:"",\u5186:0}}let E=te(x,u,f.\u6750.\u8ABF\u6574\u3042\u308A);if(!M)return{\u983C\u307F:k,\u7BC0:E,Fable:null,\u5931\u6557:"",\u7167\u3089\u3057\u5931\u6557:"",\u5186:0};try{let A=await w("spec/systems/check",{doc:oe(E.\u7BC0),material:k,lang:u?"en":"ja"},f.\u6750.\u984C),S=C=>({\u4ED5\u69D8\u66F8\u306E\u6587:C.specText,\u30B3\u30FC\u30C9\u306E\u5B9F\u969B:C.actual,\u6839\u62E0\u306E\u30B3\u30FC\u30C9:C.codeQuote,\u91CD\u3055:C.severity,\u76F4\u3057\u305F\u6587:C.fixed}),N=se(E.\u7BC0,(A.findings??[]).map(S),u),G={\u5F53\u3066\u305F:N.\u5F53\u3066\u305F,\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F:N.\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F,\u5408\u308F\u306A\u3044:(A.unmatched??[]).map(C=>({...S(C),\u6587\u3042\u308A:C.specTextFound,\u6839\u62E0\u3042\u308A:C.codeQuoteFound})),\u78BA\u304B\u3081\u3089\u308C\u306A\u304B\u3063\u305F:A.unverifiable??[]},z=((A.usage?.input_tokens??0)*10+(A.usage?.output_tokens??0)*50)/1e6*150;return{\u983C\u307F:k,\u7BC0:{...E,\u7BC0:N.\u7BC0},Fable:G,\u5931\u6557:"",\u7167\u3089\u3057\u5931\u6557:"",\u5186:z}}catch(A){return{\u983C\u307F:k,\u7BC0:E,Fable:null,\u5931\u6557:"",\u7167\u3089\u3057\u5931\u6557:A instanceof Error?A.message:String(A),\u5186:0}}}));R.default.mkdirSync(O,{recursive:!0});let Z=["\u4ED5\u69D8\u66F8\uFF08\u4EBA\u304C\u8AAD\u3080\u7248\uFF09.md","spec-for-readers.md"].find(f=>R.default.existsSync(W.default.join(s,f))),X=new Date().toLocaleDateString("sv-SE");console.log("");let In=0;y.forEach((f,k)=>{let x=K[k];if(x.\u5931\u6557||!x.\u7BC0){console.log(l.\u5931\u6557(f.\u6750.\u984C,x.\u5931\u6557));return}let E=re({\u6750\u6599:f.\u6750,\u756A\u53F7:k+1,\u5168\u90E8:y.length,Writer\u7BC0:x.\u7BC0.\u7BC0,\u6368\u3066\u305F\u7BC0:x.\u7BC0.\u6368\u3066\u305F,\u983C\u307F:x.\u983C\u307F,\u8A08\u7B97:f.\u8A08\u7B97,\u30B3\u30FC\u30C9\u306E\u30D5\u30A1\u30A4\u30EB:a(p),\u7247:f.\u7247,\u65E5\u4ED8:X,\u5168\u4F53\u306E\u4ED5\u69D8\u66F8:Z,PARAMS:$?.PARAMS??null,Fable:x.Fable}),A=ie(f.\u6750.\u984C),S=W.default.join(O,`${k+1}_${/^[\x21-\x7e]+$/.test(A)?A:"system"}.md`),N=[p,r?t:null].filter(z=>!!z&&R.default.existsSync(z)).map(z=>({\u540D:a(z),\u6307\u7D0B:an(R.default.readFileSync(z,"utf8"))}));R.default.writeFileSync(S,ln(E.md,{\u9053\u5177:"system-docs",\u65E5:un(),\u3082\u3068:N}));let G=E.\u7167\u3089\u3057\u5408\u308F\u305B;console.log(l.\u66F8\u3044\u305F(a(S),l.\u7167(G.\u6750\u6599\u306B\u7121\u3044\u6570,G.PARAMS\u306B\u7121\u3044.length,G.\u5206\u304B\u3089\u306A\u3044,G.\u6368\u3066\u305F\u7BC0))),x.Fable?console.log(l.\u7167\u3089\u3057\u305F(x.Fable.\u5F53\u3066\u305F.length,x.Fable.\u5F53\u3066\u3089\u308C\u306A\u304B\u3063\u305F.length,x.Fable.\u5408\u308F\u306A\u3044.length)):M&&(In+=1,console.log(l.\u7167\u3089\u3057\u5931\u6557(x.\u7167\u3089\u3057\u5931\u6557)))});let Rn=K.reduce((f,k)=>f+k.\u5186,0);if(M&&Rn>0&&console.log(`
360
+ `+l.\u8CBB\u7528(Math.round(Rn))),console.log(`
361
+ `+(M&&!In?l.\u6700\u5F8C\u7167\u3089\u3057\u305F:l.\u6700\u5F8C)),o.\u6B8B\u9AD8!=null){let f=k=>Math.round(k*100)/100;console.log(u?`This run: \xA5${f(o.\u5186)} \xB7 Kokoro balance: \xA5${f(o.\u6B8B\u9AD8)}`:`\u3053\u306E\u52D5\u304D\u3067 ${f(o.\u5186)} \u5186 \u30FB Kokoro \u306E\u6B8B\u9AD8 ${f(o.\u6B8B\u9AD8)} \u5186`)}}var hn="0.1.1",Sn=(process.env.KOKORO_API_BASE||"https://usekokoro.com").replace(/\/+$/,""),F=(()=>{let n=process.argv.indexOf("--lang"),e=n>=0?process.argv[n+1]:"";return e==="ja"||e==="en"?e:(process.env.LANG||process.env.LC_ALL||Intl.DateTimeFormat().resolvedOptions().locale||"").toLowerCase().startsWith("ja")?"ja":"en"})(),le={blog:["\u3075\u3064\u3046\u306B\uFF08\u8AAD\u307F\u3084\u3059\u304F\uFF09","Readable article"],manual:["\u696D\u52D9\u30DE\u30CB\u30E5\u30A2\u30EB","Manual"],spec:["\u4ED5\u69D8\u66F8","Spec"],report:["\u5831\u544A\u66F8","Report"],proposal:["\u63D0\u6848\u66F8\u30FB\u4F01\u753B\u66F8","Proposal"],minutes:["\u8B70\u4E8B\u9332","Meeting minutes"],apology:["\u304A\u8A6B\u3073\u6587","Apology"],email_formal:["\u30D3\u30B8\u30CD\u30B9\u30E1\u30FC\u30EB","Business email"]},ue={default:["\u81EA\u7531","Free"],poem:["\u8A69","Poem"],story:["\u77ED\u7DE8","Short story"],email_formal:["\u30E1\u30FC\u30EB\u30FB\u30D5\u30A9\u30FC\u30DE\u30EB","Formal email"],email_casual:["\u30E1\u30FC\u30EB\u30FB\u30AB\u30B8\u30E5\u30A2\u30EB","Casual email"],sns:["SNS \u6295\u7A3F","Social post"],pitch_lead:["\u4F01\u753B\u66F8\u30EA\u30FC\u30C9","Pitch lead"],self_intro:["\u81EA\u5DF1\u7D39\u4ECB","Self-introduction"],speech:["\u30D7\u30EC\u30BC\u30F3\u53F0\u672C","Talk script"],ad_copy:["\u5E83\u544A\u30B3\u30D4\u30FC","Ad copy"],review:["\u611F\u60F3\u6587","Review"],letter:["\u624B\u7D19","Letter"]},jn=(n,e)=>n[e]?n[e][F==="en"?1:0]:e,v={ja:{\u4F55\u3082\u7121\u3044:'\u4ED5\u7ACB\u3066\u308B\u6587\u7AE0\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u304B\u3001"\u6587\u7AE0" \u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: npx kokoro-writer \u30E1\u30E2.md --format minutes\uFF09\u3002',\u4ED5\u7ACB\u3066\u4E2D:n=>`${n} \u4ED5\u7ACB\u3066\u3066\u3044\u307E\u3059\u2026`,\u4E0A\u66F8\u304D:n=>`${n} \u306F\u3082\u3046\u3042\u308A\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u307E\u3059\u304B\uFF1F [y/n] `,\u3084\u3081\u305F:"\u66F8\u304D\u51FA\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002",\u66F8\u3044\u305F:n=>`\u66F8\u304D\u307E\u3057\u305F: ${n}`,\u30E1\u30E2:"Writer \u306E\u30E1\u30E2:",\u63D0\u6848:"\u6B21\u306E\u63D0\u6848:",\u78BA\u304B\u3081\u3069\u3053\u308D:"\u2605\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\uFF08\u5165\u308C\u305F\u6587\u7AE0\u306B\u7121\u3044\u3053\u3068\u3092\u3001AI \u304C\u66F8\u304D\u8DB3\u3057\u3066\u3044\u307E\u3059\uFF09:",\u8584\u3044:"\u2605\u5165\u308C\u305F\u6587\u7AE0\u304C\u77ED\u3044\u306E\u3067\u3001\u4E8B\u5B9F\u306E\u4E00\u90E8\u306F AI \u306E\u77E5\u8B58\u3067\u88DC\u3063\u3066\u3044\u308B\u898B\u8FBC\u307F\u304C\u3042\u308A\u307E\u3059\u3002\u78BA\u304B\u3081\u3066\u304B\u3089\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002",\u5207\u308C\u305F:"\u2605\u9577\u3044\u305F\u3081\u3001\u9014\u4E2D\u3067\u6B62\u307E\u3063\u3066\u3044\u307E\u3059\u3002\u6587\u7AE0\u3092\u5206\u3051\u3066\u3001\u3082\u3046\u4E00\u5EA6\u4ED5\u7ACB\u3066\u3066\u304F\u3060\u3055\u3044\u3002",\u5931\u6557:n=>`\u6B62\u307E\u308A\u307E\u3057\u305F: ${n}`,\u305D\u306E\u307E\u307E:"\u305D\u306E\u307E\u307E\u6574\u3048\u308B",\u4E00\u89A7:(n,e)=>`\u6587\u66F8\u306E\u5F62\uFF08--format\uFF09:
362
+ ${n}
363
+
364
+ \u6587\u4F53\uFF08--style\uFF09:
365
+ ${e}
366
+
367
+ \u3069\u3061\u3089\u3082\u4ED8\u3051\u306A\u3051\u308C\u3070\u300C\u305D\u306E\u307E\u307E\u6574\u3048\u308B\u300D\uFF08\u8A00\u8449\u306F\u5909\u3048\u305A\u306B\u898B\u51FA\u3057\u3084\u7B87\u6761\u66F8\u304D\u3060\u3051\u6574\u3048\u308B\uFF09\u3002`,\u4F7F\u3044\u65B9:`\u4F7F\u3044\u65B9: npx kokoro-writer <\u30D5\u30A1\u30A4\u30EB \u307E\u305F\u306F "\u6587\u7AE0"> [--format spec] [--style email_formal] [--model haiku|sonnet|sonnet-expert] [--out \u540D\u524D.md] [--yes] [--list] [--lang ja|en]
368
+ npx kokoro-writer spec-doc [\u30D5\u30A9\u30EB\u30C0 \u304B \u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB] [--code \u30D5\u30A1\u30A4\u30EB] [--out \u540D\u524D.md] [--yes] \u2026 kokoro-spec.md \u304B\u3089\u4EBA\u304C\u8AAD\u3080\u4ED5\u69D8\u66F8\uFF08AI \u304C\u66F8\u304F\u306E\u306F\u6982\u8981\u3068\u8003\u3048\u65B9\u3060\u3051\uFF09
369
+ npx kokoro-writer system-docs [\u30D5\u30A9\u30EB\u30C0 \u304B \u4ED5\u69D8\u306E\u30D5\u30A1\u30A4\u30EB] [--code \u30D5\u30A1\u30A4\u30EB] [--yes] [--no-check] \u2026 \u30B3\u30FC\u30C9\u304B\u3089\u4ED5\u7D44\u307F\u3054\u3068\u306E\u4ED5\u69D8\u66F8\uFF08AI \u304C\u5206\u3051\u3066\u66F8\u304D\u3001\u5225\u306E AI \u304C\u30B3\u30FC\u30C9\u3068\u7167\u3089\u3057\u5408\u308F\u305B\u308B\uFF09`},en:{\u4F55\u3082\u7121\u3044:'Nothing to write. Pass a file name or "text" (e.g. npx kokoro-writer notes.md --format minutes).',\u4ED5\u7ACB\u3066\u4E2D:n=>`Writing: ${n}\u2026`,\u4E0A\u66F8\u304D:n=>`${n} already exists. Overwrite? [y/n] `,\u3084\u3081\u305F:"Nothing was written.",\u66F8\u3044\u305F:n=>`Written: ${n}`,\u30E1\u30E2:"Notes from Writer:",\u63D0\u6848:"Suggestion:",\u78BA\u304B\u3081\u3069\u3053\u308D:"\u2605Please check (the AI added things that were not in your text):",\u8584\u3044:"\u2605Your text was short, so some facts were probably filled in from the AI's general knowledge. Check before using.",\u5207\u308C\u305F:"\u2605It stopped partway because it was too long. Split the text and run again.",\u5931\u6557:n=>`Stopped: ${n}`,\u305D\u306E\u307E\u307E:"Tidy only",\u4E00\u89A7:(n,e)=>`Document formats (--format):
370
+ ${n}
371
+
372
+ Styles (--style):
373
+ ${e}
374
+
375
+ With neither, it only tidies (keeps your words, adds headings and lists).`,\u4F7F\u3044\u65B9:`Usage: npx kokoro-writer <file or "text"> [--format spec] [--style email_formal] [--model haiku|sonnet|sonnet-expert] [--out name.md] [--yes] [--list] [--lang ja|en]
376
+ npx kokoro-writer spec-doc [folder or spec file] [--code file] [--out name.md] [--yes] \u2026 a spec for people to read, from kokoro-spec.md (AI writes only the overview and design approach)
377
+ npx kokoro-writer system-docs [folder or spec file] [--code file] [--yes] [--no-check] \u2026 one spec per system, from your code (AI splits and writes; another AI checks against the code)`}}[F];async function Ee(){let n=process.argv.slice(2);if(n.includes("--version")||n.includes("-v")){console.log(hn);return}if(n.includes("--help")||n.includes("-h")){console.log(v.\u4F7F\u3044\u65B9);return}if(n.includes("--list")){let d=b=>Object.keys(b).map(I=>` ${I.padEnd(14)} ${jn(b,I)}`).join(`
378
+ `);console.log(v.\u4E00\u89A7(d(le),d(ue)));return}if(n.includes("--demo")){let d=_n("writer",F,(b,I)=>L.default.writeFileSync(b,I),b=>L.default.existsSync(b));console.log(On({ja:"npx kokoro-writer \u30E1\u30E2.md --format minutes",en:"npx kokoro-writer notes.md --format minutes"},d.\u898B\u672C.\u983C\u307F,d.\u66F8\u3044\u305F,F,d.\u65E5\u672C\u8A9E\u3060\u3051));return}let e=Tn("Kokoro\u3082");e||(console.error(vn("Kokoro\u3082",F)),console.error(Wn("npx kokoro-writer",F)),process.exit(1)),console.log(Mn(e,F));let t=new Set(["--format","--style","--model","--out","--lang","--code"].map(d=>n.indexOf(d)+1).filter(d=>d>0)),s=d=>n.includes(d)?n[n.indexOf(d)+1]:void 0,r=n[0]==="spec-doc",i=n[0]==="system-docs",u=n.filter((d,b)=>!((r||i)&&b===0)&&!d.startsWith("--")&&!t.has(b)).join(" ").trim();!u&&!r&&!i&&(console.error(v.\u4F55\u3082\u7121\u3044),process.exit(1));let o=L.default.existsSync(u)&&L.default.statSync(u).isFile()?B.default.resolve(u):null,c=o?L.default.readFileSync(o,"utf8"):u,l=s("--format"),a=s("--style"),p=s("--model"),g=ge.default.createInterface({input:H.stdin,output:H.stdout,terminal:!!H.stdin.isTTY}),m=[],h=null,$=!1;g.on("line",d=>{if(h){let b=h;h=null,b(d)}else m.push(d)}),g.on("close",()=>{if($=!0,h){let d=h;h=null,d(null)}});let j=d=>new Promise((b,I)=>{if(H.stdout.write(d),H.stdin.isTTY||H.stdout.write(`
379
+ `),m.length){b(m.shift());return}if($){I(new Error(F==="en"?"input ended":"\u5165\u529B\u304C\u7D42\u308F\u308A\u307E\u3057\u305F"));return}h=y=>y===null?I(new Error(F==="en"?"input ended":"\u5165\u529B\u304C\u7D42\u308F\u308A\u307E\u3057\u305F")):b(y)});try{if(r){await Zn({\u5F15\u6570:n,\u5024:s,\u7D20:u,\u8A00\u8449:F,\u30AD\u30FC:e,\u7A93\u53E3\u306E\u5143:Sn,\u7248:hn,\u805E\u304F:j,t:v});return}if(i){await ae({\u5F15\u6570:n,\u5024:s,\u7D20:u,\u8A00\u8449:F,\u30AD\u30FC:e,\u7A93\u53E3\u306E\u5143:Sn,\u7248:hn,\u805E\u304F:j});return}let d=B.default.resolve(s("--out")??(o?B.default.join(B.default.dirname(o),`${B.default.parse(o).name}.writer.md`):"kokoro-writer.md"));if(L.default.existsSync(d)){if(n.includes("--yes")){let{dir:O,name:_,ext:w}=B.default.parse(d);for(let K=2;L.default.existsSync(d);K+=1)d=B.default.join(O,`${_}-${K}${w}`)}else if(!(await j(v.\u4E0A\u66F8\u304D(d))).trim().toLowerCase().startsWith("y")){console.log(v.\u3084\u3081\u305F);return}}let b=[l?jn(le,l):"",a?jn(ue,a):""].filter(Boolean).join(" \xD7 ")||v.\u305D\u306E\u307E\u307E;console.log(v.\u4ED5\u7ACB\u3066\u4E2D(b));let I=await fetch(`${Sn}/api/v1/writer`,{method:"POST",headers:{"Content-Type":"application/json",...e.\u898B\u51FA\u3057,"user-agent":`kokoro-writer/${hn}`},body:JSON.stringify({text:c,lang:F,...l?{format:l}:{},...a?{style:a}:{},...p?{model:p}:{}}),signal:AbortSignal.timeout(3e5)}),y=await I.json().catch(()=>({}));if(!I.ok||!y.markdown){let O=typeof y.error=="string"?y.error:y.error?.message;throw new Error(O||`HTTP ${I.status}`)}L.default.writeFileSync(d,y.markdown),console.log(`
380
+ `+v.\u66F8\u3044\u305F(d));let M=en(y,F);M&&console.log(M),y.truncated&&console.log(v.\u5207\u308C\u305F),y.addedFacts?.length&&(console.log(`
381
+ `+v.\u78BA\u304B\u3081\u3069\u3053\u308D),y.addedFacts.forEach(O=>console.log(` \u30FB${O}`))),y.thinInput&&console.log(`
382
+ `+v.\u8584\u3044),y.notes&&console.log(`
383
+ ${v.\u30E1\u30E2}
384
+ ${y.notes.replace(/\n/g,`
385
+ `)}`),y.suggestion&&console.log(`
386
+ ${v.\u63D0\u6848}
387
+ ${y.suggestion.replace(/\n/g,`
388
+ `)}`)}finally{g.close()}}Ee().catch(n=>{console.error(v.\u5931\u6557(n instanceof Error?n.message:String(n))),process.exit(1)});
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "kokoro-writer",
3
+ "version": "0.1.1",
4
+ "description": "Turn rough notes into a finished document (spec, meeting minutes, manual, report, proposal, business email…) in Markdown, from your terminal. Uses your own Anthropic API key.",
5
+ "homepage": "https://github.com/xmichinokux/kokoro-os-tools#readme",
6
+ "bin": {
7
+ "kokoro-writer": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist/cli.js",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "engines": {
15
+ "node": ">=22"
16
+ },
17
+ "keywords": [
18
+ "writing",
19
+ "markdown",
20
+ "documentation",
21
+ "meeting-minutes",
22
+ "kokoro-os"
23
+ ],
24
+ "license": "PolyForm-Shield-1.0.0",
25
+ "author": "Masanori Chida (Kokoro OS)",
26
+ "scripts": {
27
+ "build": "node build.mjs",
28
+ "prepublishOnly": "node build.mjs"
29
+ }
30
+ }