gpt-connector 0.1.0 → 0.3.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.
- package/CHANGELOG.md +17 -0
- package/README.md +160 -19
- package/dist/src/asset-discovery.d.ts +2 -0
- package/dist/src/asset-discovery.js +58 -12
- package/dist/src/asset-discovery.js.map +1 -1
- package/dist/src/attachment-files.d.ts +25 -0
- package/dist/src/attachment-files.js +272 -0
- package/dist/src/attachment-files.js.map +1 -0
- package/dist/src/browser-launcher.d.ts +57 -0
- package/dist/src/browser-launcher.js +494 -0
- package/dist/src/browser-launcher.js.map +1 -0
- package/dist/src/cdp.js +3 -3
- package/dist/src/cdp.js.map +1 -1
- package/dist/src/cli.js +170 -9
- package/dist/src/cli.js.map +1 -1
- package/dist/src/connector.d.ts +12 -1
- package/dist/src/connector.js +370 -12
- package/dist/src/connector.js.map +1 -1
- package/dist/src/consult-job-store.d.ts +37 -0
- package/dist/src/consult-job-store.js +464 -0
- package/dist/src/consult-job-store.js.map +1 -0
- package/dist/src/contract.d.ts +86 -0
- package/dist/src/contract.js +42 -0
- package/dist/src/contract.js.map +1 -1
- package/dist/src/errors.d.ts +2 -2
- package/dist/src/errors.js +15 -2
- package/dist/src/errors.js.map +1 -1
- package/dist/src/factory-diagnostics.d.ts +28 -0
- package/dist/src/factory-diagnostics.js +109 -0
- package/dist/src/factory-diagnostics.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp-server.d.ts +8 -3
- package/dist/src/mcp-server.js +71 -5
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp.js +1 -1
- package/dist/src/mcp.js.map +1 -1
- package/dist/src/page-bridge.d.ts +2 -2
- package/dist/src/page-bridge.js +333 -12
- package/dist/src/page-bridge.js.map +1 -1
- package/dist/src/runtime-error-store.d.ts +157 -0
- package/dist/src/runtime-error-store.js +327 -0
- package/dist/src/runtime-error-store.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +2 -0
- package/dist/src/version.js.map +1 -0
- package/docs/ai-installer-setup-contract.md +137 -0
- package/package.json +5 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 — 2026-07-14
|
|
4
|
+
|
|
5
|
+
- BugHub factory向けに `gpt-connector factory-diagnostics --json` を追加した。既存
|
|
6
|
+
`gpt-connector.diagnostics.v1` の `doctor` 契約は維持する。
|
|
7
|
+
- 明示的な canonical dotagents `collection.enabled: true` の時だけ動く、network I/O を
|
|
8
|
+
持たない product-owned `runtime-errors` local aggregate を追加した。
|
|
9
|
+
- runtime error の公開面は固定 code/template と SHA-256 fingerprint のみを使う。prompt、
|
|
10
|
+
応答、添付、識別子、credential、CDP dump、絶対 path、raw error は保存・出力しない。
|
|
11
|
+
- true headlessを使わず、cold startでは窓なしで専用profileのheadful Chromeを起動し、CDPで
|
|
12
|
+
ChatGPT targetを最初から最小化状態で作成・確認してからapp readyを待つ`gpt-connector browser start`
|
|
13
|
+
を追加した。既存endpointもapp probeより先に最小化する。現行macOS実測では最小化中も送受信を維持する。
|
|
14
|
+
- `gpt-connector browser show`で、正規専用profileの一意ChatGPT windowだけを明示的に表示へ戻せるようにした。認証要求時はstartが同じwindowを表示へ戻してから`AUTH_REQUIRED`を返す。
|
|
15
|
+
- window stateのCDP read-backを有界pollにし、非同期遷移直後の旧stateによるfalse failureを防いだ。
|
|
16
|
+
- cold startはhidden Chrome・background minimized targetから開始し、最小化確認後に正規PIDだけをunhideしてからprobeする。
|
|
17
|
+
- showはCDP stateのstale値に依存せず`Page.bringToFront`を送る。最終状態はWindowServerの正規PID/layer 0 window数で確認する。
|
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# GPT Connector
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/gpt-connector)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
3
6
|
Codex開発枠から、ログイン済みChatGPT公式Web runtimeの通常Chatを呼び出すローカルconnector。
|
|
4
7
|
|
|
5
8
|
ブラウザは認証・integrity・attestation・conversation lifecycleの実行環境として使う。composer、送信button、回答DOM、React fiberは操作・参照しない。
|
|
@@ -7,6 +10,8 @@ Codex開発枠から、ログイン済みChatGPT公式Web runtimeの通常Chat
|
|
|
7
10
|
> [!WARNING]
|
|
8
11
|
> consumer Chatの非公開Web runtimeとminified bundleに依存する実験的実装。OpenAIの公開・安定APIではない。bundle contractが変わった場合は`RUNTIME_DRIFT`で停止し、別方式へ自動fallbackしない。
|
|
9
12
|
|
|
13
|
+
現在版は[`gpt-connector@0.3.0`](https://www.npmjs.com/package/gpt-connector)。ソースと変更履歴は[GitHub repository](https://github.com/kitepon-rgb/gpt-connector)を正とする。
|
|
14
|
+
|
|
10
15
|
## 成立済み機能
|
|
11
16
|
|
|
12
17
|
- 通常Chatのone-shot送信と自動archive。
|
|
@@ -16,6 +21,12 @@ Codex開発枠から、ログイン済みChatGPT公式Web runtimeの通常Chat
|
|
|
16
21
|
- model/thinking effort明示選択。
|
|
17
22
|
- Work-only modelの除外。
|
|
18
23
|
- 非対応model/effortの送信前拒否。
|
|
24
|
+
- 全regular fileのChatGPT正規添付。known extensionは標準MIME、unknown extensionは`application/octet-stream`。
|
|
25
|
+
- workspaceRoot境界、glob、MIME、size、秘密file denylistの送信前検証。
|
|
26
|
+
- 256KiB CDP chunk転送とpage側SHA-256照合。
|
|
27
|
+
- server attachment metadata read-backとモデル読取確認。
|
|
28
|
+
- caller既知slugによるconsult冪等性、terminal result回収、owner-only durable job台帳。
|
|
29
|
+
- upload/conversationを作らないdry-run、既存diagnostics、factory diagnostics。
|
|
19
30
|
- CLIとstdio MCP adapter。
|
|
20
31
|
|
|
21
32
|
## 前提
|
|
@@ -23,9 +34,10 @@ Codex開発枠から、ログイン済みChatGPT公式Web runtimeの通常Chat
|
|
|
23
34
|
- macOS
|
|
24
35
|
- Google Chrome
|
|
25
36
|
- Node.js 26以上
|
|
26
|
-
- pnpm 11以上
|
|
27
37
|
- ChatGPTへログインできるaccount
|
|
28
38
|
|
|
39
|
+
sourceからbuildする場合だけpnpm 11以上も必要。
|
|
40
|
+
|
|
29
41
|
## npm global install
|
|
30
42
|
|
|
31
43
|
```bash
|
|
@@ -33,18 +45,33 @@ npm install --global gpt-connector
|
|
|
33
45
|
```
|
|
34
46
|
|
|
35
47
|
専用Chromeを起動する。通常ChromeとOracle profileは使用しない。
|
|
48
|
+
true headlessは使わず、cold startでは窓なしで専用profileのheadful Chromeを起動する。CDP browser endpointからChatGPT targetを最初から最小化状態で作成し、最小化を確認してからapp readyを待つ。既存endpointではapp probeより先に専用ChatGPT windowを最小化する。現行macOS実測では最小化中も送受信を維持する。
|
|
49
|
+
|
|
50
|
+
Chromeのhidden状態はflashを覆うcold準備中だけに使い、最小化確認後は正規PIDだけをunhideしてからprobeする。hiddenのまま運用せず、Oracleのhide fallbackでもない。
|
|
51
|
+
|
|
52
|
+
`browser start`が成功を返す時点では専用ChatGPT windowは最小化済みである。認証が必要になった場合だけwindowを表示へ戻す。手動でログイン/確認するには次を使う。
|
|
53
|
+
|
|
54
|
+
window stateのCDP read-backは遷移直後の旧stateを単発判定せず、有界時間内に期待stateへ収束したことを確認する。
|
|
55
|
+
|
|
56
|
+
ChromeのCDPはshow後も最小化状態を返すことがあるため、表示/非表示の最終判定は正規PIDのWindowServer layer 0 window数で行う。start成功時は0、show成功時は1件以上である。
|
|
57
|
+
実機では同時cold startが`started` 1件/`already_ready` 1件へ収束し、新規専用Chrome PIDで15秒・10ms監視中のlayer 0 on-screen最大値は0だった。`models`とchat(`ACCEPTED_NO_FLASH_OK`)の後も0を維持し、show→startは0→1→0を確認した。
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gpt-connector browser show
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Chrome更新時はrelease smokeとして`browser start`、`models`、最小化中の`chat`、必要時の`browser show`を確認する。
|
|
36
64
|
|
|
37
65
|
```bash
|
|
38
|
-
|
|
39
|
-
--remote-debugging-port=9223 \
|
|
40
|
-
--user-data-dir="$HOME/.gpt-connector/browser-profile" \
|
|
41
|
-
--no-first-run \
|
|
42
|
-
--no-default-browser-check \
|
|
43
|
-
https://chatgpt.com/
|
|
66
|
+
gpt-connector browser start
|
|
44
67
|
```
|
|
45
68
|
|
|
46
69
|
初回だけ、開いた専用ChromeでChatGPTへ手動ログインする。connectorはpassword、cookie、tokenを読み出さない。
|
|
47
70
|
|
|
71
|
+
### AI installer向けセットアップ
|
|
72
|
+
|
|
73
|
+
CodexなどのAIが導入する場合は、[AI installer向けセットアップ契約](docs/ai-installer-setup-contract.md)に従う。AIはinstall、専用Chrome起動、read-only診断、MCP設定を担当し、人間には専用ChromeでのChatGPTログインだけを依頼する。通常ChromeやOracleのprofile、認証情報は使用しない。
|
|
74
|
+
|
|
48
75
|
## source setup
|
|
49
76
|
|
|
50
77
|
```bash
|
|
@@ -71,7 +98,75 @@ gpt-connector chat \
|
|
|
71
98
|
--prompt 'Reply with exactly: OK'
|
|
72
99
|
```
|
|
73
100
|
|
|
74
|
-
CLI
|
|
101
|
+
CLIの`chat`はone-shot専用。`consult` jobはdurable台帳へ残るため、別processの`sessions`から回収できる。複数turnの会話sessionはMCP adapterを使う。
|
|
102
|
+
|
|
103
|
+
正規添付のdry-run:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
gpt-connector consult \
|
|
107
|
+
--endpoint http://127.0.0.1:9223 \
|
|
108
|
+
--workspace-root "$PWD" \
|
|
109
|
+
--file 'docs/*.md' \
|
|
110
|
+
--prompt '添付資料を監査してください' \
|
|
111
|
+
--slug review-001 \
|
|
112
|
+
--model gpt-5-6-thinking \
|
|
113
|
+
--effort extended \
|
|
114
|
+
--dry-run
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`--dry-run`を外すと、検証済みbytesをChatGPTへ正規添付して通常Chatへ送る。caller timeout後は同じconsultを作り直さず、次で回収する。
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
gpt-connector sessions --slug review-001
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
read-only診断:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
gpt-connector doctor
|
|
127
|
+
gpt-connector --version
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`doctor`は`gpt-connector.diagnostics.v1` JSONを返します。接続可能なら`overall: "ready"`、CDPや認証などが未準備なら`overall: "not_ready"`と安定`reasonCode`をstdoutへ返し、exit codeは非0です。診断はuploadや会話作成を行いません。
|
|
131
|
+
|
|
132
|
+
## BugHub factory 契約
|
|
133
|
+
|
|
134
|
+
既存の `doctor` と別に、factory consumer 用の versioned read-only JSON を提供します。
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
gpt-connector factory-diagnostics --json
|
|
138
|
+
gpt-connector runtime-errors diagnostics --json
|
|
139
|
+
gpt-connector runtime-errors snapshot --after-cursor 0 --limit 256 --json
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`factory-diagnostics` は package version、既存 diagnostics schema、overall、consult job の
|
|
143
|
+
state/job schema と migration、CDP、official origin、auth、runtime bridge、stdio MCP contractを
|
|
144
|
+
固定 check ID で返します。Chrome/CDP/auth が未準備なら `not_ready`、live connector を提供しない
|
|
145
|
+
host は `unsupported`、検査できない項目は `unverified` です。いずれも upload、conversation、archive、
|
|
146
|
+
job 作成を行いません。
|
|
147
|
+
|
|
148
|
+
`runtime-errors` は product-owned local aggregate であり、network I/O は実装しません。canonical
|
|
149
|
+
dotagents factory config(POSIX: `~/.config/dotagents/factory-reporter.json`、Windows native:
|
|
150
|
+
`%LOCALAPPDATA%\\dotagents\\factory-reporter\\config.json`)が厳密な JSON shape で
|
|
151
|
+
`collection.enabled: true` の場合だけ collection を開始します。設定なし・不正設定・
|
|
152
|
+
`reporting.enabled`・token/credentialの存在は collection を有効にしません。既定はOFFです。
|
|
153
|
+
|
|
154
|
+
公開操作はすべて `--json` 必須です。
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
gpt-connector runtime-errors snapshot --json
|
|
158
|
+
gpt-connector runtime-errors diagnostics --json
|
|
159
|
+
gpt-connector runtime-errors ack 12 --json
|
|
160
|
+
gpt-connector runtime-errors resolve <sha256-fingerprint> --json
|
|
161
|
+
gpt-connector runtime-errors reopen <sha256-fingerprint> --json
|
|
162
|
+
gpt-connector runtime-errors compact --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
recordは固定 code/template、SHA-256 fingerprint、count、first/last seen、status、cursorだけを持ちます。
|
|
166
|
+
ack cursor は単調で、compact は retention を過ぎた resolved かつ ack 済み recordだけを削除します。
|
|
167
|
+
stateは製品所有directoryへ owner-only atomic writeし、symlink・権限 drift・schema改ざんを拒否します。
|
|
168
|
+
prompt、assistant response、file名/内容/digest、conversation/session/job ID、cookie/token、CDP dump、
|
|
169
|
+
絶対path、生stack/stderrは入力・保存・出力できません。
|
|
75
170
|
|
|
76
171
|
## Codex MCP
|
|
77
172
|
|
|
@@ -84,10 +179,13 @@ startup_timeout_sec = 20
|
|
|
84
179
|
tool_timeout_sec = 240
|
|
85
180
|
enabled = true
|
|
86
181
|
required = false
|
|
87
|
-
enabled_tools = ["chatgpt_models", "chatgpt_chat", "chatgpt_close"]
|
|
182
|
+
enabled_tools = ["chatgpt_models", "chatgpt_chat", "chatgpt_close", "consult", "sessions", "diagnostics"]
|
|
88
183
|
|
|
89
184
|
[mcp_servers.gpt_connector.env]
|
|
90
185
|
GPT_CONNECTOR_CDP_ENDPOINT = "http://127.0.0.1:9223"
|
|
186
|
+
# 任意。未指定時は $XDG_STATE_HOME/gpt-connector、
|
|
187
|
+
# XDG_STATE_HOME未設定時は ~/.local/state/gpt-connector
|
|
188
|
+
GPT_CONNECTOR_STATE_DIR = "/absolute/product-owned/state/gpt-connector"
|
|
91
189
|
```
|
|
92
190
|
|
|
93
191
|
設定の正本はOpenAI公式の[Model Context Protocol設定](https://learn.chatgpt.com/docs/extend/mcp#configure-with-configtoml)。
|
|
@@ -96,14 +194,34 @@ GPT_CONNECTOR_CDP_ENDPOINT = "http://127.0.0.1:9223"
|
|
|
96
194
|
2. 専用Chromeを起動してログインする。
|
|
97
195
|
3. `.codex/config.toml`を置いたprojectで新しいCodex taskを開く。
|
|
98
196
|
4. `chatgpt_models`でlive catalogを確認する。
|
|
99
|
-
5.
|
|
100
|
-
6.
|
|
197
|
+
5. second opinionはcaller既知slugを付けて`consult`を呼ぶ。
|
|
198
|
+
6. timeout時は再送せず、同じslugを`sessions`へ渡す。
|
|
199
|
+
7. 既存互換の複数turnで`keepOpen=true`を使った場合は、最後に`chatgpt_close`を呼ぶ。
|
|
101
200
|
|
|
102
201
|
MCP tools:
|
|
103
202
|
|
|
104
203
|
- `chatgpt_models`: 通常Chat model/effort一覧。
|
|
105
204
|
- `chatgpt_chat`: 新規またはsession継続。既定`keepOpen=false`で応答後archive。
|
|
106
205
|
- `chatgpt_close`: sessionをarchiveしてhandleを破棄。deleteは行わない。
|
|
206
|
+
- `consult`: slug冪等化、任意の正規添付、model/effort、dry-runを持つsecond opinion入口。
|
|
207
|
+
- `sessions`: exact slug 1件の状態/terminal resultを返す。uploadや会話を作らず、connector未起動時は台帳を直接読む。
|
|
208
|
+
- `diagnostics`: 接続、bridge build、job/session/operation/upload buffer件数だけを返すread-only診断。
|
|
209
|
+
|
|
210
|
+
移行期間にCodex側のMCP server idを`oracle`へすれば、tool名は`oracle.consult`/`oracle.sessions`になる。別adapter packageやOracleへの自動fallbackは使わない。
|
|
211
|
+
|
|
212
|
+
## attachment contract
|
|
213
|
+
|
|
214
|
+
- `workspaceRoot`はabsolute directory、`files`はそこからのrelative pathまたはglob。
|
|
215
|
+
- spec順、glob内POSIX path順、realpath first occurrenceで決定的に解決する。
|
|
216
|
+
- absolute file path、`..`、root外symlink、directory、empty fileを拒否する。
|
|
217
|
+
- regular fileは形式を問わず元bytesのまま公式uploadへ渡す。一般的なtext、image、PDF、Office、archive、audio、videoには標準MIME、未知拡張子には`application/octet-stream`を使う。localで内容解析・変換は行わず、ChatGPTが解釈できる形式かは公式runtimeが判断する。
|
|
218
|
+
- 最大20 file、20MiB/file、64MiB total。
|
|
219
|
+
- `.env*`、key/certificate、credential/secret名など明白な秘密fileをoverrideなしで拒否する。
|
|
220
|
+
- ChatGPTへ渡すのはbytes、basename、MIMEだけ。ローカルabsolute pathはpage contextやtool resultへ渡さない。
|
|
221
|
+
- upload済みfileの削除手段は未成立。結果は`retention=unknown`、`cleanup=not_supported`と返し、archiveをfile cleanupとは表現しない。
|
|
222
|
+
- OpenAI公式は一般的なtext、spreadsheet、presentation、documentを対応対象として例示する一方、`.gdoc`は非対応としている。pass-through可能であることは、モデルが内容を解釈できる保証ではない。
|
|
223
|
+
|
|
224
|
+
詳細は[`docs/native-attachment-contract.md`](docs/native-attachment-contract.md)。
|
|
107
225
|
|
|
108
226
|
## model/effort contract
|
|
109
227
|
|
|
@@ -124,39 +242,62 @@ MCP tools:
|
|
|
124
242
|
- one-shotと`chatgpt_close`はserverの`is_archived=true`をread-backしてから成功を返す。
|
|
125
243
|
- delete機能はない。
|
|
126
244
|
|
|
245
|
+
`consult` jobは別契約:
|
|
246
|
+
|
|
247
|
+
- callerが`^[a-z0-9][a-z0-9._-]{2,63}$`のslugを事前指定する。
|
|
248
|
+
- 同slug/同fingerprintは既存snapshotを返し、再upload/再送しない。
|
|
249
|
+
- 同slugへ異なるinputは`JOB_CONFLICT`。
|
|
250
|
+
- stateは`queued | uploading | submitted | running | succeeded | failed`。
|
|
251
|
+
- terminal jobはowner-only JSONへatomic保存し、process再起動後も`sessions`で回収できる。
|
|
252
|
+
- 再起動前の非terminal jobは完了有無を断定せず`JOB_RECOVERY_UNAVAILABLE`へ固定し、自動再送しない。
|
|
253
|
+
|
|
127
254
|
## failure codes
|
|
128
255
|
|
|
256
|
+
- `INVALID_INPUT`
|
|
129
257
|
- `AUTH_REQUIRED`
|
|
130
258
|
- `CDP_UNAVAILABLE`
|
|
131
259
|
- `RUNTIME_DRIFT`
|
|
132
260
|
- `MODEL_NOT_AVAILABLE`
|
|
133
261
|
- `EFFORT_NOT_SUPPORTED`
|
|
262
|
+
- `FILE_NOT_FOUND`
|
|
263
|
+
- `FILE_OUTSIDE_ROOT`
|
|
264
|
+
- `SENSITIVE_FILE_BLOCKED`
|
|
265
|
+
- `FILE_TYPE_NOT_SUPPORTED`
|
|
266
|
+
- `FILE_EMPTY`
|
|
267
|
+
- `FILE_LIMIT_EXCEEDED`
|
|
268
|
+
- `UPLOAD_FAILED`
|
|
269
|
+
- `UPLOAD_TIMEOUT`
|
|
270
|
+
- `ATTACHMENT_READBACK_FAILED`
|
|
134
271
|
- `CHAT_FAILED`
|
|
135
272
|
- `STREAM_INCOMPLETE`
|
|
136
273
|
- `SESSION_NOT_FOUND`
|
|
137
274
|
- `SESSION_BUSY`
|
|
138
275
|
- `ARCHIVE_FAILED`
|
|
276
|
+
- `JOB_NOT_FOUND`
|
|
277
|
+
- `JOB_CONFLICT`
|
|
278
|
+
- `JOB_RECOVERY_UNAVAILABLE`
|
|
139
279
|
|
|
140
280
|
## 秘密情報とログ
|
|
141
281
|
|
|
142
282
|
- cookie、authorization、access/refresh token、integrity、attestation、conduit tokenを取得・保存しない。
|
|
143
283
|
- CDP生dumpを保存しない。
|
|
144
284
|
- server conversation IDをtool resultやlogへ出さない。
|
|
145
|
-
- prompt
|
|
285
|
+
- prompt、file本文、absolute pathをlogやjob台帳へ保存しない。
|
|
286
|
+
- terminal assistant responseはcaller timeout後の回収に必要なため、fingerprint/状態/結果とともにowner-only job台帳へ保存する。
|
|
287
|
+
- job台帳は製品所有state directoryに置き、他ツールの管理directoryやhookへ便乗しない。
|
|
146
288
|
- `.browser-profile/`、log、temporary dumpはgit管理外。
|
|
147
289
|
|
|
148
290
|
## architecture
|
|
149
291
|
|
|
150
292
|
```text
|
|
151
|
-
Codex ──stdio MCP──> GptConnector core ──raw CDP──> ChatGPT page main world
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
→ state getter
|
|
293
|
+
Codex ──stdio MCP──> resolver/job store ──> GptConnector core ──raw CDP──> ChatGPT page main world
|
|
294
|
+
│ │
|
|
295
|
+
└─ slug status ├─ official upload client
|
|
296
|
+
├─ builder/sender
|
|
297
|
+
└─ state/server read-back
|
|
157
298
|
```
|
|
158
299
|
|
|
159
|
-
runtime role
|
|
300
|
+
runtime roleは上限付きasset import graph、function source signature、object method shape、read-only catalog probeで一意検出する。候補が0件または複数なら実行しない。DOM selector、file input、React fiber、座標操作は本番経路に含まない。
|
|
160
301
|
|
|
161
302
|
## license
|
|
162
303
|
|
|
@@ -2,8 +2,10 @@ import type { CdpClient } from "./cdp.js";
|
|
|
2
2
|
export interface RuntimeAssets {
|
|
3
3
|
readonly coreUrl: string;
|
|
4
4
|
readonly conversationUrl: string;
|
|
5
|
+
readonly uploadUrl: string;
|
|
5
6
|
readonly coreFingerprint: string;
|
|
6
7
|
readonly conversationFingerprint: string;
|
|
8
|
+
readonly uploadFingerprint: string;
|
|
7
9
|
}
|
|
8
10
|
export declare function listLoadedAssetUrls(client: CdpClient): Promise<readonly string[]>;
|
|
9
11
|
export declare function discoverRuntimeAssets(urls: readonly string[], fetchImplementation?: typeof fetch): Promise<RuntimeAssets>;
|
|
@@ -12,6 +12,13 @@ const conversationMarkers = [
|
|
|
12
12
|
"selectedSkillIds",
|
|
13
13
|
"build_request_params.prompt_message",
|
|
14
14
|
];
|
|
15
|
+
const uploadMarkers = [
|
|
16
|
+
"process_upload_stream",
|
|
17
|
+
"attachLibraryFile",
|
|
18
|
+
"uploadFile:async",
|
|
19
|
+
];
|
|
20
|
+
const maxAssetCount = 800;
|
|
21
|
+
const assetBatchSize = 12;
|
|
15
22
|
function allowedAssetUrl(value) {
|
|
16
23
|
try {
|
|
17
24
|
const url = new URL(value);
|
|
@@ -26,6 +33,21 @@ function allowedAssetUrl(value) {
|
|
|
26
33
|
function fingerprint(source) {
|
|
27
34
|
return createHash("sha256").update(source).digest("hex").slice(0, 16);
|
|
28
35
|
}
|
|
36
|
+
function importedAssetUrls(baseUrl, source) {
|
|
37
|
+
const matches = source.matchAll(/(?:https:\/\/(?:chatgpt\.com|[a-z0-9.-]+\.oaistatic\.com))?\/(?:cdn\/assets|assets|_next\/static\/chunks)\/[a-zA-Z0-9_-]+\.js|(?:\.\.?\/)[a-zA-Z0-9_-]+\.js/gu);
|
|
38
|
+
const urls = [];
|
|
39
|
+
for (const match of matches) {
|
|
40
|
+
try {
|
|
41
|
+
const url = new URL(match[0], baseUrl).href;
|
|
42
|
+
if (allowedAssetUrl(url))
|
|
43
|
+
urls.push(url);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// 不正なimport-like文字列はasset候補にしない。
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [...new Set(urls)];
|
|
50
|
+
}
|
|
29
51
|
function findUnique(role, candidates, markers) {
|
|
30
52
|
const matches = candidates.filter(({ source }) => markers.every((marker) => source.includes(marker)));
|
|
31
53
|
if (matches.length !== 1) {
|
|
@@ -36,6 +58,10 @@ function findUnique(role, candidates, markers) {
|
|
|
36
58
|
export async function listLoadedAssetUrls(client) {
|
|
37
59
|
const expression = String.raw `(() => Array.from(new Set([
|
|
38
60
|
...Array.from(document.scripts, (element) => element.src),
|
|
61
|
+
...Array.from(document.scripts)
|
|
62
|
+
.filter((element) => !element.src && element.type === "module")
|
|
63
|
+
.flatMap((element) => element.textContent?.match(/\/(?:cdn\/assets|_next\/static\/chunks)\/[a-zA-Z0-9_-]+\.js/g) ?? [])
|
|
64
|
+
.map((path) => new URL(path, location.origin).href),
|
|
39
65
|
...Array.from(document.head.children)
|
|
40
66
|
.filter((element) => element.tagName === "LINK" && element.rel === "modulepreload")
|
|
41
67
|
.map((element) => element.href),
|
|
@@ -48,26 +74,46 @@ export async function listLoadedAssetUrls(client) {
|
|
|
48
74
|
return [...new Set(raw.filter(allowedAssetUrl))];
|
|
49
75
|
}
|
|
50
76
|
export async function discoverRuntimeAssets(urls, fetchImplementation = fetch) {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
77
|
+
const queue = [...new Set(urls.filter(allowedAssetUrl))];
|
|
78
|
+
const queued = new Set(queue);
|
|
79
|
+
const fetched = [];
|
|
80
|
+
while (queue.length > 0 && fetched.length < maxAssetCount) {
|
|
81
|
+
const remaining = maxAssetCount - fetched.length;
|
|
82
|
+
const batch = queue.splice(0, Math.min(assetBatchSize, remaining));
|
|
83
|
+
const candidates = await Promise.all(batch.map(async (url) => {
|
|
84
|
+
let response;
|
|
85
|
+
try {
|
|
86
|
+
response = await fetchImplementation(url);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
if (!response.ok)
|
|
92
|
+
return null;
|
|
93
|
+
return { url, source: await response.text() };
|
|
94
|
+
}));
|
|
95
|
+
for (const candidate of candidates) {
|
|
96
|
+
if (candidate === null)
|
|
97
|
+
continue;
|
|
98
|
+
fetched.push(candidate);
|
|
99
|
+
for (const importedUrl of importedAssetUrls(candidate.url, candidate.source)) {
|
|
100
|
+
if (queued.has(importedUrl))
|
|
101
|
+
continue;
|
|
102
|
+
queued.add(importedUrl);
|
|
103
|
+
queue.push(importedUrl);
|
|
104
|
+
}
|
|
55
105
|
}
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
if (!response.ok)
|
|
60
|
-
return null;
|
|
61
|
-
return { url, source: await response.text() };
|
|
62
|
-
}));
|
|
63
|
-
const fetched = candidates.filter((candidate) => candidate !== null);
|
|
106
|
+
}
|
|
64
107
|
const core = findUnique("core", fetched, coreMarkers);
|
|
65
108
|
const conversation = findUnique("conversation", fetched, conversationMarkers);
|
|
109
|
+
const upload = findUnique("upload", fetched, uploadMarkers);
|
|
66
110
|
return {
|
|
67
111
|
coreUrl: core.url,
|
|
68
112
|
conversationUrl: conversation.url,
|
|
113
|
+
uploadUrl: upload.url,
|
|
69
114
|
coreFingerprint: fingerprint(core.source),
|
|
70
115
|
conversationFingerprint: fingerprint(conversation.source),
|
|
116
|
+
uploadFingerprint: fingerprint(upload.source),
|
|
71
117
|
};
|
|
72
118
|
}
|
|
73
119
|
//# sourceMappingURL=asset-discovery.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-discovery.js","sourceRoot":"","sources":["../../src/asset-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"asset-discovery.js","sourceRoot":"","sources":["../../src/asset-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const attachmentLimits: {
|
|
2
|
+
readonly maxFiles: 20;
|
|
3
|
+
readonly maxFileBytes: number;
|
|
4
|
+
readonly maxTotalBytes: number;
|
|
5
|
+
};
|
|
6
|
+
export interface AttachmentFile {
|
|
7
|
+
readonly relativePath: string;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly bytes: number;
|
|
10
|
+
readonly mimeType: string;
|
|
11
|
+
readonly sha256: string;
|
|
12
|
+
}
|
|
13
|
+
export interface PreparedAttachmentFile extends AttachmentFile {
|
|
14
|
+
readonly content: Uint8Array;
|
|
15
|
+
}
|
|
16
|
+
export interface AttachmentFileResolution<TFile extends AttachmentFile = AttachmentFile> {
|
|
17
|
+
readonly files: readonly TFile[];
|
|
18
|
+
readonly totalBytes: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ResolveAttachmentFilesInput {
|
|
21
|
+
readonly workspaceRoot: string;
|
|
22
|
+
readonly specs: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function prepareAttachmentFiles(input: ResolveAttachmentFilesInput): Promise<AttachmentFileResolution<PreparedAttachmentFile>>;
|
|
25
|
+
export declare function resolveAttachmentFiles(input: ResolveAttachmentFilesInput): Promise<AttachmentFileResolution>;
|