aptly 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +45 -0
  3. package/README.ja.md +45 -0
  4. package/README.md +45 -0
  5. package/README.zh-CN.md +45 -0
  6. package/dist/bin/aptly.d.ts +2 -0
  7. package/dist/bin/aptly.js +122 -0
  8. package/dist/src/automatic-hook.d.ts +42 -0
  9. package/dist/src/automatic-hook.js +232 -0
  10. package/dist/src/catalog.d.ts +19 -0
  11. package/dist/src/catalog.js +135 -0
  12. package/dist/src/config.d.ts +24 -0
  13. package/dist/src/config.js +75 -0
  14. package/dist/src/core.d.ts +50 -0
  15. package/dist/src/core.js +324 -0
  16. package/dist/src/diagnostics.d.ts +11 -0
  17. package/dist/src/diagnostics.js +68 -0
  18. package/dist/src/files.d.ts +10 -0
  19. package/dist/src/files.js +70 -0
  20. package/dist/src/hook.d.ts +20 -0
  21. package/dist/src/hook.js +102 -0
  22. package/dist/src/inspect.d.ts +31 -0
  23. package/dist/src/inspect.js +219 -0
  24. package/dist/src/model-info.d.ts +32 -0
  25. package/dist/src/model-info.js +223 -0
  26. package/dist/src/provenance.d.ts +62 -0
  27. package/dist/src/provenance.js +266 -0
  28. package/dist/src/provider.d.ts +9 -0
  29. package/dist/src/provider.js +80 -0
  30. package/dist/src/report.d.ts +51 -0
  31. package/dist/src/report.js +177 -0
  32. package/dist/src/runtime.d.ts +8 -0
  33. package/dist/src/runtime.js +22 -0
  34. package/dist/src/server.d.ts +7 -0
  35. package/dist/src/server.js +80 -0
  36. package/dist/src/setup.d.ts +22 -0
  37. package/dist/src/setup.js +408 -0
  38. package/dist/src/types.d.ts +76 -0
  39. package/dist/src/types.js +2 -0
  40. package/dist/src/version.d.ts +1 -0
  41. package/dist/src/version.js +1 -0
  42. package/docs/ADVISORY_USAGE.md +196 -0
  43. package/docs/DRAFT_0_1_0.md +55 -0
  44. package/docs/guide/en.md +190 -0
  45. package/docs/guide/ja.md +190 -0
  46. package/docs/guide/ko.md +190 -0
  47. package/docs/guide/zh-CN.md +190 -0
  48. package/examples/claude-mcp.json +15 -0
  49. package/examples/codex-mcp.toml +9 -0
  50. package/examples/recommend.claude.json +9 -0
  51. package/examples/recommend.codex.json +9 -0
  52. package/examples/router.shadow.json +5 -0
  53. package/examples/settings-inventory.json +5 -0
  54. package/package.json +75 -0
@@ -0,0 +1,190 @@
1
+ # Aptly 使用ガイド
2
+
3
+ [한국어](ko.md) · [English](en.md) · [简体中文](zh-CN.md) · **日本語**
4
+
5
+ [README に戻る](../../README.ja.md)
6
+
7
+ 韓国語版が正本です。このガイドは 0.1.0 ローカルパッケージ案を対象とします。npm registry で公開済みであることや、すべてのアカウントでモデルにアクセスできることを意味しません。子エージェントの実行・承認・サンドボックス・MCP 権限は、Claude Code または Codex が管理します。
8
+
9
+ ## インストール
10
+
11
+ Node.js 24 以上と Claude Code または Codex が必要です。確認済みのアーカイブとインストール先を指定してください。
12
+
13
+ ```sh
14
+ aptly_install=/absolute/aptly-local
15
+ npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
16
+ "$aptly_install/node_modules/.bin/aptly" setup --client all --mode defaults
17
+ ```
18
+
19
+ 以降の例の `aptly` は、上記のインストール先にある実行ファイルを指します。PATH に追加していない場合はフルパスで実行してください。インストール済みの `node_modules` 内で TypeScript ソースを直接実行しないでください。
20
+
21
+ `postinstall` は、現在のユーザーの既存のホスト設定ディレクトリに MCP と `PreToolUse` Hook を登録します。`CODEX_HOME`・`CLAUDE_CONFIG_DIR` を使う場合は、インストールプロセスにも同じ環境を渡してください。まだ存在しないホストディレクトリは自動登録ではスキップし、明示的な `setup` で作成できます。必要なホストだけを登録するには、`--client codex` または `--client claude` を使用してください。
22
+
23
+ 新規登録では `ROUTER_PROVIDER=decisions`、Hook の `defaults` ポリシー、ホストごとの非公開台帳を指定します。他の既存設定・Hook と、既存の Aptly のコマンド・環境・provider・台帳パスは保持します。既存の fixture 設定を自動で有料モードに切り替えることはありません。
24
+
25
+ ### キーと再起動
26
+
27
+ `OPENAI_API_KEY` は分類用のキーです。子エージェントのモデルが使用する既存のログイン・サブスクリプション認証とは別のものです。ユーザーの認証情報ストアや安全な実行環境から、**MCP プロセスの環境変数として渡して**ください。キーをコマンドライン・ツール引数・リクエスト JSON・MCP 設定 JSON・ソース・ログ・一時ファイルに含めないでください。特定の認証情報ストアは必須ではありません。
28
+
29
+ ホストを新しく起動するか MCP サーバーを再起動して、登録と環境を読み込ませてください。別のターミナルで環境変数を変更するだけでは、実行中の GUI・MCP の環境は更新されません。**Codex では `/hooks` で新しい Hook の正確な定義を確認し、信頼を承認する必要があります。** インストーラーがこの承認を迂回することはありません。
30
+
31
+ キーがない場合や、接続・認証・タイムアウトのエラーが発生した場合は、元の呼び出しの引数を変更しません。直接 Decisions を呼び出すには、次の環境が必要です。
32
+
33
+ | 環境変数 | 用途 |
34
+ |---|---|
35
+ | `OPENAI_API_KEY` | 安全な実行環境から注入する分類用キー |
36
+ | `ROUTER_PROVIDER=decisions` | 実際の分類 API を使用 |
37
+ | `ROUTER_LEDGER_PATH` | ユーザー所有・権限 700 の非公開ディレクトリ内にある台帳の絶対パス |
38
+
39
+ ### スキップ・削除
40
+
41
+ ```sh
42
+ APTLY_SKIP_SETUP=1 npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
43
+ aptly setup --client codex --mode defaults
44
+ aptly remove --client all
45
+ ```
46
+
47
+ `CI` 環境や npm の `--ignore-scripts` でも自動登録をスキップします。直接 `setup` を実行して登録できます。`advisory` モードは推薦だけを伝え、引数は変更しません。ポリシーを変える場合は、既存の登録を削除した後、希望する `--mode` で再登録してください。結果が `partial` の場合は client ごとのエラーコードを確認してください。削除の対象は、登録時の所有情報と一致する項目だけです。ユーザーが変更した項目は保持し、競合があることを通知します。
48
+
49
+ ## 自動 Hook
50
+
51
+ 接続済みの対象呼び出しは、`route_spawn_hook` → Decisions を自動で経由します。`defaults` は、対象範囲でホストのデフォルトモデルより Aptly の選択を優先することを、運用者が許可するポリシーです。このポリシーは、ホストのすべての設定元を確認したことを示すものではありません。
52
+
53
+ | ホスト | 自動選択の対象 |
54
+ |---|---|
55
+ | Codex | モデル・effort・固定ロール・resume の指定がなく、`fork_turns: "none"` の新しい汎用呼び出し |
56
+ | Claude Code | モデル・effort・固定ロール・resume・履歴継承の指定がない、`subagent_type: "general-purpose"` の呼び出し |
57
+
58
+ 明示的な指定とロール・fork・resume、承認・サンドボックス・MCP 権限は保持します。fixture の結果でデフォルトモデルを自動変更することはありません。コンテキスト不足・未対応の応答・キャンセル・呼び出しの変更がある場合は、元の引数を変更しません。同じ呼び出しの入力・ポリシー・カタログを結び付け、非同期応答後に再確認します。
59
+
60
+ 別途設定せずに実行する CLI と既存の手動設定は、fixture / shadow がデフォルトです。ホスト設定の証拠(host-evidence)に基づく従来の経路は、自動ポリシーがない場合のものです。インストールしたデフォルト値選択ポリシーとは区別してください。ホスト内部のパッチは保留中で、直接推薦の前提条件ではありません。
61
+
62
+ | MCP ツール | 用途 |
63
+ |---|---|
64
+ | `get_routing_capabilities` | 候補・制限・provider・Hook の状態を、有料 API を呼び出さずに確認します |
65
+ | `recommend_agent` | タスク要約から直接推薦を取得します |
66
+ | `get_routing_precedence` | 呼び出しを保持する根拠と、未確認の設定元を説明します |
67
+ | `route_spawn_hook` | インストールしたポリシーに応じて、対象呼び出しのデフォルト値を選択するか、推薦だけを伝えます |
68
+
69
+ ## 直接推薦
70
+
71
+ `recommend_agent` MCP と CLI の `recommend` は、タスク要約を受け取ってプロファイルを推薦します。子エージェントを直接生成することはありません。以下の JSON を MCP ツールの引数として渡すか、ファイルに保存して CLI の標準入力に渡してください。
72
+
73
+ ```json
74
+ {
75
+ "request_id": "demo-codex-sort-001",
76
+ "client": "codex",
77
+ "task": {
78
+ "summary": "Sort the supplied numbers [3, 1, 2] into ascending order. No files or network are needed.",
79
+ "operation": "analysis",
80
+ "context_sufficient": true
81
+ }
82
+ }
83
+ ```
84
+
85
+ ```sh
86
+ ROUTER_PROVIDER=fixture aptly recommend < request.json
87
+ aptly capabilities
88
+ aptly config codex
89
+ aptly config claude
90
+ ```
91
+
92
+ fixture は、キー・ネットワーク・子エージェントの実行なしで、ローカルで生成した試験用の結果を返します。実際の Decisions の判断や品質試験の結果ではありません。`config` は手動 MCP 登録用の断片を出力するだけで、`setup` は設定を実際に変更します。実際の API を使う場合は、前述のキー・provider・非公開台帳を準備してください。
93
+
94
+ `task.operation` は `read_only`、`write`、`review`、`analysis` のいずれかです。`context_sufficient` は、呼び出し元が必要な要約を提供したことを表すもので、ホスト設定の検証ではありません。`eligible_profile_ids` を省略すると、その client の有効なカタログを使用し、指定すると、その中で候補を制限します。
95
+
96
+ `constraints` の `model_pinned`、`effort_pinned`、`role_pinned`、`fork_inherits` のいずれかが true の場合は、既存の選択を保持します。省略は、この計画用リクエストで保持条件を宣言していないことを意味します。実際のホストで値が固定指定(pin)されていないことを証明するものではありません。新規リクエストでは `provenance_verified` を使用しないでください。
97
+
98
+ | status | 次の操作 |
99
+ |---|---|
100
+ | `recommended` | `profile` を確認し、既存のホストで別途実行するかどうかを判断してください |
101
+ | `keep_current` | 明示的な選択を保持するか、推薦を保留してください |
102
+ | `needs_context` | 必要な要約を補ってください |
103
+ | `unavailable` | 返された `reason` を確認してください。結果が不明な有料リクエストを新しい ID で自動再実行しないでください |
104
+
105
+ 直接推薦の `application: advisory_only` は、ホスト設定の確認・モデルへのアクセス権限・実行承認を意味しません。完了済みの結果を再照会する際は、同じ ID・入力・ポリシー・台帳を使用してください。`unknown` は結果が不明確であることを意味するため、新しい ID で無条件に再試行しないでください。コンテキストの補完で入力が変わった新規リクエストには、別の ID を使用してください。
106
+
107
+ ## モデルと環境変数
108
+
109
+ デフォルト候補は 6 つのプロファイルです。この区分は Aptly の運用プリセットであり、両プロバイダーのモデルが同等という意味ではありません。
110
+
111
+ | 区分 | Claude Code | Codex | 代表的なタスク |
112
+ |---|---|---|---|
113
+ | simple | `haiku` | `gpt-6-luna` / `max` | 抽出・形式変換・小さな機械的修正 |
114
+ | routine | `sonnet` | `gpt-6.1-terra` / `high` | コンテキストを考慮した執筆・翻訳・範囲が明確な実装 |
115
+ | deep | `opus` | `gpt-6.1-sol` / `medium` | 複数コンポーネントにまたがるデバッグ・設計判断・掘り下げたレビュー |
116
+
117
+ MCP の `env` の値は文字列なので、候補配列も JSON 文字列として渡します。
118
+
119
+ ```json
120
+ {
121
+ "env": {
122
+ "APTLY_CLAUDE_MODELS": "[\"haiku\", \"sonnet\", \"opus\"]",
123
+ "APTLY_CODEX_MODELS": "[\"gpt-6-luna\", \"gpt-6.1-terra\", \"gpt-6.1-sol\"]"
124
+ }
125
+ }
126
+ ```
127
+
128
+ 未指定の場合は上記のデフォルト値を使い、`[]` の場合はその client の推薦を無効にします。空の文字列・重複・未対応のモデル・不正な JSON はエラーです。`CLAUDE_MODELS`・`CODEX_MODELS` も別名として利用できますが、同じプロバイダーの標準名と別名を同時に設定するとエラーになります。候補設定は、既存の選択を上書きしたり、アカウントのモデルへのアクセス権限を認証したりするものではありません。
129
+
130
+ ### 公式説明とキャッシュ
131
+
132
+ Decisions の選択肢には、モデル名・Codex effort・公式の特性・タスク区分の説明を一緒に送ります。同梱の説明で開始でき、推薦のたびにドキュメントを取得することはありません。最新の公式 Markdown を反映するには、明示的に更新します。出力先の親ディレクトリは、ユーザー所有の非公開ディレクトリとして事前に用意してください。
133
+
134
+ ```sh
135
+ mkdir -m 700 /absolute/private-aptly-state
136
+ aptly catalog refresh --output /absolute/private-aptly-state/model-info.json
137
+ export APTLY_MODEL_INFO_PATH=/absolute/private-aptly-state/model-info.json
138
+ ```
139
+
140
+ 更新時は、固定の [Claude モデルドキュメント](https://code.claude.com/docs/en/model-config.md)と [OpenAI モデルドキュメント](https://learn.chatgpt.com/docs/models.md)だけを読み、API キーは必要ありません。短く正規化したモデル情報だけを保存し、失敗した場合は既存のファイルを保持します。起動時にキャッシュを読み、7 日を超えているか無効な場合は同梱の説明を使用します。更新後は MCP を再起動してください。新しいドキュメントにモデルが登場しても、候補を自動追加したり、アカウントでのアクセス可否を確認したりすることはありません。
141
+
142
+ ## コンテキストの提供
143
+
144
+ Codex が子エージェントの `message` を暗号文として Hook に渡す環境では、本文を読み取ったり復号したりしません。この場合は、十分に具体的な平文の `task_name` だけを要約として使用します。たとえば `sort_supplied_numbers_3_1_2_ascending_without_tools` のように、タスクの種類と範囲を表します。短い名前や曖昧な名前の場合は、元のモデルを保持します。Claude Code と平文の本文が渡される呼び出しでは、提供された本文の要約を使用します。
145
+
146
+ `get_routing_capabilities` の `automatic_hook.last_result` で、その MCP プロセスによる最後の適用・保持の理由を確認できます。`null` は、まだ自動 Hook の処理記録がないことを意味します。タスクの本文や個人の設定値は返しません。
147
+
148
+ 直接推薦では、リポジトリ・ファイルの URL と、ドキュメントを読んで整理したタスクの範囲・規模・制約を、要約に含めて提供できます。URL の文字列を送ることと、ドキュメントの本文を提供することは異なります。現在の Aptly の分類リクエスト処理コードは、リポジトリ URL を GET したり、ドキュメントを収集したりしません。必要なドキュメントの取得と要約は、呼び出し元が行います。
149
+
150
+ 現在の自動 Hook には、URL を別途平文で渡すフィールドがありません。URL を暗号化される `message` に追加しただけで、分類に渡されるとは想定しないでください。直接 MCP 推薦を受け取り、そのプロファイルをホストの呼び出し引数として渡す経路と、自動 Hook の適用は区別してください。
151
+
152
+ ## 費用実測
153
+
154
+ 2026-11-05 に [session-peer の英語 README](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.md)を正本として、[韓国語訳](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.ko.md)をレビューしました。合計 17,964 バイトの同じドキュメントと同じ指示で、実行ごとに 6 件の修正案を作成し、原本は変更していません。
155
+
156
+ タスク名だけを提供した自動 Hook 試験は、3 回とも `needs_context` で保留されました。`recommend_agent` にリポジトリ・ファイル URL を追加した 3 回と、URL にドキュメントの要約も追加した 3 回は、すべて Terra/high を推薦しました。以下は、URL+要約条件での実際の Terra/high 実行 3 回を、直前の Sol/high 実行 3 回と比較した 1 回あたりの平均です。
157
+
158
+ | Standard API 換算基準 | Sol/high | Terra/high + 分類費用 | 減少率 |
159
+ |---|---:|---:|---:|
160
+ | 実際のキャッシュ使用量を反映 | $0.03229 | $0.01354 | 58.05% |
161
+ | 入力全体をキャッシュなしで換算 | $0.11254 | $0.05363 | 52.35% |
162
+
163
+ ホストが記録した実測トークン数に [公式の Standard API 単価](https://developers.openai.com/api/docs/pricing)を適用した USD 換算値です。サブスクリプションの実際の請求額や、利用枠から実際に差し引かれた量を示すものではありません。Terra 側には [Decisions の分類費用](https://developers.openai.com/api/docs/guides/decisions) 1 回あたり $0.0000756 を含めています。比較範囲はレビューする子エージェントと分類で、ドキュメントの収集・要約の準備・メインエージェントの調査費用は除外しています。
164
+
165
+ 測定経路は、**明示的な MCP 推薦 → 推薦プロファイルを引数として渡したホスト上での実行**です。自動 Hook の URL 収集・伝達機能を検証したものではありません。基準群は直前の実測を再利用しており、条件ごとの標本は 3 回です。ドキュメント全体の読み取り・原文の引用一致・出力形式は確認しましたが、品質の同等性、統計的有意性、他のタスクでの費用削減を保証するものではありません。
166
+
167
+ ## 診断と開発
168
+
169
+ ```sh
170
+ aptly report --format both --output-dir reports
171
+ ```
172
+
173
+ report は、同じ ID の Markdown・JSON を非公開ファイルとして作成します。確認後に手動で共有し、自動アップロードは行いません。添付ファイルにキー・個人のパス・環境値・タスクの本文・加工していないエラー情報を含めないでください。API 認証の成功や、ホスト設定全体の確認を意味するものではありません。
174
+
175
+ ソースチェックアウトでは以下のコマンドを使います。前述のインストール済み CLI の例とは、実行パスを区別してください。
176
+
177
+ ```sh
178
+ npm ci --ignore-scripts --no-audit --no-fund
179
+ npm run typecheck
180
+ npm run build
181
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.codex.json
182
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.claude.json
183
+ npm test
184
+ npm run poc
185
+ npm run check:release
186
+ ```
187
+
188
+ 標準の回帰試験と fixture を用いたスモークテストは、有料 API・実際の子エージェントなしで実行します。リリース検査は公開ファイル・個人情報パターン・npm file allowlist を確認し、公開や Git push は行いません。台帳は、完了結果の再利用・unknown の再呼び出し防止・呼び出し数・遅延・見積費用の制限に使いますが、実際の請求額の上限ではありません。
189
+
190
+ 設計・過去の検証・開発履歴は、ソースチェックアウトの他のドキュメントに保持します。この多言語ガイドはインストールと日常的な使用の基準であり、過去の研究資料のすべての主張や未実装の計画を、現在の機能として扱うものではありません。
@@ -0,0 +1,190 @@
1
+ # Aptly 사용 가이드
2
+
3
+ **한국어** · [English](en.md) · [简体中文](zh-CN.md) · [日本語](ja.md)
4
+
5
+ [README로 돌아가기](../../README.md)
6
+
7
+ 한국어가 정본입니다. 이 안내는 0.1.0 로컬 패키지 초안을 다룹니다. npm 레지스트리 게시나 모든 계정의 모델 접근 가능성을 뜻하지 않습니다. 실제 자식 실행·승인·샌드박스·MCP 권한은 Claude Code 또는 Codex가 담당합니다.
8
+
9
+ ## 설치
10
+
11
+ Node.js 24 이상과 Claude Code 또는 Codex가 필요합니다. 검토한 아카이브와 설치 위치를 지정하십시오.
12
+
13
+ ```sh
14
+ aptly_install=/absolute/aptly-local
15
+ npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
16
+ "$aptly_install/node_modules/.bin/aptly" setup --client all --mode defaults
17
+ ```
18
+
19
+ 이후 예제의 `aptly`는 위 설치 위치의 실행 파일을 가리킵니다. PATH에 연결하지 않았다면 전체 경로로 실행하십시오. 설치된 `node_modules`에서 TypeScript 소스를 직접 실행하지 마십시오.
20
+
21
+ `postinstall`은 현재 사용자의 기존 호스트 설정 디렉터리에 MCP와 `PreToolUse` Hook을 등록합니다. `CODEX_HOME`·`CLAUDE_CONFIG_DIR`을 사용한다면 설치 프로세스에도 같은 환경을 전달하십시오. 아직 없는 호스트 디렉터리는 자동 등록에서 건너뛰고, 명시적인 `setup`으로 만들 수 있습니다. 필요한 호스트만 등록하려면 `--client codex` 또는 `--client claude`를 사용하십시오.
22
+
23
+ 새 등록은 `ROUTER_PROVIDER=decisions`, Hook `defaults` 정책과 호스트별 비공개 원장을 지정합니다. 기존 다른 설정·Hook, 기존 Aptly의 실행 명령·환경·분류 방식·원장 경로는 보존합니다. 기존 fixture 설정을 자동으로 유료 모드로 바꾸지 않습니다.
24
+
25
+ ### 키와 재시작
26
+
27
+ `OPENAI_API_KEY`는 분류용 키입니다. 자식 모델의 기존 로그인·구독 인증과는 별개입니다. 사용자 자격 저장소나 안전한 실행 환경에서 **MCP 프로세스의 환경변수로 전달**하십시오. 키를 명령행·도구 인자·요청 JSON·MCP 설정 JSON·소스·로그·임시 파일에 기록하지 마십시오. 특정 자격 저장소는 요구하지 않습니다.
28
+
29
+ 호스트를 새로 시작하거나 MCP 서버를 재시작해 등록한 설정과 환경을 반영하십시오. 다른 터미널에서 환경변수를 바꾸는 것만으로 이미 실행 중인 GUI·MCP 환경이 갱신되지는 않습니다. **Codex는 `/hooks`에서 새 Hook의 정확한 정의를 검토하고 신뢰를 승인해야 합니다.** 설치 프로그램은 신뢰 승인을 우회하지 않습니다.
30
+
31
+ 키가 없거나 연결·인증·시간 제한 오류가 나면 원래 호출을 유지합니다. 직접 Decisions 호출에는 다음 환경이 필요합니다.
32
+
33
+ | 환경변수 | 용도 |
34
+ |---|---|
35
+ | `OPENAI_API_KEY` | 안전한 실행 환경에서 주입하는 분류용 키 |
36
+ | `ROUTER_PROVIDER=decisions` | 실제 분류 API 사용 |
37
+ | `ROUTER_LEDGER_PATH` | 사용자 소유·권한 700인 비공개 디렉터리 안의 절대 원장 경로 |
38
+
39
+ ### 건너뛰기·제거
40
+
41
+ ```sh
42
+ APTLY_SKIP_SETUP=1 npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
43
+ aptly setup --client codex --mode defaults
44
+ aptly remove --client all
45
+ ```
46
+
47
+ `CI` 환경이나 npm `--ignore-scripts`도 자동 등록을 건너뜁니다. 직접 `setup`으로 등록할 수 있습니다. `advisory` 모드는 추천만 전달하고 인자를 바꾸지 않습니다. 정책을 바꾸려면 기존 등록을 제거한 뒤 원하는 `--mode`로 다시 등록하십시오. `partial` 결과가 나오면 호스트별 오류 코드를 확인하십시오. 제거는 소유 기록과 일치하는 항목만 대상으로 하며, 사용자가 변경한 항목은 보존하고 충돌을 알립니다.
48
+
49
+ ## 자동 Hook
50
+
51
+ 연결된 대상 호출은 `route_spawn_hook` → Decisions를 자동 경유합니다. `defaults`는 해당 범위에서 호스트 기본 모델보다 Aptly의 선택을 우선하도록 운영자가 허용하는 정책입니다. 호스트의 모든 설정 출처를 관측했다는 선언은 아닙니다.
52
+
53
+ | 호스트 | 자동 선택 대상 |
54
+ |---|---|
55
+ | Codex | 모델·effort·고정 역할·resume을 지정하지 않고 `fork_turns: "none"`인 새 일반 호출 |
56
+ | Claude Code | 모델·effort·고정 역할·resume·이력 상속을 지정하지 않은 `subagent_type: "general-purpose"` 호출 |
57
+
58
+ 명시 선택과 역할·fork·resume, 승인·샌드박스·MCP 권한은 보존합니다. fixture 결과로 기본 모델을 자동 변경하지 않습니다. 불충분한 맥락·지원하지 않는 응답·취소·변경된 호출에서는 기존 인자를 유지합니다. 각 호출의 입력·정책·후보 정보가 일치하는지 확인하고, 비동기 응답 후 다시 확인합니다.
59
+
60
+ 별도 설정 없이 실행하는 CLI와 기존 수동 설정은 fixture / shadow가 기본입니다. 자동 정책이 없는 기존 호스트 설정 증거에 기반한 경로와 설치한 기본값 선택 정책은 구분합니다. 호스트 내부 패치는 보류 상태이며 직접 추천의 선행 조건이 아닙니다.
61
+
62
+ | MCP 도구 | 용도 |
63
+ |---|---|
64
+ | `get_routing_capabilities` | 무료로 후보·제한·분류 방식·Hook 상태를 조회합니다 |
65
+ | `recommend_agent` | 작업 요약으로 프로필 추천을 받습니다 |
66
+ | `get_routing_precedence` | 호출의 보존 근거와 미확인 설정 출처를 설명합니다 |
67
+ | `route_spawn_hook` | 설치한 정책에 따라 대상 호출의 기본값을 선택하거나 추천만 전달합니다 |
68
+
69
+ ## 직접 추천
70
+
71
+ `recommend_agent` MCP와 CLI `recommend`는 작업 요약을 받아 프로필을 추천합니다. 자식을 직접 생성하지 않습니다. 아래 JSON을 MCP 도구 인자로 전달하거나 파일에 저장해 CLI의 표준 입력으로 제공하십시오.
72
+
73
+ ```json
74
+ {
75
+ "request_id": "demo-codex-sort-001",
76
+ "client": "codex",
77
+ "task": {
78
+ "summary": "Sort the supplied numbers [3, 1, 2] into ascending order. No files or network are needed.",
79
+ "operation": "analysis",
80
+ "context_sufficient": true
81
+ }
82
+ }
83
+ ```
84
+
85
+ ```sh
86
+ ROUTER_PROVIDER=fixture aptly recommend < request.json
87
+ aptly capabilities
88
+ aptly config codex
89
+ aptly config claude
90
+ ```
91
+
92
+ fixture는 키·네트워크·자식 실행 없이 로컬 규칙으로 생성한 시험용 결과를 반환합니다. 실제 Decisions의 판단이나 품질 시험 결과가 아닙니다. `config`는 수동 MCP 등록 조각만 출력하고, `setup`은 설정을 실제 변경합니다. 실제 API를 사용할 때는 앞서 설명한 키·분류 방식·비공개 원장을 준비하십시오.
93
+
94
+ `task.operation`은 `read_only`, `write`, `review`, `analysis` 중 하나입니다. `context_sufficient`는 호출자가 필요한 요약을 제공했다는 표현이며 호스트 설정 검증이 아닙니다. `eligible_profile_ids`를 생략하면 해당 호스트에 설정된 후보 목록을 사용하고, 지정하면 그 안에서 후보를 제한합니다.
95
+
96
+ `constraints`의 `model_pinned`, `effort_pinned`, `role_pinned`, `fork_inherits` 중 하나라도 true이면 기존 선택을 보존합니다. 생략은 이 계획용 요청에서 보존 조건을 선언하지 않았다는 뜻입니다. 실제 호스트에 고정된 설정이 없다고 확인하는 의미는 아니며, 새 요청에는 `provenance_verified`를 사용하지 않습니다.
97
+
98
+ | status | 다음 행동 |
99
+ |---|---|
100
+ | `recommended` | `profile`을 검토하고 기존 호스트에서 별도로 실행 여부를 결정하십시오 |
101
+ | `keep_current` | 명시 선택을 유지하거나 추천을 보류하십시오 |
102
+ | `needs_context` | 필요한 요약을 보완하십시오 |
103
+ | `unavailable` | 결과 사유를 나타내는 `reason`을 확인하십시오. 결과가 불명확한 유료 요청을 새 ID로 자동 재호출하지 마십시오 |
104
+
105
+ 직접 추천의 `application: advisory_only`는 호스트 설정 확인·모델 접근 권한·실행 승인이 아닙니다. 완료 결과를 재조회할 때는 같은 ID·입력·정책·원장을 유지하십시오. `unknown`은 결과가 불명확하다는 뜻이므로 새 ID로 무조건 재시도하지 마십시오. 맥락을 보완해 입력이 달라진 새 요청에는 다른 ID를 사용하십시오.
106
+
107
+ ## 모델과 환경변수
108
+
109
+ 기본 후보는 여섯 프로필입니다. 등급은 Aptly의 운영 프리셋이며 두 제공사의 모델이 동급이라는 뜻은 아닙니다.
110
+
111
+ | 등급 | Claude Code | Codex | 대표 작업 |
112
+ |---|---|---|---|
113
+ | simple | `haiku` | `gpt-6-luna` / `max` | 추출·형식 변환·작은 기계적 수정 |
114
+ | routine | `sonnet` | `gpt-6.1-terra` / `high` | 문맥을 고려한 작성·번역·범위가 명확한 구현 |
115
+ | deep | `opus` | `gpt-6.1-sol` / `medium` | 복합 디버깅·설계 판단·심층 검토 |
116
+
117
+ MCP의 `env` 값은 문자열이므로 후보 배열도 JSON 문자열로 전달합니다.
118
+
119
+ ```json
120
+ {
121
+ "env": {
122
+ "APTLY_CLAUDE_MODELS": "[\"haiku\", \"sonnet\", \"opus\"]",
123
+ "APTLY_CODEX_MODELS": "[\"gpt-6-luna\", \"gpt-6.1-terra\", \"gpt-6.1-sol\"]"
124
+ }
125
+ }
126
+ ```
127
+
128
+ 미지정이면 위 기본값, `[]`이면 해당 호스트의 추천을 비활성화합니다. 빈 문자열·중복·지원하지 않는 모델·잘못된 JSON은 오류입니다. `CLAUDE_MODELS`·`CODEX_MODELS`도 별칭으로 지원하지만 같은 제공사의 기본 이름과 별칭을 동시에 설정하면 오류입니다. 후보 설정은 기존 선택을 덮어쓰거나 계정의 모델 접근 권한을 인증하지 않습니다.
129
+
130
+ ### 공식 설명과 캐시
131
+
132
+ Decisions 선택지에는 모델명·Codex effort·공식 특성·작업 등급 설명을 함께 보냅니다. 동봉한 설명으로 시작할 수 있으며 추천할 때마다 문서를 가져오지는 않습니다. 최신 공식 Markdown을 반영하려면 명시적으로 갱신하십시오. 출력 파일의 상위 디렉터리는 먼저 사용자 소유의 비공개 디렉터리로 준비하십시오.
133
+
134
+ ```sh
135
+ mkdir -m 700 /absolute/private-aptly-state
136
+ aptly catalog refresh --output /absolute/private-aptly-state/model-info.json
137
+ export APTLY_MODEL_INFO_PATH=/absolute/private-aptly-state/model-info.json
138
+ ```
139
+
140
+ 갱신은 고정된 [Claude 모델 문서](https://code.claude.com/docs/en/model-config.md)와 [OpenAI 모델 문서](https://learn.chatgpt.com/docs/models.md)만 읽으며 API 키를 요구하지 않습니다. 짧게 정규화한 모델 정보만 저장하고 실패하면 기존 파일을 보존합니다. 시작 시 캐시를 읽고 7일을 넘거나 유효하지 않으면 동봉 설명을 사용합니다. 갱신 후 MCP를 재시작하십시오. 새 문서에 모델이 나타나도 후보를 자동 추가하거나 계정 접근 가능성을 인증하지 않습니다.
141
+
142
+ ## 맥락 전달
143
+
144
+ Codex가 자식 `message`를 암호문으로 Hook에 전달하는 환경에서는 본문을 읽거나 해독하지 않습니다. 이 경우 충분히 구체적인 평문 `task_name`만 요약으로 사용합니다. 예를 들어 `sort_supplied_numbers_3_1_2_ascending_without_tools`처럼 작업 종류와 범위를 설명하십시오. 짧거나 모호한 이름은 원래 모델을 유지합니다. Claude Code와 평문 본문이 전달되는 호출은 제공된 본문 요약을 사용합니다.
145
+
146
+ `get_routing_capabilities`의 `automatic_hook.last_result`에서 해당 MCP 프로세스가 마지막으로 기본값을 적용하거나 원래 호출을 유지한 사유를 확인할 수 있습니다. `null`은 아직 자동 Hook 처리 기록이 없다는 뜻입니다. 작업 본문이나 개인 설정 값은 반환하지 않습니다.
147
+
148
+ 직접 추천에는 저장소·파일 URL과 문서를 읽고 정리한 작업 범위·규모·제약을 요약에 함께 제공할 수 있습니다. URL 문자열을 보내는 것과 문서 본문을 제공하는 것은 다릅니다. 현재 Aptly의 분류 요청 처리 코드는 저장소 URL을 GET하거나 문서를 수집하지 않습니다. 필요한 문서 조회와 요약은 호출자가 수행합니다.
149
+
150
+ 현재 자동 Hook에는 URL을 별도 평문으로 전달하는 필드가 없습니다. 암호화되는 `message`에 URL을 추가한 것만으로 해당 URL이 분류에 전달된다고 가정하지 마십시오. 직접 MCP 추천을 받고 그 프로필을 호스트의 기본 실행 인자로 전달하는 경로와 자동 Hook 적용을 구분합니다.
151
+
152
+ ## 비용 실측
153
+
154
+ 2026-11-05에 [session-peer의 영어 README](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.md)를 정본으로 [한국어 번역](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.ko.md)을 검토했습니다. 합계 17,964바이트의 같은 문서와 같은 지시로 실행마다 수정안 6개를 작성했고 원본은 수정하지 않았습니다.
155
+
156
+ 작업명만 제공한 자동 Hook 시험은 3회 모두 `needs_context`로 보류됐습니다. `recommend_agent`에 저장소·파일 URL을 추가한 3회와 URL에 문서 요약까지 추가한 3회는 모두 Terra/high를 추천했습니다. 아래는 URL+요약 조건의 실제 Terra/high 3회를 직전 Sol/high 3회와 비교한 회당 평균입니다.
157
+
158
+ | Standard API 환산 기준 | Sol/high | Terra/high + 분류비 | 감소율 |
159
+ |---|---:|---:|---:|
160
+ | 실제 캐시 사용량 반영 | $0.03229 | $0.01354 | 58.05% |
161
+ | 입력 전체를 비캐시로 환산 | $0.11254 | $0.05363 | 52.35% |
162
+
163
+ 호스트에 기록된 실측 토큰에 [공식 Standard API 단가](https://developers.openai.com/api/docs/pricing)를 적용한 USD 환산값입니다. 구독 실청구액이나 실제 한도 차감액은 아닙니다. Terra 쪽에는 [Decisions 분류 비용](https://developers.openai.com/api/docs/guides/decisions) 회당 $0.0000756을 포함했습니다. 비교 범위는 검토 자식 에이전트와 분류이며 문서 수집·요약 준비·메인 에이전트 조사 비용은 제외했습니다.
164
+
165
+ 측정은 **명시적 MCP 추천 → 추천 프로필을 인자로 전달한 호스트의 기본 실행**입니다. 자동 Hook의 URL 수집·전달 기능 검증이 아닙니다. 기준군은 직전 실측을 재사용했고 조건별 표본은 3회입니다. 문서 전체 읽기·원문 인용 일치·출력 형식은 확인했지만 품질 동등성, 통계적 유의성, 다른 업무의 절감을 보장하지 않습니다.
166
+
167
+ ## 진단과 개발
168
+
169
+ ```sh
170
+ aptly report --format both --output-dir reports
171
+ ```
172
+
173
+ report는 같은 ID를 사용하는 Markdown·JSON 비공개 파일을 만듭니다. 검토 후 수동으로 공유하며 자동 업로드하지 않습니다. 첨부 파일에 키·개인 경로·환경 값·업무 본문·원시 오류를 넣지 마십시오. API 인증 성공이나 호스트 전체 설정 확인을 뜻하지 않습니다.
174
+
175
+ 소스 코드를 내려받은 작업 디렉터리에서는 아래 명령을 사용하십시오. 앞서 설명한 설치된 CLI 예제와 실행 경로를 구분하십시오.
176
+
177
+ ```sh
178
+ npm ci --ignore-scripts --no-audit --no-fund
179
+ npm run typecheck
180
+ npm run build
181
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.codex.json
182
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.claude.json
183
+ npm test
184
+ npm run poc
185
+ npm run check:release
186
+ ```
187
+
188
+ 기본 회귀 시험과 fixture를 사용하는 동작 점검은 유료 API·실제 자식 없이 실행합니다. 릴리스 검사는 공개 파일·개인 정보 패턴·npm 배포 파일 허용 목록을 확인하며 게시나 Git push를 하지 않습니다. 원장은 완료 결과 재사용·unknown 재호출 방지·호출 수·지연·추정 비용을 제한하는 데 쓰며 실제 청구 상한은 아닙니다.
189
+
190
+ 설계·과거 검증·개발 이력은 소스 작업 디렉터리의 다른 문서에 보존합니다. 이 다국어 가이드는 설치와 일상 사용의 기준이며 과거 연구 자료의 모든 주장이나 미구현 계획을 현재 기능으로 승격하지 않습니다.
@@ -0,0 +1,190 @@
1
+ # Aptly 使用指南
2
+
3
+ [한국어](ko.md) · [English](en.md) · **简体中文** · [日本語](ja.md)
4
+
5
+ [返回 README](../../README.zh-CN.md)
6
+
7
+ 韩语文档是正本。本指南介绍 0.1.0 本地软件包草案,并不表示软件包已发布到 npm registry,或所有账户都能访问相关模型。子代理的实际执行、审批、沙箱与 MCP 权限仍由 Claude Code 或 Codex 负责。
8
+
9
+ ## 安装
10
+
11
+ 需要 Node.js 24 或更高版本,以及 Claude Code 或 Codex。请指定已审核的归档文件和安装位置。
12
+
13
+ ```sh
14
+ aptly_install=/absolute/aptly-local
15
+ npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
16
+ "$aptly_install/node_modules/.bin/aptly" setup --client all --mode defaults
17
+ ```
18
+
19
+ 后续示例中的 `aptly` 指上述安装位置的可执行文件。如果尚未将它加入 PATH,请使用完整路径运行。不要直接执行已安装 `node_modules` 中的 TypeScript 源码。
20
+
21
+ `postinstall` 会在当前用户现有的宿主配置目录中注册 MCP 和 `PreToolUse` Hook。如果使用 `CODEX_HOME` 或 `CLAUDE_CONFIG_DIR`,请向安装进程传递相同的环境。自动注册会跳过尚不存在的宿主目录;显式运行 `setup` 可以创建这些目录。若只需注册某个宿主,请使用 `--client codex` 或 `--client claude`。
22
+
23
+ 新注册项会指定 `ROUTER_PROVIDER=decisions`、Hook 的 `defaults` 策略,以及各宿主独立的私有账本。其他现有配置与 Hook,以及 Aptly 原有的命令、环境、分类方式和账本路径都会保留。现有 fixture 配置不会自动切换为付费模式。
24
+
25
+ ### 密钥与重启
26
+
27
+ `OPENAI_API_KEY` 仅用于分类,与运行子代理所用的现有登录或订阅认证是两回事。请通过用户的凭据存储或安全运行环境,**将其注入 MCP 进程的环境变量**。不要将密钥放入命令行、工具参数、请求 JSON、MCP 配置 JSON、源码、日志或临时文件。无需使用特定的凭据存储服务。
28
+
29
+ 请重新启动宿主或 MCP 服务器,使其读取注册项与环境。仅在另一个终端中更改环境变量,不会更新已运行的 GUI 或 MCP 环境。**Codex 要求在 `/hooks` 中审核新 Hook 的确切定义并批准信任。** 安装程序不会绕过信任批准。
30
+
31
+ 如果缺少密钥,或发生连接、认证、超时错误,则保留原始调用。直接调用 Decisions 需要以下环境。
32
+
33
+ | 环境变量 | 用途 |
34
+ |---|---|
35
+ | `OPENAI_API_KEY` | 通过安全运行环境注入的分类用密钥 |
36
+ | `ROUTER_PROVIDER=decisions` | 使用实际分类 API |
37
+ | `ROUTER_LEDGER_PATH` | 位于归用户所有、权限为 700 的私有目录中的账本绝对路径 |
38
+
39
+ ### 跳过与移除
40
+
41
+ ```sh
42
+ APTLY_SKIP_SETUP=1 npm install --prefix "$aptly_install" /absolute/path/aptly-0.1.0.tgz
43
+ aptly setup --client codex --mode defaults
44
+ aptly remove --client all
45
+ ```
46
+
47
+ 在 `CI` 环境中或使用 npm `--ignore-scripts` 时,也会跳过自动注册。之后可显式运行 `setup` 进行注册。`advisory` 模式只传递推荐,不修改参数。更改策略时,请先移除原有注册,再使用所需的 `--mode` 重新注册。如果结果为 `partial`,请检查各宿主对应的错误代码。移除操作仅针对与所有权记录一致的项目;用户已修改的项目会保留,并报告冲突。
48
+
49
+ ## 自动 Hook
50
+
51
+ 已连接的目标调用会自动经过 `route_spawn_hook` → Decisions。`defaults` 是由操作者明确允许的策略,可在上述范围内优先采用 Aptly 的选择,而非宿主的默认模型。这并不表示已观测到宿主的全部配置来源。
52
+
53
+ | 宿主 | 自动选择的适用范围 |
54
+ |---|---|
55
+ | Codex | 未指定模型、effort、固定角色或 resume,且 `fork_turns: "none"` 的新建通用调用 |
56
+ | Claude Code | 未指定模型、effort、固定角色、resume 或历史继承,且 `subagent_type: "general-purpose"` 的调用 |
57
+
58
+ 明确指定的选择、角色、fork、resume、审批、沙箱与 MCP 权限设置均会保留。fixture 结果不会自动修改默认模型。如果上下文不足、响应不受支持、调用被取消或已发生变化,则保留现有参数。系统会将输入、策略和候选配置集合与同一次调用绑定,并在收到异步响应后重新确认。
59
+
60
+ 未额外配置的 CLI 与现有手动配置默认使用 fixture / shadow。请区分未启用自动策略、依据宿主配置来源证据进行判断的既有路径,与安装后用于选择默认值的策略。宿主内部补丁工作处于暂停状态,不是直接推荐的前提条件。
61
+
62
+ | MCP 工具 | 用途 |
63
+ |---|---|
64
+ | `get_routing_capabilities` | 免费查询候选、限制、分类方式与 Hook 状态 |
65
+ | `recommend_agent` | 根据任务摘要获取直接推荐 |
66
+ | `get_routing_precedence` | 解释调用的保留依据与未确认的配置来源 |
67
+ | `route_spawn_hook` | 根据已安装的策略选择目标调用的默认值,或仅传递推荐 |
68
+
69
+ ## 直接推荐
70
+
71
+ `recommend_agent` MCP 与 CLI 的 `recommend` 接收任务摘要并推荐执行配置,不会直接创建子代理。请将以下 JSON 作为 MCP 工具参数传递,或保存为文件并通过 CLI 的标准输入提供。
72
+
73
+ ```json
74
+ {
75
+ "request_id": "demo-codex-sort-001",
76
+ "client": "codex",
77
+ "task": {
78
+ "summary": "Sort the supplied numbers [3, 1, 2] into ascending order. No files or network are needed.",
79
+ "operation": "analysis",
80
+ "context_sufficient": true
81
+ }
82
+ }
83
+ ```
84
+
85
+ ```sh
86
+ ROUTER_PROVIDER=fixture aptly recommend < request.json
87
+ aptly capabilities
88
+ aptly config codex
89
+ aptly config claude
90
+ ```
91
+
92
+ fixture 无需密钥、网络或执行子代理,即可返回本地模拟结果。这不代表实际 Decisions 判断或质量测试结果。`config` 仅输出手动 MCP 注册片段,而 `setup` 会实际修改配置。使用实际 API 时,请先准备上述密钥、分类方式和私有账本。
93
+
94
+ `task.operation` 可为 `read_only`、`write`、`review` 或 `analysis`。`context_sufficient` 表示调用方已提供所需摘要,并非对宿主配置的验证。省略 `eligible_profile_ids` 时,会使用对应 client 当前启用的候选配置;指定该字段时,可在其中进一步限制候选。
95
+
96
+ 如果 `constraints` 中的 `model_pinned`、`effort_pinned`、`role_pinned`、`fork_inherits` 任意一项为 true,则保留原有选择。省略这些字段,表示该规划请求未声明保留条件,并不能据此确认实际宿主没有明确指定的设置;新请求不要使用 `provenance_verified`。
97
+
98
+ | status | 后续操作 |
99
+ |---|---|
100
+ | `recommended` | 审核 `profile`,在现有宿主中另行决定是否执行 |
101
+ | `keep_current` | 保留明确选择或暂缓推荐 |
102
+ | `needs_context` | 补充所需摘要 |
103
+ | `unavailable` | 检查预定义的 `reason` 代码;不要以新 ID 自动重新发起结果不明的付费请求 |
104
+
105
+ 直接推荐的 `application: advisory_only` 不代表已确认宿主配置、模型访问权限或执行批准。重新查询已完成的结果时,请保持相同的 ID、输入、策略和账本。`unknown` 表示结果不明确,不要无条件使用新 ID 重试。因补充上下文而改变输入的新请求,应使用不同的 ID。
106
+
107
+ ## 模型与环境变量
108
+
109
+ 默认候选共有六个配置。这些等级是 Aptly 预设的运行配置,并不表示两家提供商的模型能力相等。
110
+
111
+ | 等级 | Claude Code | Codex | 典型任务 |
112
+ |---|---|---|---|
113
+ | simple | `haiku` | `gpt-6-luna` / `max` | 提取、格式转换、小型机械性修改 |
114
+ | routine | `sonnet` | `gpt-6.1-terra` / `high` | 结合上下文的撰写或翻译、范围明确的实现 |
115
+ | deep | `opus` | `gpt-6.1-sol` / `medium` | 复合调试、设计判断、深入审查 |
116
+
117
+ MCP 的 `env` 值是字符串,因此候选数组也必须以 JSON 字符串传递。
118
+
119
+ ```json
120
+ {
121
+ "env": {
122
+ "APTLY_CLAUDE_MODELS": "[\"haiku\", \"sonnet\", \"opus\"]",
123
+ "APTLY_CODEX_MODELS": "[\"gpt-6-luna\", \"gpt-6.1-terra\", \"gpt-6.1-sol\"]"
124
+ }
125
+ }
126
+ ```
127
+
128
+ 未设置时使用上述默认值,`[]` 会禁用对应 client 的推荐。空字符串、重复项、不支持的模型或无效 JSON 都会报错。也支持别名 `CLAUDE_MODELS` 和 `CODEX_MODELS`,但同时设置同一提供商的主变量名与别名会报错。候选设置不会覆盖现有选择,也不代表已确认账户的模型访问权限。
129
+
130
+ ### 官方说明与缓存
131
+
132
+ Decisions 的选项会同时包含模型名称、Codex effort、官方特性和任务等级说明。可以使用附带说明启动,不会在每次推荐时获取文档。若要反映最新的官方 Markdown,请显式更新。请先准备一个归用户所有的私有目录,作为输出文件的父目录。
133
+
134
+ ```sh
135
+ mkdir -m 700 /absolute/private-aptly-state
136
+ aptly catalog refresh --output /absolute/private-aptly-state/model-info.json
137
+ export APTLY_MODEL_INFO_PATH=/absolute/private-aptly-state/model-info.json
138
+ ```
139
+
140
+ 更新仅读取固定的 [Claude 模型文档](https://code.claude.com/docs/en/model-config.md)和 [OpenAI 模型文档](https://learn.chatgpt.com/docs/models.md),不需要 API 密钥。只保存简要整理并规范化的模型信息;更新失败时,原有文件会保留。服务器启动时读取缓存;缓存超过 7 天或无效时,会回退到附带说明。更新后请重启 MCP。即使新文档中出现了模型,也不会自动增加候选或确认账户的访问能力。
141
+
142
+ ## 提供上下文
143
+
144
+ 在 Codex 将子代理 `message` 以密文传递给 Hook 的环境中,Aptly 不会读取或解密正文。此时只使用足够具体的明文 `task_name` 作为摘要,例如用 `sort_supplied_numbers_3_1_2_ascending_without_tools` 说明任务类型与范围。名称过短或含糊时保留原有模型。对于 Claude Code 或传递明文正文的调用,则使用所提供正文的摘要。
145
+
146
+ 通过 `get_routing_capabilities` 的 `automatic_hook.last_result`,可查看该 MCP 进程最后一次应用或保留的原因。`null` 表示尚无自动 Hook 处理记录。该诊断不会返回任务正文或个人配置值。
147
+
148
+ 直接推荐的摘要可以同时包含仓库、文件 URL,以及阅读文档后整理的任务范围、规模和约束。发送 URL 字符串与提供文档正文不同。目前 Aptly 的分类请求处理代码不会向仓库 URL 发起 GET 请求,也不会获取文档正文。所需的文档读取和摘要由调用方完成。
149
+
150
+ 目前自动 Hook 没有单独以明文传递 URL 的字段。不要假定仅将 URL 添加到会被加密的 `message` 中,就能将其传递给分类器。请区分两种路径:直接获取 MCP 推荐后,将推荐配置作为参数传递给宿主的原生调用;或通过自动 Hook 应用推荐。
151
+
152
+ ## 成本实测
153
+
154
+ 2026-11-05,以 [session-peer 的英文 README](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.md) 为正本,审阅了[韩语翻译](https://github.com/abruption/session-peer/blob/6e9efda7588e1df638748eeb7ad1b2707e0a3bf4/README.ko.md)。使用合计 17,964 字节的相同文档和相同指令,每次生成 6 条修改建议,未修改原始文件。
155
+
156
+ 仅提供任务名的自动 Hook 测试,3 次均以 `needs_context` 暂缓推荐。向 `recommend_agent` 添加仓库和文件 URL 的 3 次,以及同时添加 URL 和文档摘要的 3 次,均推荐了 Terra/high。下表是 URL+摘要条件下实际执行 Terra/high 的 3 次,与紧接在此前的 Sol/high 实测 3 次相比的每次平均值。
157
+
158
+ | Standard API 换算依据 | Sol/high | Terra/high + 分类费用 | 降幅 |
159
+ |---|---:|---:|---:|
160
+ | 计入实际缓存用量 | $0.03229 | $0.01354 | 58.05% |
161
+ | 将全部输入按非缓存换算 | $0.11254 | $0.05363 | 52.35% |
162
+
163
+ 这些数值将宿主记录的实测 token 用量按[官方 Standard API 单价](https://developers.openai.com/api/docs/pricing)换算为 USD,并非实际订阅账单或实际额度扣减。Terra 一侧包括每次 $0.0000756 的 [Decisions 分类费用](https://developers.openai.com/api/docs/guides/decisions)。比较范围是审阅子代理和分类,不包括文档收集、摘要准备或主代理调查的成本。
164
+
165
+ 测量路径为**显式 MCP 推荐 → 将推荐配置作为参数传递给宿主原生调用**。这不是对自动 Hook 的 URL 收集或传递功能的验证。基准组复用了紧接在此前的实测数据,每个条件的样本为 3 次。已确认各次执行读取了完整文档,并检查了原文引用的一致性和输出格式。这些检查不能证明结果质量相同或差异具有统计显著性,也不能保证其他任务会降低成本。
166
+
167
+ ## 诊断与开发
168
+
169
+ ```sh
170
+ aptly report --format both --output-dir reports
171
+ ```
172
+
173
+ report 会以相同 ID 生成私有的 Markdown 和 JSON 文件。请审核后手动共享;不会自动上传。附件中不要包含密钥、个人路径、环境值、任务正文或原始错误信息。这些文件不代表 API 认证成功,也不代表已确认宿主的全部配置。
174
+
175
+ 在源码检出目录中,请使用以下命令。请区分此处的执行路径与前面的已安装 CLI 示例。
176
+
177
+ ```sh
178
+ npm ci --ignore-scripts --no-audit --no-fund
179
+ npm run typecheck
180
+ npm run build
181
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.codex.json
182
+ ROUTER_PROVIDER=fixture node bin/aptly.ts recommend < examples/recommend.claude.json
183
+ npm test
184
+ npm run poc
185
+ npm run check:release
186
+ ```
187
+
188
+ 默认回归测试与 fixture smoke 测试无需付费 API 或实际子代理执行。发布检查会检查公开文件、个人信息模式和 npm 文件允许列表,不会发布或执行 Git push。账本用于复用已完成结果、防止重试 unknown 请求,以及限制调用次数、延迟和估算成本;它并非实际账单上限。
189
+
190
+ 设计、历史验证与开发记录保留在源码检出目录的其他文档中。本多语言指南用于说明安装和日常使用。历史研究资料中的主张或尚未实现的计划,不应据此视为当前功能。
@@ -0,0 +1,15 @@
1
+ {
2
+ "mcpServers": {
3
+ "aptly": {
4
+ "command": "aptly",
5
+ "args": [
6
+ "serve"
7
+ ],
8
+ "env": {
9
+ "ROUTER_PROVIDER": "fixture",
10
+ "APTLY_CLAUDE_MODELS": "[\"haiku\",\"sonnet\",\"opus\"]",
11
+ "APTLY_CODEX_MODELS": "[\"gpt-6-luna\",\"gpt-6.1-terra\",\"gpt-6.1-sol\"]"
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ [mcp_servers.aptly]
2
+ command = "aptly"
3
+ args = ["serve"]
4
+ env_vars = ["OPENAI_API_KEY", "ROUTER_PROVIDER", "ROUTER_LEDGER_PATH", "ROUTER_CONFIG_PATH", "APTLY_MODEL_INFO_PATH"]
5
+
6
+ [mcp_servers.aptly.env]
7
+ ROUTER_PROVIDER = "fixture"
8
+ APTLY_CLAUDE_MODELS = '["haiku","sonnet","opus"]'
9
+ APTLY_CODEX_MODELS = '["gpt-6-luna","gpt-6.1-terra","gpt-6.1-sol"]'
@@ -0,0 +1,9 @@
1
+ {
2
+ "request_id": "demo-claude-count-001",
3
+ "client": "claude",
4
+ "task": {
5
+ "summary": "Count how many times the word apple appears in this supplied list: apple, pear, apple. No files or network are needed.",
6
+ "operation": "analysis",
7
+ "context_sufficient": true
8
+ }
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "request_id": "demo-codex-sort-001",
3
+ "client": "codex",
4
+ "task": {
5
+ "summary": "Sort the supplied numbers [3, 1, 2] into ascending order. No files or network are needed.",
6
+ "operation": "analysis",
7
+ "context_sufficient": true
8
+ }
9
+ }