ima2-gen 3.13.1 → 3.14.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/.env.example +10 -0
- package/CHANGELOG.md +14 -0
- package/README.md +15 -2
- package/bin/commands/capabilities.js +5 -3
- package/bin/commands/config.js +15 -4
- package/bin/commands/defaults.js +7 -5
- package/bin/commands/doctor.js +88 -39
- package/bin/commands/gen.js +21 -4
- package/bin/commands/models.js +2 -2
- package/bin/commands/ping.js +1 -1
- package/bin/commands/prompt.js +5 -3
- package/bin/commands/service.js +32 -4
- package/bin/commands/tools.js +19 -3
- package/bin/commands/upscale.js +18 -4
- package/bin/commands/video.js +37 -50
- package/bin/ima2.js +28 -9
- package/bin/lib/characterResolve.js +2 -1
- package/bin/lib/client.js +155 -20
- package/bin/lib/config-store.js +40 -7
- package/bin/lib/doctor-bundle.js +6 -2
- package/bin/lib/doctor-checks.js +13 -29
- package/bin/lib/doctor-media.js +3 -3
- package/bin/lib/doctor-providers.js +48 -35
- package/bin/lib/doctor-report.js +78 -0
- package/bin/lib/doctor-runtime.js +173 -0
- package/bin/lib/mcpJob.js +19 -7
- package/bin/lib/output.js +3 -0
- package/bin/lib/platform.js +12 -9
- package/bin/lib/recover-output.js +9 -2
- package/bin/lib/sse.js +9 -1
- package/bin/lib/videoMcp.js +16 -8
- package/config.js +41 -5
- package/docs/API.md +154 -16
- package/docs/CLI.md +65 -1
- package/docs/DOCKER.md +19 -4
- package/docs/DOCKER.zh-CN.md +11 -4
- package/docs/DOCKER.zh-TW.md +11 -4
- package/docs/FAQ.md +13 -0
- package/docs/NPX_QUICKSTART.md +6 -0
- package/docs/README.ja.md +15 -2
- package/docs/README.ko.md +15 -2
- package/docs/README.zh-CN.md +15 -2
- package/docs/README.zh-TW.md +15 -2
- package/docs/migration/runtime-test-inventory.md +79 -8
- package/lib/agyArtifact.js +82 -0
- package/lib/agyArtifactRead.js +249 -0
- package/lib/agyImageAdapter.js +2 -329
- package/lib/agyProcess.js +122 -0
- package/lib/apiRequestBudget.js +48 -0
- package/lib/assetLifecycle.js +42 -9
- package/lib/canvasVersionStore.js +46 -14
- package/lib/capabilities.js +7 -1
- package/lib/configKeys.js +2 -0
- package/lib/errors/providerMap.js +26 -0
- package/lib/eventBus.js +10 -6
- package/lib/eventsPolicy.js +9 -0
- package/lib/geminiApiImageAdapter.js +1 -214
- package/lib/generatePipeline.js +39 -165
- package/lib/generatedMediaAccess.js +74 -0
- package/lib/generationErrors.js +3 -22
- package/lib/grokImageAdapter.js +2 -353
- package/lib/grokImageCore.js +1 -57
- package/lib/grokImageDownload.js +159 -0
- package/lib/grokImageDownloadPolicy.js +124 -0
- package/lib/grokImagePlanner.js +301 -0
- package/lib/grokMultimodeAdapter.js +1 -75
- package/lib/grokVideoDownload.js +137 -34
- package/lib/inflight.js +112 -112
- package/lib/jobs/terminalStore.js +45 -0
- package/lib/lanSessionStore.js +131 -0
- package/lib/localAccessPolicy.js +180 -0
- package/lib/localLanAccess.js +281 -0
- package/lib/logger.js +22 -13
- package/lib/mcp/downloadMediaResult.js +72 -78
- package/lib/multimodePipeline.js +39 -126
- package/lib/nodeGeneration.js +44 -101
- package/lib/nodeStore.js +25 -11
- package/lib/nodeValidation.js +5 -1
- package/lib/pinnedHttpGet.js +174 -0
- package/lib/promptImport/githubFolder.js +32 -18
- package/lib/promptImport/githubSource.js +14 -10
- package/lib/promptImport/parsePromptCandidates.js +32 -2
- package/lib/providers/adapters/agyOperations.js +179 -0
- package/lib/providers/adapters/comfy.js +1 -0
- package/lib/providers/adapters/geminiOperations.js +214 -0
- package/lib/providers/adapters/googleExecution.js +97 -0
- package/lib/providers/adapters/grokExecution.js +137 -0
- package/lib/providers/adapters/grokMultimodeOperations.js +83 -0
- package/lib/providers/adapters/grokOperations.js +63 -0
- package/lib/providers/adapters/openaiExecution.js +118 -0
- package/lib/providers/adapters/openaiOperations.js +201 -0
- package/lib/providers/adapters/openaiTypes.js +1 -0
- package/lib/providers/derive.js +4 -0
- package/lib/providers/deriveCore.js +2 -7
- package/lib/providers/execution/admission.js +25 -0
- package/lib/providers/execution/index.js +34 -0
- package/lib/providers/execution/legacy.js +17 -0
- package/lib/providers/execution/legacyClassic.js +66 -0
- package/lib/providers/execution/legacyEdit.js +30 -0
- package/lib/providers/execution/legacyMultimode.js +34 -0
- package/lib/providers/execution/legacyNode.js +41 -0
- package/lib/providers/execution/types.js +1 -0
- package/lib/providers/registry.js +19 -14
- package/lib/providers/surfaceSupport.js +22 -0
- package/lib/responsesImageAdapter.js +1 -389
- package/lib/responsesTransport.js +190 -0
- package/lib/spriteJobEvents.js +20 -2
- package/lib/ssePublish.js +5 -4
- package/lib/videoExtendI2vOperation.js +76 -0
- package/package.json +5 -2
- package/routes/edit.js +31 -123
- package/routes/events.js +140 -63
- package/routes/mcpMedia.js +10 -2
- package/routes/models.js +28 -25
- package/routes/videoExtended.js +9 -68
- package/server.js +24 -46
- package/ui/dist/.vite/manifest.json +90 -63
- package/ui/dist/assets/{AgentWorkspace-PbBytTeV.js → AgentWorkspace-CL3MLv3l.js} +2 -2
- package/ui/dist/assets/App-B9cEM6dJ.js +9 -0
- package/ui/dist/assets/AssetGenWorkspace-swWPvXrx.js +2 -0
- package/ui/dist/assets/AssetsWorkspace-CRVeYU2F.js +1 -0
- package/ui/dist/assets/{CardNewsWorkspace-BS3jKOja.js → CardNewsWorkspace-BAOxWLKf.js} +2 -2
- package/ui/dist/assets/GenerationRequestLogPanel-DZtYZm-D.js +1 -0
- package/ui/dist/assets/HomeWorkspace-BeZ1s0Jm.js +1 -0
- package/ui/dist/assets/KeyingPanel-ZyBSXioh.js +1 -0
- package/ui/dist/assets/NodeCanvas-BvvcCErf.js +7 -0
- package/ui/dist/assets/{PromptBuilderPanel-D97A4pwB.js → PromptBuilderPanel-DBycmShA.js} +2 -2
- package/ui/dist/assets/PromptImportDialog-ChvMv7ek.js +2 -0
- package/ui/dist/assets/PromptImportDiscoverySection-60py7whH.js +1 -0
- package/ui/dist/assets/PromptImportFolderSection-CCRh_-_7.js +1 -0
- package/ui/dist/assets/PromptLibraryPanel-BFWQO8OT.js +2 -0
- package/ui/dist/assets/SettingsWorkspace-B5Ghsgdj.js +1 -0
- package/ui/dist/assets/SpriteRecipeWorkspace-DRWdkmwU.js +1 -0
- package/ui/dist/assets/index-7ngEOVxt.js +5 -0
- package/ui/dist/assets/index-B5jy7ePg.css +1 -0
- package/ui/dist/assets/index-gxh_02DQ.js +22 -0
- package/ui/dist/assets/{pptxgen.es-D4pedbwM.js → pptxgen.es-OUNhQLEV.js} +1 -1
- package/ui/dist/assets/promptBuilderStore-BTUUzbBT.js +1 -0
- package/ui/dist/assets/useAgentDialogFocus-DSc2qY8p.js +1 -0
- package/ui/dist/index.html +3 -2
- package/ui/dist/assets/AssetGenWorkspace-B-TGlvVb.js +0 -2
- package/ui/dist/assets/AssetsWorkspace-LnGaW151.js +0 -1
- package/ui/dist/assets/GenerationRequestLogPanel-DuDWD_ic.js +0 -1
- package/ui/dist/assets/HomeWorkspace-DVP7UG6O.js +0 -1
- package/ui/dist/assets/KeyingPanel-5bRUFQaq.js +0 -1
- package/ui/dist/assets/NodeCanvas-BBEpERTb.js +0 -7
- package/ui/dist/assets/PromptImportDialog-C89MN5JY.js +0 -2
- package/ui/dist/assets/PromptImportDiscoverySection-BgRfDOs2.js +0 -1
- package/ui/dist/assets/PromptImportFolderSection-zTMyriT1.js +0 -1
- package/ui/dist/assets/PromptLibraryPanel-BD96qZu_.js +0 -2
- package/ui/dist/assets/SettingsWorkspace-BAOk3X_8.js +0 -1
- package/ui/dist/assets/SpriteRecipeWorkspace-ClIM5QRo.js +0 -1
- package/ui/dist/assets/index-0fpfY8vu.css +0 -1
- package/ui/dist/assets/index-BFciPGTn.js +0 -5
- package/ui/dist/assets/index-BbykeXR9.js +0 -30
- package/ui/dist/assets/promptBuilderStore-Do7M8g7J.js +0 -1
- package/ui/dist/assets/useAgentDialogFocus-B6-QgEVI.js +0 -1
package/docs/DOCKER.zh-CN.md
CHANGED
|
@@ -9,7 +9,7 @@ ima2-gen运送多级`Dockerfile`(问题#114)。该图像构建了
|
|
|
9
9
|
docker build -t ima2-gen .
|
|
10
10
|
docker run -d --name ima2 \
|
|
11
11
|
-p 3333:3333 \
|
|
12
|
-
-e IMA2_LAN_TOKEN
|
|
12
|
+
-e IMA2_LAN_TOKEN \
|
|
13
13
|
-v ima2-data:/data \
|
|
14
14
|
ima2-gen
|
|
15
15
|
```
|
|
@@ -17,11 +17,18 @@ docker run -d --name ima2 \
|
|
|
17
17
|
或者使用 compose:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
docker compose up -d
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
`
|
|
23
|
+
请先在环境中设置自己生成的强随机 `IMA2_LAN_TOKEN`,不要使用示例令牌。
|
|
24
|
+
然后打开 `http://localhost:3333/`,在工作室登录表单中输入令牌。
|
|
25
|
+
浏览器使用 HttpOnly 会话访问 API、图片、视频和 SSE;令牌不保存在浏览器存储中。
|
|
26
|
+
|
|
27
|
+
更改发布端口或使用代理时,设置 `IMA2_PUBLIC_ORIGINS` JSON 数组,
|
|
28
|
+
例如 `["http://localhost:8080"]`。TLS 代理必须保留 Host/Origin 并转发 Set-Cookie。
|
|
29
|
+
HTTP 不加密凭据,仅适用于可信网络;不可信网络请使用 TLS/VPN。
|
|
30
|
+
生成文件现需授权且不缓存,但旧缓存和已下载的副本无法撤回。
|
|
31
|
+
重启会使会话失效,不会删除文件。详见 [访问协议](API.md#local-and-lan-access) 和 [CLI 认证](CLI.md#lan-server-authentication)。
|
|
25
32
|
|
|
26
33
|
## 为什么`IMA2_LAN_TOKEN`是必须的
|
|
27
34
|
|
package/docs/DOCKER.zh-TW.md
CHANGED
|
@@ -9,7 +9,7 @@ ima2-gen運送多級`Dockerfile`(問題#114)。該圖像建構了
|
|
|
9
9
|
docker build -t ima2-gen .
|
|
10
10
|
docker run -d --name ima2 \
|
|
11
11
|
-p 3333:3333 \
|
|
12
|
-
-e IMA2_LAN_TOKEN
|
|
12
|
+
-e IMA2_LAN_TOKEN \
|
|
13
13
|
-v ima2-data:/data \
|
|
14
14
|
ima2-gen
|
|
15
15
|
```
|
|
@@ -17,11 +17,18 @@ docker run -d --name ima2 \
|
|
|
17
17
|
或使用 compose:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
docker compose up -d
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
`
|
|
23
|
+
請先在環境中設定自行產生的強隨機 `IMA2_LAN_TOKEN`,不要使用範例權杖。
|
|
24
|
+
然後開啟 `http://localhost:3333/`,在工作室登入表單輸入權杖。
|
|
25
|
+
瀏覽器使用 HttpOnly 工作階段存取 API、圖片、影片與 SSE;權杖不會存入瀏覽器儲存空間。
|
|
26
|
+
|
|
27
|
+
變更發布連接埠或使用代理時,設定 `IMA2_PUBLIC_ORIGINS` JSON 陣列,
|
|
28
|
+
例如 `["http://localhost:8080"]`。TLS 代理須保留 Host/Origin 並轉送 Set-Cookie。
|
|
29
|
+
HTTP 不會加密憑證,僅適用可信網路;不可信網路請使用 TLS/VPN。
|
|
30
|
+
生成檔案現在需要授權且不快取,但無法撤回舊快取或已下載的副本。
|
|
31
|
+
重新啟動會使工作階段失效,不會刪除檔案。詳見 [存取協定](API.md#local-and-lan-access) 與 [CLI 認證](CLI.md#lan-server-authentication)。
|
|
25
32
|
|
|
26
33
|
## 為什麼`IMA2_LAN_TOKEN`是必須的
|
|
27
34
|
|
package/docs/FAQ.md
CHANGED
|
@@ -71,6 +71,19 @@ again.
|
|
|
71
71
|
|
|
72
72
|
## Authentication and providers
|
|
73
73
|
|
|
74
|
+
### Why does LAN access now show a studio sign-in page or return 401 for media?
|
|
75
|
+
|
|
76
|
+
LAN APIs and generated images/videos now share an authenticated session. Open the
|
|
77
|
+
studio and enter its configured LAN token; CLI users set `IMA2_LAN_TOKEN` and an
|
|
78
|
+
explicit `--server` / `IMA2_SERVER`. This is separate from provider login. Sessions
|
|
79
|
+
expire after eight hours or server restart. Reconnect does not replay generation,
|
|
80
|
+
and sign-out does not cancel accepted work. No generated files are deleted.
|
|
81
|
+
|
|
82
|
+
If a Docker port or proxy address differs, configure its exact
|
|
83
|
+
`IMA2_PUBLIC_ORIGINS` value. HTTP requires a trusted network; use TLS/VPN otherwise.
|
|
84
|
+
Old downloaded/cached copies cannot be revoked. See the [access contract](API.md#local-and-lan-access)
|
|
85
|
+
and [CLI setup](CLI.md#lan-server-authentication).
|
|
86
|
+
|
|
74
87
|
### Do I need an OpenAI API key?
|
|
75
88
|
|
|
76
89
|
No for the default generation path. The normal path uses your local Codex/ChatGPT OAuth session.
|
package/docs/NPX_QUICKSTART.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# npx Quickstart
|
|
2
2
|
|
|
3
|
+
The package engine requirement applies to npx too; source `.ts` files require the normal build before emitted `.js` files are run.
|
|
4
|
+
|
|
3
5
|
> The recommended install method is `npm install -g ima2-gen`. This page covers
|
|
4
6
|
> the alternative `npx` workflow for one-shot usage without a global install.
|
|
5
7
|
|
|
@@ -11,6 +13,10 @@ npx ima2-gen serve
|
|
|
11
13
|
|
|
12
14
|
Then open `http://localhost:3333`.
|
|
13
15
|
|
|
16
|
+
To check the installed package without starting a server or reading provider
|
|
17
|
+
credentials, run `npx ima2-gen doctor --installation --json`. A failed local
|
|
18
|
+
prerequisite exits1; missing provider credentials are not installation failures.
|
|
19
|
+
|
|
14
20
|
If ChatGPT OAuth is not logged in yet:
|
|
15
21
|
|
|
16
22
|
```bash
|
package/docs/README.ja.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# ima2-gen
|
|
2
2
|
|
|
3
|
+
<!-- runtime-install:generated:start -->
|
|
4
|
+
| Contract | Value |
|
|
5
|
+
|---|---|
|
|
6
|
+
| Node engine | `>=22` |
|
|
7
|
+
| npm toolchain | `npm@11.18.0` |
|
|
8
|
+
| Release Node | `24.17.0` |
|
|
9
|
+
| CLI entry | `bin/ima2.js` |
|
|
10
|
+
| OpenAI SDK | `^7.4.0` |
|
|
11
|
+
| Express | `^5.1.0` |
|
|
12
|
+
<!-- runtime-install:generated:end -->
|
|
13
|
+
|
|
14
|
+
インストーラーはパッケージメタデータから Node.js の最低バージョンを読み、サーバー起動前にオフライン検査を行います。
|
|
15
|
+
|
|
3
16
|
[](https://www.npmjs.com/package/ima2-gen)
|
|
4
17
|
[](https://nodejs.org/)
|
|
5
18
|
[](../LICENSE)
|
|
@@ -54,7 +67,7 @@ irm https://lidge-jun.github.io/ima2-gen/install-windows.ps1 | iex
|
|
|
54
67
|
curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
55
68
|
```
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
各スクリプトは対応する Node バージョンを確認し、必要に応じて nvm/fnm/brew/winget で Node LTS を入れます。npm のインストールは一度だけ試し、`ima2 doctor --installation --json` が成功してからサーバーを起動します。プロセスの強制終了やグローバルロックの削除は行いません。
|
|
58
71
|
|
|
59
72
|
### セットアップ
|
|
60
73
|
|
|
@@ -75,7 +88,7 @@ curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
|
75
88
|
npm install -g ima2-gen@latest
|
|
76
89
|
```
|
|
77
90
|
|
|
78
|
-
Ctrl+C は DB
|
|
91
|
+
Ctrl+C は DB クローズ、子プロセス停止、ファイルロック解放まで行うクリーンシャットダウンです。インストールに失敗した場合は表示された npm 権限を確認するか、対象の `ima2` プロセスを手動で停止してください。インストーラーは無関係なプロセスやグローバルロックを操作しません。
|
|
79
92
|
|
|
80
93
|
## できること
|
|
81
94
|
|
package/docs/README.ko.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# ima2-gen
|
|
2
2
|
|
|
3
|
+
<!-- runtime-install:generated:start -->
|
|
4
|
+
| Contract | Value |
|
|
5
|
+
|---|---|
|
|
6
|
+
| Node engine | `>=22` |
|
|
7
|
+
| npm toolchain | `npm@11.18.0` |
|
|
8
|
+
| Release Node | `24.17.0` |
|
|
9
|
+
| CLI entry | `bin/ima2.js` |
|
|
10
|
+
| OpenAI SDK | `^7.4.0` |
|
|
11
|
+
| Express | `^5.1.0` |
|
|
12
|
+
<!-- runtime-install:generated:end -->
|
|
13
|
+
|
|
14
|
+
설치 프로그램은 패키지 메타데이터에서 Node.js 최소 버전을 읽고 서버 시작 전에 오프라인 설치 검사를 수행합니다.
|
|
15
|
+
|
|
3
16
|
[](https://www.npmjs.com/package/ima2-gen)
|
|
4
17
|
[](https://nodejs.org/)
|
|
5
18
|
[](../LICENSE)
|
|
@@ -62,7 +75,7 @@ irm https://lidge-jun.github.io/ima2-gen/install-windows.ps1 | iex
|
|
|
62
75
|
curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
63
76
|
```
|
|
64
77
|
|
|
65
|
-
각
|
|
78
|
+
각 스크립트는 지원하는 Node 버전을 확인하고, 필요하면 nvm/fnm/brew/winget으로 Node LTS를 설치합니다. npm 설치는 한 번만 시도하며, `ima2 doctor --installation --json`을 통과해야 서버를 시작합니다. 다른 프로세스를 종료하거나 전역 잠금 파일을 지우지는 않습니다.
|
|
66
79
|
|
|
67
80
|
### 업데이트
|
|
68
81
|
|
|
@@ -74,7 +87,7 @@ npm install -g ima2-gen@latest
|
|
|
74
87
|
|
|
75
88
|
npm 12라면 업데이트 명령에도 `--allow-scripts=ima2-gen,better-sqlite3,sharp`를 붙이세요. 원클릭 설치 스크립트는 npm 버전을 감지해 자동으로 처리합니다.
|
|
76
89
|
|
|
77
|
-
|
|
90
|
+
Ctrl+C로 DB, 소켓, 자식 프로세스를 정리할 수 있습니다. Windows에서 `EBUSY`가 나면 실행 중인 해당 ima2 서버를 직접 종료한 뒤 다시 설치하세요. 설치기는 프로세스를 임의로 종료하거나 관리자 권한으로 재시도하지 않습니다.
|
|
78
91
|
|
|
79
92
|
## 최근 주요 변경
|
|
80
93
|
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# ima2-gen
|
|
2
2
|
|
|
3
|
+
<!-- runtime-install:generated:start -->
|
|
4
|
+
| Contract | Value |
|
|
5
|
+
|---|---|
|
|
6
|
+
| Node engine | `>=22` |
|
|
7
|
+
| npm toolchain | `npm@11.18.0` |
|
|
8
|
+
| Release Node | `24.17.0` |
|
|
9
|
+
| CLI entry | `bin/ima2.js` |
|
|
10
|
+
| OpenAI SDK | `^7.4.0` |
|
|
11
|
+
| Express | `^5.1.0` |
|
|
12
|
+
<!-- runtime-install:generated:end -->
|
|
13
|
+
|
|
14
|
+
安装程序从包元数据读取 Node.js 最低版本,并在启动服务器前执行离线安装检查。
|
|
15
|
+
|
|
3
16
|
<p align="center">
|
|
4
17
|
<img src="../assets/logo.png" alt="ima2-gen logo" width="240">
|
|
5
18
|
</p>
|
|
@@ -75,7 +88,7 @@ irm https://lidge-jun.github.io/ima2-gen/install-windows.ps1 | iex
|
|
|
75
88
|
curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
76
89
|
```
|
|
77
90
|
|
|
78
|
-
|
|
91
|
+
每个脚本都会检查支持的 Node 版本,必要时使用 nvm/fnm/brew/winget 安装 Node LTS。npm 安装只尝试一次,`ima2 doctor --installation --json` 通过后才启动服务器。脚本不会终止其他进程或删除全局锁文件。
|
|
79
92
|
|
|
80
93
|
### 设置
|
|
81
94
|
|
|
@@ -96,7 +109,7 @@ curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
|
96
109
|
npm install -g ima2-gen@latest
|
|
97
110
|
```
|
|
98
111
|
|
|
99
|
-
Ctrl+C
|
|
112
|
+
Ctrl+C 会关闭数据库、停止子进程并释放文件锁。如果 Windows 报告 `EBUSY`,请先手动停止对应的 ima2 服务再重试安装。安装器不会自动终止进程或提升权限。
|
|
100
113
|
|
|
101
114
|
## 它的作用
|
|
102
115
|
|
package/docs/README.zh-TW.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# ima2-gen
|
|
2
2
|
|
|
3
|
+
<!-- runtime-install:generated:start -->
|
|
4
|
+
| Contract | Value |
|
|
5
|
+
|---|---|
|
|
6
|
+
| Node engine | `>=22` |
|
|
7
|
+
| npm toolchain | `npm@11.18.0` |
|
|
8
|
+
| Release Node | `24.17.0` |
|
|
9
|
+
| CLI entry | `bin/ima2.js` |
|
|
10
|
+
| OpenAI SDK | `^7.4.0` |
|
|
11
|
+
| Express | `^5.1.0` |
|
|
12
|
+
<!-- runtime-install:generated:end -->
|
|
13
|
+
|
|
14
|
+
安裝程式從套件中繼資料讀取 Node.js 最低版本,並在啟動伺服器前執行離線安裝檢查。
|
|
15
|
+
|
|
3
16
|
<p align="center">
|
|
4
17
|
<img src="../assets/logo.png" alt="ima2-gen logo" width="240">
|
|
5
18
|
</p>
|
|
@@ -75,7 +88,7 @@ irm https://lidge-jun.github.io/ima2-gen/install-windows.ps1 | iex
|
|
|
75
88
|
curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
76
89
|
```
|
|
77
90
|
|
|
78
|
-
|
|
91
|
+
每個腳本都會檢查支援的 Node 版本,必要時使用 nvm、fnm、Homebrew 或 winget 安裝 Node LTS。npm 安裝只嘗試一次,通過 `ima2 doctor --installation --json` 後才啟動伺服器。腳本不會終止其他程序或刪除全域鎖定檔案。
|
|
79
92
|
|
|
80
93
|
### 設定
|
|
81
94
|
|
|
@@ -96,7 +109,7 @@ curl -fsSL https://lidge-jun.github.io/ima2-gen/install-linux.sh | bash
|
|
|
96
109
|
npm install -g ima2-gen@latest
|
|
97
110
|
```
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
按下 Ctrl+C 會關閉資料庫、停止子程序並釋放檔案鎖定。如果 Windows 顯示 `EBUSY`,請先手動停止對應的 ima2 服務,再重新安裝。安裝器不會自動終止程序或提高權限。
|
|
100
113
|
|
|
101
114
|
## 功能總覽
|
|
102
115
|
|
|
@@ -4,7 +4,7 @@ Generated by `npm run test:inventory` (script: `scripts/classify-tests.mjs`).
|
|
|
4
4
|
|
|
5
5
|
_Tests considered "runtime-importing" if they import from `../lib/`, `../routes/`, `../bin/`, `../server`, or `../config`._
|
|
6
6
|
|
|
7
|
-
Total:
|
|
7
|
+
Total: 487 (runtime: 224, contract: 263)
|
|
8
8
|
|
|
9
9
|
## Runtime-importing tests
|
|
10
10
|
- `tests/agent-image-reference-contract.test.ts`
|
|
@@ -19,13 +19,18 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
19
19
|
- `tests/agent-queue-store-contract.test.ts`
|
|
20
20
|
- `tests/agent-video-intent.test.ts`
|
|
21
21
|
- `tests/agent-video-reference-contract.test.ts`
|
|
22
|
+
- `tests/agy-artifact-confinement.test.ts`
|
|
22
23
|
- `tests/agy-artifact-fallback.test.ts`
|
|
23
24
|
- `tests/agy-cli.test.ts`
|
|
25
|
+
- `tests/agy-execution-cleanup.test.ts`
|
|
26
|
+
- `tests/agy-execution-process.test.ts`
|
|
24
27
|
- `tests/api-cache-policy.test.ts`
|
|
25
28
|
- `tests/api-provider-parity.test.ts`
|
|
29
|
+
- `tests/api-request-budget.test.ts`
|
|
26
30
|
- `tests/asset-character-bindings.test.ts`
|
|
27
31
|
- `tests/asset-derived-vector-contract.test.ts`
|
|
28
32
|
- `tests/asset-derived.test.ts`
|
|
33
|
+
- `tests/asset-lifecycle-path.test.ts`
|
|
29
34
|
- `tests/asset-ref-contract.test.ts`
|
|
30
35
|
- `tests/assets-routes-contract.test.ts`
|
|
31
36
|
- `tests/assets-store-contract.test.ts`
|
|
@@ -34,12 +39,14 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
34
39
|
- `tests/backend-input-lan-hardening.test.ts`
|
|
35
40
|
- `tests/background-presets.test.ts`
|
|
36
41
|
- `tests/billing-source.test.ts`
|
|
42
|
+
- `tests/canvas-version-normalization.test.ts`
|
|
37
43
|
- `tests/capabilities-lane-contract.test.ts`
|
|
38
44
|
- `tests/capabilities-video-modes-contract.test.ts`
|
|
39
45
|
- `tests/card-news-contract.test.ts`
|
|
40
46
|
- `tests/card-news-template.test.ts`
|
|
41
47
|
- `tests/classic-generate-async.test.ts`
|
|
42
48
|
- `tests/cli-error-hints.test.ts`
|
|
49
|
+
- `tests/cli-lan-auth.test.ts`
|
|
43
50
|
- `tests/cli-lib.test.ts`
|
|
44
51
|
- `tests/cli-model-resolver.test.ts`
|
|
45
52
|
- `tests/cli-models-command-contract.test.ts`
|
|
@@ -54,22 +61,29 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
54
61
|
- `tests/contracts-catalog.test.ts`
|
|
55
62
|
- `tests/contracts-discovery.test.ts`
|
|
56
63
|
- `tests/doctor-provider-contract.test.ts`
|
|
64
|
+
- `tests/doctor-report.test.ts`
|
|
65
|
+
- `tests/doctor-runtime.test.ts`
|
|
57
66
|
- `tests/element-compiler.test.ts`
|
|
58
67
|
- `tests/element-metadata.test.ts`
|
|
59
68
|
- `tests/error-class-coverage.test.ts`
|
|
60
69
|
- `tests/error-classify.test.ts`
|
|
61
70
|
- `tests/error-envelope-contract.test.ts`
|
|
62
71
|
- `tests/event-bus.test.ts`
|
|
72
|
+
- `tests/events-backpressure.test.ts`
|
|
63
73
|
- `tests/events-channel-contract.test.ts`
|
|
64
74
|
- `tests/filename.test.ts`
|
|
65
|
-
- `tests/gemini-api-wire-contract.test.ts`
|
|
66
75
|
- `tests/generate-route-validation-error.test.ts`
|
|
67
76
|
- `tests/generated-static-privacy.test.ts`
|
|
68
77
|
- `tests/generation-errors.test.ts`
|
|
69
78
|
- `tests/generation-request-log.test.ts`
|
|
79
|
+
- `tests/google-execution-parity.test.ts`
|
|
70
80
|
- `tests/gpt56-rollout-contract.test.ts`
|
|
71
81
|
- `tests/grok-advertise-liveness-contract.test.ts`
|
|
72
82
|
- `tests/grok-command-login-contract.test.ts`
|
|
83
|
+
- `tests/grok-execution-parity.test.ts`
|
|
84
|
+
- `tests/grok-image-address-policy.test.ts`
|
|
85
|
+
- `tests/grok-image-download-pinning.test.ts`
|
|
86
|
+
- `tests/grok-image-download-policy.test.ts`
|
|
73
87
|
- `tests/grok-planner-adapter.test.ts`
|
|
74
88
|
- `tests/grok-planner-config-route.test.ts`
|
|
75
89
|
- `tests/grok-proxy-launcher.test.ts`
|
|
@@ -78,6 +92,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
78
92
|
- `tests/grok-size-mapper.test.ts`
|
|
79
93
|
- `tests/grok-upstream-retry.test.ts`
|
|
80
94
|
- `tests/grokVideoAdapter.test.ts`
|
|
95
|
+
- `tests/grokVideoDownload.test.ts`
|
|
81
96
|
- `tests/grokVideoPlannerFallback.test.ts`
|
|
82
97
|
- `tests/grokVideoTimeoutBudgets.test.ts`
|
|
83
98
|
- `tests/history-metadata-fallback.test.ts`
|
|
@@ -89,11 +104,15 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
89
104
|
- `tests/inflight-guard-contract.test.ts`
|
|
90
105
|
- `tests/inflight-persistence.test.ts`
|
|
91
106
|
- `tests/inflight.test.ts`
|
|
107
|
+
- `tests/job-cancellation-terminal.test.ts`
|
|
92
108
|
- `tests/job-envelope-contract.test.ts`
|
|
93
109
|
- `tests/job-envelope-terminal-coverage.test.ts`
|
|
94
110
|
- `tests/job-idempotency.test.ts`
|
|
95
111
|
- `tests/job-terminal-status-contract.test.ts`
|
|
112
|
+
- `tests/lan-media-access.test.ts`
|
|
113
|
+
- `tests/lan-session.test.ts`
|
|
96
114
|
- `tests/local-import-contract.test.ts`
|
|
115
|
+
- `tests/local-lan-policy.test.ts`
|
|
97
116
|
- `tests/logging.test.ts`
|
|
98
117
|
- `tests/mcp-character-route.test.ts`
|
|
99
118
|
- `tests/mcp-connection-manager.test.ts`
|
|
@@ -131,6 +150,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
131
150
|
- `tests/nai-zip-decode.test.ts`
|
|
132
151
|
- `tests/node-parent-source-contract.test.ts`
|
|
133
152
|
- `tests/node-route-refs.test.ts`
|
|
153
|
+
- `tests/node-store-metadata.test.ts`
|
|
134
154
|
- `tests/node-streaming-sse.test.ts`
|
|
135
155
|
- `tests/node-template-contract.test.ts`
|
|
136
156
|
- `tests/node-validation-error-contract.test.ts`
|
|
@@ -138,19 +158,30 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
138
158
|
- `tests/oauth-normalize.test.ts`
|
|
139
159
|
- `tests/oauth-proxy-error-safety.test.ts`
|
|
140
160
|
- `tests/open-directory.test.ts`
|
|
161
|
+
- `tests/openai-execution-parity.test.ts`
|
|
162
|
+
- `tests/openai-transport-parity.test.ts`
|
|
141
163
|
- `tests/preset-compiler.test.ts`
|
|
142
164
|
- `tests/preset-restore-contract.test.ts`
|
|
143
165
|
- `tests/preset-xmp-roundtrip.test.ts`
|
|
144
166
|
- `tests/prompt-builder-contract.test.ts`
|
|
167
|
+
- `tests/prompt-candidates-normalization.test.ts`
|
|
145
168
|
- `tests/prompt-discovery-contract.test.ts`
|
|
146
169
|
- `tests/prompt-fidelity.test.ts`
|
|
147
170
|
- `tests/prompt-import-folder-contract.test.ts`
|
|
148
171
|
- `tests/prompt-import-github-contract.test.ts`
|
|
149
172
|
- `tests/prompt-index-ranking-contract.test.ts`
|
|
150
173
|
- `tests/provider-adapter-v1-contract.test.ts`
|
|
174
|
+
- `tests/provider-execution-boundary.test.ts`
|
|
175
|
+
- `tests/provider-execution-classic.test.ts`
|
|
176
|
+
- `tests/provider-execution-multimode.test.ts`
|
|
177
|
+
- `tests/provider-execution-node.test.ts`
|
|
178
|
+
- `tests/provider-execution-routes.test.ts`
|
|
151
179
|
- `tests/provider-registry-contract.test.ts`
|
|
152
180
|
- `tests/provider-registry-parity.test.ts`
|
|
181
|
+
- `tests/provider-surface-boundary.test.ts`
|
|
182
|
+
- `tests/provider-surface-support.test.ts`
|
|
153
183
|
- `tests/reference-image-compress.test.ts`
|
|
184
|
+
- `tests/reference-limits-node-recovery.test.mjs`
|
|
154
185
|
- `tests/refs-size.test.ts`
|
|
155
186
|
- `tests/request-logging.test.ts`
|
|
156
187
|
- `tests/responses-adapter-safety.test.ts`
|
|
@@ -170,6 +201,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
170
201
|
- `tests/sprite-atlas-manifest.test.ts`
|
|
171
202
|
- `tests/sprite-curation-store.test.ts`
|
|
172
203
|
- `tests/sprite-gif-export.test.ts`
|
|
204
|
+
- `tests/sprite-job-events.test.ts`
|
|
173
205
|
- `tests/sprite-layout-guide.test.ts`
|
|
174
206
|
- `tests/sprite-recipe-routes.test.ts`
|
|
175
207
|
- `tests/sprite-recipe-store.test.ts`
|
|
@@ -186,6 +218,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
186
218
|
- `tests/vectorize-image-contract.test.ts`
|
|
187
219
|
- `tests/video-chroma-key.test.ts`
|
|
188
220
|
- `tests/video-concat.test.ts`
|
|
221
|
+
- `tests/video-download-cancellation.test.ts`
|
|
189
222
|
- `tests/video-history-item.test.ts`
|
|
190
223
|
- `tests/video-motion-presets.test.ts`
|
|
191
224
|
- `tests/video-ref2v-duration-contract.test.ts`
|
|
@@ -210,6 +243,8 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
210
243
|
- `tests/agent-mode-streaming-a11y-contract.test.js`
|
|
211
244
|
- `tests/agent-mode-tool-call-rendering-contract.test.js`
|
|
212
245
|
- `tests/agent-mode-tool-folding-contract.test.js`
|
|
246
|
+
- `tests/agy-artifact-check-contract.test.ts`
|
|
247
|
+
- `tests/agy-artifact-read-bounds.test.ts`
|
|
213
248
|
- `tests/api-docs-contract.test.js`
|
|
214
249
|
- `tests/app-weight-splitting-contract.test.js`
|
|
215
250
|
- `tests/asset-element-toggle-contract.test.ts`
|
|
@@ -260,6 +295,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
260
295
|
- `tests/card-news-smoke.test.js`
|
|
261
296
|
- `tests/card-news-visible-text-language-contract.test.ts`
|
|
262
297
|
- `tests/character-binding-ui-contract.test.ts`
|
|
298
|
+
- `tests/ci-windows-candidate.test.ts`
|
|
263
299
|
- `tests/cli-capabilities-contract.test.js`
|
|
264
300
|
- `tests/cli-character-contract.test.js`
|
|
265
301
|
- `tests/cli-commands.test.js`
|
|
@@ -274,12 +310,13 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
274
310
|
- `tests/cli-prompt-builder-contract.test.js`
|
|
275
311
|
- `tests/cli-prompt-import-contract.test.js`
|
|
276
312
|
- `tests/cli-skill-command-contract.test.js`
|
|
313
|
+
- `tests/cli-unknown-options.test.ts`
|
|
277
314
|
- `tests/cli-upscale-contract.test.js`
|
|
278
315
|
- `tests/cli-video-command-contract.test.js`
|
|
279
316
|
- `tests/color-key.test.ts`
|
|
280
317
|
- `tests/comfy-cli-contract.test.ts`
|
|
318
|
+
- `tests/comfy-display.test.ts`
|
|
281
319
|
- `tests/comfy-export-ui-contract.test.js`
|
|
282
|
-
- `tests/comfy-selection-persistence.test.js`
|
|
283
320
|
- `tests/comfy-ui-contract.test.ts`
|
|
284
321
|
- `tests/comfyui-custom-node-contract.test.js`
|
|
285
322
|
- `tests/composer-feedback-contract.test.js`
|
|
@@ -287,14 +324,25 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
287
324
|
- `tests/composer-tray-ui-contract.test.js`
|
|
288
325
|
- `tests/config.test.js`
|
|
289
326
|
- `tests/contract-docs-projection.test.ts`
|
|
327
|
+
- `tests/core-generation-mode.test.ts`
|
|
328
|
+
- `tests/core-selection-actions.test.ts`
|
|
329
|
+
- `tests/core-selection-memory.test.ts`
|
|
330
|
+
- `tests/core-selection-reconcile.test.ts`
|
|
331
|
+
- `tests/core-selection-transport.test.mjs`
|
|
290
332
|
- `tests/current-image-actions-readiness-contract.test.js`
|
|
291
333
|
- `tests/direct-mode-visual-contract.test.js`
|
|
292
334
|
- `tests/duration-slider-contract.test.js`
|
|
335
|
+
- `tests/e2e-app-environment.test.ts`
|
|
336
|
+
- `tests/e2e-runtime-build.test.mjs`
|
|
337
|
+
- `tests/e2e-runtime-guards.test.mjs`
|
|
293
338
|
- `tests/edit-mask-api-contract.test.js`
|
|
294
339
|
- `tests/element-mention-ui-contract.test.js`
|
|
295
340
|
- `tests/error-ui-consumption.test.ts`
|
|
341
|
+
- `tests/event-channel-replay-gap.test.ts`
|
|
342
|
+
- `tests/execution-network-isolation.test.ts`
|
|
343
|
+
- `tests/execution-process-isolation.test.ts`
|
|
296
344
|
- `tests/frame-extraction-fallback.test.ts`
|
|
297
|
-
- `tests/frontend-connection-state-contract.test.
|
|
345
|
+
- `tests/frontend-connection-state-contract.test.ts`
|
|
298
346
|
- `tests/frontend-sse-risk-contract.test.js`
|
|
299
347
|
- `tests/gallery-hang-regression-contract.test.ts`
|
|
300
348
|
- `tests/gallery-load-older-contract.test.js`
|
|
@@ -304,6 +352,8 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
304
352
|
- `tests/gallery-shortcuts-behavior.test.js`
|
|
305
353
|
- `tests/gallery-shortcuts-visible-domain-contract.test.js`
|
|
306
354
|
- `tests/gallery-viewer-navigation-contract.test.js`
|
|
355
|
+
- `tests/gemini-api-wire-contract.test.ts`
|
|
356
|
+
- `tests/gemini-transport-parity.test.ts`
|
|
307
357
|
- `tests/gen-output-path-contract.test.js`
|
|
308
358
|
- `tests/generation-controls-ux-contract.test.js`
|
|
309
359
|
- `tests/generation-limit-unlock-contract.test.js`
|
|
@@ -311,7 +361,7 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
311
361
|
- `tests/health.test.js`
|
|
312
362
|
- `tests/history-index-contract.test.js`
|
|
313
363
|
- `tests/history-permanent-delete.test.js`
|
|
314
|
-
- `tests/history-strip-duplicate-contract.test.
|
|
364
|
+
- `tests/history-strip-duplicate-contract.test.ts`
|
|
315
365
|
- `tests/i18n-coverage-contract.test.ts`
|
|
316
366
|
- `tests/i18n-dictionary-contract.test.ts`
|
|
317
367
|
- `tests/image-metadata-ui-contract.test.js`
|
|
@@ -319,14 +369,23 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
319
369
|
- `tests/inflight-cancel-contract.test.js`
|
|
320
370
|
- `tests/inflight-list-tooltip-contract.test.js`
|
|
321
371
|
- `tests/inflight-popup-polish-contract.test.js`
|
|
322
|
-
- `tests/inflight-
|
|
323
|
-
- `tests/inflight-reload-
|
|
372
|
+
- `tests/inflight-reconciliation-behavior.test.ts`
|
|
373
|
+
- `tests/inflight-reload-race.test.ts`
|
|
374
|
+
- `tests/inflight-reload-reconcile-contract.test.ts`
|
|
375
|
+
- `tests/install-runtime-contract.test.ts`
|
|
324
376
|
- `tests/install-windows-contract.test.js`
|
|
325
377
|
- `tests/issue75-prompt-studio-state-contract.test.js`
|
|
326
378
|
- `tests/issue77-long-prompt-preview-contract.test.js`
|
|
379
|
+
- `tests/j6-isolation-preflight.test.mjs`
|
|
380
|
+
- `tests/job-tracking-ci-contract.test.ts`
|
|
381
|
+
- `tests/job-tracking-timeout-ui.test.ts`
|
|
382
|
+
- `tests/lan-config.test.ts`
|
|
383
|
+
- `tests/lane-catalog.test.ts`
|
|
327
384
|
- `tests/mcp-media-kind-behavior.test.ts`
|
|
328
385
|
- `tests/mcp-provider-smoke.test.ts`
|
|
329
386
|
- `tests/mcp-provider-ui-contract.test.js`
|
|
387
|
+
- `tests/mcp-readiness-observation.test.ts`
|
|
388
|
+
- `tests/mcp-readiness.test.ts`
|
|
330
389
|
- `tests/mcp-schema-spike-contract.test.ts`
|
|
331
390
|
- `tests/mcp-selection-helpers.test.ts`
|
|
332
391
|
- `tests/mcp-settings-states-contract.test.ts`
|
|
@@ -367,8 +426,11 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
367
426
|
- `tests/oauth-proxy-edit-mask-contract.test.js`
|
|
368
427
|
- `tests/package-global-update-smoke-contract.test.ts`
|
|
369
428
|
- `tests/package-smoke.test.js`
|
|
429
|
+
- `tests/pages-publication-contract.test.ts`
|
|
430
|
+
- `tests/platform-open-url.test.ts`
|
|
370
431
|
- `tests/png-info-contract.test.js`
|
|
371
432
|
- `tests/portal-dropdown-scroll-dismiss-contract.test.ts`
|
|
433
|
+
- `tests/pr-fast-history.test.mjs`
|
|
372
434
|
- `tests/prompt-curated-search-contract.test.js`
|
|
373
435
|
- `tests/prompt-discovery-ui-contract.test.js`
|
|
374
436
|
- `tests/prompt-import-dialog-ui-contract.test.js`
|
|
@@ -380,10 +442,15 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
380
442
|
- `tests/provenance-chip-contract.test.ts`
|
|
381
443
|
- `tests/provider-canary-live-contract.test.ts`
|
|
382
444
|
- `tests/provider-canary-parity.test.ts`
|
|
445
|
+
- `tests/provider-execution-edit.test.ts`
|
|
446
|
+
- `tests/provider-execution-harness.test.ts`
|
|
447
|
+
- `tests/provider-execution-imports.test.ts`
|
|
383
448
|
- `tests/provider-ui-polish-contract.test.js`
|
|
384
449
|
- `tests/reference-limits.test.ts`
|
|
385
450
|
- `tests/reference-tray-model.test.ts`
|
|
386
451
|
- `tests/release-pipeline-contract.test.ts`
|
|
452
|
+
- `tests/runtime-install-projection.test.ts`
|
|
453
|
+
- `tests/selector-comfy-admission.test.ts`
|
|
387
454
|
- `tests/server-fallback-contract.test.js`
|
|
388
455
|
- `tests/server.test.js`
|
|
389
456
|
- `tests/session-conflict.test.js`
|
|
@@ -403,11 +470,15 @@ Total: 416 (runtime: 191, contract: 225)
|
|
|
403
470
|
- `tests/studio-surface-docs-contract.test.ts`
|
|
404
471
|
- `tests/style-feature-removal-contract.test.js`
|
|
405
472
|
- `tests/subprocess-deadline-contract.test.ts`
|
|
473
|
+
- `tests/test-runner-invocation.test.ts`
|
|
406
474
|
- `tests/toast-stack-contract.test.js`
|
|
407
475
|
- `tests/tools-cli-contract.test.ts`
|
|
408
476
|
- `tests/transparent-background-ui-contract.test.js`
|
|
477
|
+
- `tests/ui-build-receipt-inventory.test.mjs`
|
|
478
|
+
- `tests/ui-build-receipt-transaction.test.mjs`
|
|
479
|
+
- `tests/ui-build-receipt.test.mjs`
|
|
409
480
|
- `tests/ui-color-token-contract.test.ts`
|
|
410
|
-
- `tests/ui-error-code-contract.test.
|
|
481
|
+
- `tests/ui-error-code-contract.test.ts`
|
|
411
482
|
- `tests/ui-glyph-policy.test.ts`
|
|
412
483
|
- `tests/ui-gradient-manifest-contract.test.ts`
|
|
413
484
|
- `tests/ui-radius-scale-contract.test.ts`
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { agyError } from "./agyProcess.js";
|
|
5
|
+
export function parseAgyOutput(stdout) {
|
|
6
|
+
const lines = stdout.replace(/\r/g, "").trim().split("\n").filter((l) => l.trim().length > 0);
|
|
7
|
+
const resultLine = lines.find((l) => l.startsWith("RESULT|"));
|
|
8
|
+
if (resultLine) {
|
|
9
|
+
const parts = resultLine.split("|");
|
|
10
|
+
const artifactPath = parts[1];
|
|
11
|
+
const ext = parts[2];
|
|
12
|
+
if (parts.length >= 3 && artifactPath && ext) {
|
|
13
|
+
return { artifactPath: artifactPath.trim(), ext: ext.trim() };
|
|
14
|
+
}
|
|
15
|
+
throw agyError(`Malformed RESULT line: ${resultLine}`, 502, "AGY_MALFORMED_RESULT");
|
|
16
|
+
}
|
|
17
|
+
const errorLine = lines.find((l) => l.startsWith("ERROR|"));
|
|
18
|
+
if (errorLine) {
|
|
19
|
+
const msg = errorLine.slice("ERROR|".length).trim() || "Unknown agy error";
|
|
20
|
+
const lower = msg.toLowerCase();
|
|
21
|
+
if (lower.includes("resource exhausted") || lower.includes("exhausted your capacity") || lower.includes("quota will reset")) {
|
|
22
|
+
throw agyError(`Agy generation failed: ${msg}`, 429, "AGY_QUOTA_EXHAUSTED");
|
|
23
|
+
}
|
|
24
|
+
throw agyError(`Agy generation failed: ${msg}`, 502, "AGY_GENERATION_FAILED");
|
|
25
|
+
}
|
|
26
|
+
const fullLower = stdout.toLowerCase();
|
|
27
|
+
if (fullLower.includes("resource exhausted") || fullLower.includes("exhausted your capacity")) {
|
|
28
|
+
throw agyError(`Agy quota exhausted: ${stdout.trim().slice(0, 200)}`, 429, "AGY_QUOTA_EXHAUSTED");
|
|
29
|
+
}
|
|
30
|
+
const savedPathLine = lines.find((l) => l.startsWith("SAVED_PATH="));
|
|
31
|
+
if (savedPathLine) {
|
|
32
|
+
const p = savedPathLine.slice("SAVED_PATH=".length).trim();
|
|
33
|
+
const ext = p.split(".").pop() || "png";
|
|
34
|
+
return { artifactPath: p, ext };
|
|
35
|
+
}
|
|
36
|
+
const normalizedStdout = stdout.replace(/\r/g, "").replace(/\\/g, "/");
|
|
37
|
+
const pathMatch = normalizedStdout.match(/(?:[A-Za-z]:)?\/[^\s"']+\/(brain|artifacts|\.gemini)\/[^\s"']+\.(png|jpg|jpeg|webp)/i);
|
|
38
|
+
if (pathMatch) {
|
|
39
|
+
const matched = pathMatch[0];
|
|
40
|
+
const artifactPath = process.platform === "win32" ? matched.replace(/\//g, "\\") : matched;
|
|
41
|
+
const ext = extname(artifactPath).slice(1) || "png";
|
|
42
|
+
return { artifactPath, ext };
|
|
43
|
+
}
|
|
44
|
+
throw agyError(`Could not parse artifact path from agy output (${stdout.length} chars): ${stdout.slice(0, 200)}`, 502, "AGY_PARSE_FAILED");
|
|
45
|
+
}
|
|
46
|
+
export async function findRecentAgyArtifact(sinceMs, rootOverrides) {
|
|
47
|
+
const roots = rootOverrides ?? [
|
|
48
|
+
join(homedir(), ".gemini", "antigravity-cli", "brain"),
|
|
49
|
+
join(homedir(), ".gemini"),
|
|
50
|
+
];
|
|
51
|
+
const candidates = [];
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
async function walk(dir, depth) {
|
|
54
|
+
if (depth > 5 || seen.has(dir))
|
|
55
|
+
return;
|
|
56
|
+
seen.add(dir);
|
|
57
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (entry.isSymbolicLink())
|
|
60
|
+
continue;
|
|
61
|
+
const p = join(dir, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
await walk(p, depth + 1);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!entry.isFile() || !/^ima2_generated.*\.(png|jpg|jpeg|webp)$/i.test(entry.name)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const s = await stat(p).catch(() => null);
|
|
70
|
+
if (!s?.isFile())
|
|
71
|
+
continue;
|
|
72
|
+
if (s.mtimeMs >= sinceMs - 5_000) {
|
|
73
|
+
candidates.push({ path: p, mtimeMs: s.mtimeMs });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const root of roots) {
|
|
78
|
+
await walk(root, 0);
|
|
79
|
+
}
|
|
80
|
+
candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
81
|
+
return candidates[0]?.path ?? null;
|
|
82
|
+
}
|