feat(ai-tools): install/update AI CLIs, remote catalog sync, cached favicons (#40 A2)

This commit is contained in:
2026-09-29 08:25:37 +07:00
parent fcfebe44f1
commit 7ec5a7cd85
40 changed files with 3145 additions and 92 deletions
+18
View File
@@ -6,6 +6,24 @@ One JSON file per AI coding CLI AgentHub can run in a lane. Loaded by
`DASHBOARD_AI_TOOLS_DIR` with the same `id` replaces the built-in one (it may
not set `launcher`).
## Install / update (A2)
Two optional fields, honoured only in built-in files and in the copy of the
newest release's catalog that `server/lib/ai-tools-sync.js` keeps in
`<data dir>/runtime/ai-tools-remote/` — a file in `DASHBOARD_AI_TOOLS_DIR`
carrying either is rejected, because an Install click would run what it names:
- `install`: `{ "kind": "npm", "package": "<npm name>" }` (runs
`npm install -g <package>@latest` with the login shell's npm) or
`{ "kind": "script", "url": "https://…" }` (https, same site — last two host
labels — as `homepageUrl`; downloaded by the server, run as `bash <file>`).
- `update`: `{ "kind": "npm" }` or `{ "kind": "script" }` (reuse `install`),
or `{ "kind": "self", "args": ["update"] }` (the tool's own updater).
Before adding an npm package, check its owner (`npm view <pkg> maintainers
repository.url`) and that its `bin` matches `detect`: a squatted name would
install a stranger's code on every machine that clicks Install.
## Attribution
The commands, prompt modes, permission-bypass flags and homepages of the tools
+8 -1
View File
@@ -12,5 +12,12 @@
"--dangerously-allow-all"
],
"homepageUrl": "https://ampcode.com/manual#install",
"faviconDomain": "ampcode.com"
"faviconDomain": "ampcode.com",
"install": {
"kind": "npm",
"package": "@sourcegraph/amp"
},
"update": {
"kind": "npm"
}
}
+7 -1
View File
@@ -5,5 +5,11 @@
"claude"
],
"launcher": "claude",
"homepageUrl": "https://code.claude.com/docs"
"homepageUrl": "https://code.claude.com/docs",
"update": {
"kind": "self",
"args": [
"update"
]
}
}
+8 -1
View File
@@ -8,5 +8,12 @@
"bypass": [
"--dangerously-bypass-approvals-and-sandbox"
],
"homepageUrl": "https://github.com/openai/codex"
"homepageUrl": "https://github.com/openai/codex",
"install": {
"kind": "npm",
"package": "@openai/codex"
},
"update": {
"kind": "npm"
}
}
+8 -1
View File
@@ -11,5 +11,12 @@
"bypass": [
"--yolo"
],
"homepageUrl": "https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli"
"homepageUrl": "https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli",
"install": {
"kind": "npm",
"package": "@github/copilot"
},
"update": {
"kind": "npm"
}
}
+8 -1
View File
@@ -11,5 +11,12 @@
"--yolo"
],
"homepageUrl": "https://cursor.com/cli",
"faviconDomain": "cursor.com"
"faviconDomain": "cursor.com",
"install": {
"kind": "script",
"url": "https://cursor.com/install"
},
"update": {
"kind": "script"
}
}
+8 -1
View File
@@ -12,5 +12,12 @@
"--yolo"
],
"homepageUrl": "https://github.com/google-gemini/gemini-cli",
"faviconDomain": "gemini.google.com"
"faviconDomain": "gemini.google.com",
"install": {
"kind": "npm",
"package": "@google/gemini-cli"
},
"update": {
"kind": "npm"
}
}
+8 -1
View File
@@ -8,5 +8,12 @@
"mode": "flag",
"flag": "--prompt"
},
"homepageUrl": "https://opencode.ai/docs/cli/"
"homepageUrl": "https://opencode.ai/docs/cli/",
"install": {
"kind": "npm",
"package": "opencode-ai"
},
"update": {
"kind": "npm"
}
}
+8 -1
View File
@@ -13,5 +13,12 @@
"yolo"
],
"homepageUrl": "https://github.com/QwenLM/qwen-code",
"faviconDomain": "qwenlm.github.io"
"faviconDomain": "qwenlm.github.io",
"install": {
"kind": "npm",
"package": "@qwen-code/qwen-code"
},
"update": {
"kind": "npm"
}
}