@xcanwin/manyoyo 3.4.0 → 3.5.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/README.md +20 -23
- package/bin/manyoyo.js +60 -45
- package/docker/manyoyo.Dockerfile +17 -11
- package/docs/README_EN.md +20 -23
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[English](docs/README_EN.md) |
|
|
1
|
+
[English](docs/README_EN.md) | **<[中文](README.md)>**
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
@@ -50,24 +50,20 @@ npm install -g .
|
|
|
50
50
|
podman pull ubuntu:24.04
|
|
51
51
|
|
|
52
52
|
# 使用 manyoyo 构建镜像(推荐,自动使用缓存加速)
|
|
53
|
-
manyoyo --ib
|
|
54
|
-
manyoyo --ib common
|
|
55
|
-
manyoyo --ib go,codex,java,gemini
|
|
53
|
+
manyoyo --ib # 默认构建 full 版本(推荐)
|
|
54
|
+
manyoyo --ib --iba TOOL=common # 构建常见组件版本
|
|
55
|
+
manyoyo --ib --iba TOOL=go,codex,java,gemini # 构建自定义组件版本
|
|
56
|
+
manyoyo --ib --iba --iba GIT_SSL_NO_VERIFY=true # 构建 full 版本且git跳过ssl认证
|
|
57
|
+
manyoyo --ib full --in myimage --iv 2.0.0 # 自定义镜像名称和版本,得到 myimage:2.0.0-full
|
|
58
|
+
manyoyo --ip # 清理悬空镜像和 <none> 镜像
|
|
56
59
|
|
|
57
60
|
# 工作原理:
|
|
58
61
|
# - 首次构建:自动下载 Node.js、JDT LSP、gopls 等到 docker/cache/
|
|
59
62
|
# - 2天内再次构建:直接使用本地缓存,速度提升约 5 倍
|
|
60
63
|
# - 缓存过期后:自动重新下载最新版本
|
|
61
64
|
|
|
62
|
-
# 自定义镜像名称和版本
|
|
63
|
-
manyoyo --ib all --in myimage --iv 2.0.0
|
|
64
|
-
# 构建:myimage:2.0.0-all
|
|
65
|
-
|
|
66
|
-
# 清理镜像
|
|
67
|
-
manyoyo --ip # 清理悬空镜像和 <none> 镜像
|
|
68
|
-
|
|
69
65
|
# 或手动构建(不推荐)
|
|
70
|
-
iv=1.4.0 && podman build -t localhost/xcanwin/manyoyo:$iv-
|
|
66
|
+
iv=1.4.0 && podman build -t localhost/xcanwin/manyoyo:$iv-full -f docker/manyoyo.Dockerfile . --build-arg TOOL=full --no-cache
|
|
71
67
|
podman image prune -f
|
|
72
68
|
```
|
|
73
69
|
|
|
@@ -177,11 +173,10 @@ manyoyo -y oc # 或: opencode
|
|
|
177
173
|
# 创建支持 Docker-in-Docker 的容器
|
|
178
174
|
manyoyo -n docker-dev -m dind -x /bin/bash
|
|
179
175
|
|
|
180
|
-
#
|
|
181
|
-
nohup dockerd &
|
|
176
|
+
podman ps -a # 现在可以在容器内使用 podman 命令
|
|
182
177
|
|
|
183
|
-
#
|
|
184
|
-
docker ps -a
|
|
178
|
+
nohup dockerd & # 在容器内启动 dockerd
|
|
179
|
+
docker ps -a # 现在可以在容器内使用 docker 命令
|
|
185
180
|
```
|
|
186
181
|
|
|
187
182
|
#### 挂载 Docker Socket 开发
|
|
@@ -189,10 +184,11 @@ docker ps -a
|
|
|
189
184
|
```bash
|
|
190
185
|
# 挂载 Docker Socket(危险的!!!容器可以访问和执行宿主机的一切)
|
|
191
186
|
# 创建挂载 /var/run/docker.sock 的容器
|
|
192
|
-
manyoyo -n socket-dev -m
|
|
187
|
+
manyoyo -n socket-dev -m sock -x /bin/bash
|
|
188
|
+
|
|
189
|
+
podman ps -a # 现在可以在容器内使用 podman 命令
|
|
193
190
|
|
|
194
|
-
# 现在可以在容器内使用 docker 命令
|
|
195
|
-
docker ps -a
|
|
191
|
+
docker ps -a # 现在可以在容器内使用 docker 命令
|
|
196
192
|
```
|
|
197
193
|
|
|
198
194
|
### 命令行选项
|
|
@@ -214,8 +210,9 @@ docker ps -a
|
|
|
214
210
|
| `--` | `--ss`, `--shell-suffix` | 命令参数(作为 -s 的后缀) |
|
|
215
211
|
| `-x CMD` | `--sf`, `--shell-full` | 完整命令(替代 --sp, -s 和 --) |
|
|
216
212
|
| `-y CLI` | `--yolo` | 无需确认运行 AI 智能体 |
|
|
217
|
-
| `-m MODE` | `--cm`, `--cont-mode` | 设置容器模式(common, dind,
|
|
218
|
-
| `--ib
|
|
213
|
+
| `-m MODE` | `--cm`, `--cont-mode` | 设置容器模式(common, dind, sock) |
|
|
214
|
+
| `--ib` | `--image-build` | 构建镜像 |
|
|
215
|
+
| `--iba XXX=YYY` | `--image-build-arg` | 构建镜像时传参给dockerfile |
|
|
219
216
|
| `--ip` | `--image-prune` | 清理悬空镜像和 `<none>` 镜像 |
|
|
220
217
|
| `--install NAME` | | 安装 manyoyo 命令 |
|
|
221
218
|
| `-V` | `--version` | 显示版本 |
|
|
@@ -232,8 +229,8 @@ docker ps -a
|
|
|
232
229
|
|
|
233
230
|
### 系统要求
|
|
234
231
|
|
|
235
|
-
- Node.js >=
|
|
236
|
-
-
|
|
232
|
+
- Node.js >= 22.0.0
|
|
233
|
+
- Podman 或 Docker
|
|
237
234
|
|
|
238
235
|
### 卸载
|
|
239
236
|
|
package/bin/manyoyo.js
CHANGED
|
@@ -25,14 +25,14 @@ let CONTAINER_NAME = `myy-${formatDate()}`;
|
|
|
25
25
|
let HOST_PATH = process.cwd();
|
|
26
26
|
let CONTAINER_PATH = HOST_PATH;
|
|
27
27
|
let IMAGE_NAME = "localhost/xcanwin/manyoyo";
|
|
28
|
-
let IMAGE_VERSION = `${IMAGE_VERSION_BASE}-
|
|
28
|
+
let IMAGE_VERSION = `${IMAGE_VERSION_BASE}-full`;
|
|
29
29
|
let EXEC_COMMAND = "";
|
|
30
30
|
let EXEC_COMMAND_PREFIX = "";
|
|
31
31
|
let EXEC_COMMAND_SUFFIX = "";
|
|
32
32
|
let ENV_FILE = "";
|
|
33
33
|
let SHOULD_REMOVE = false;
|
|
34
|
-
let
|
|
35
|
-
let
|
|
34
|
+
let IMAGE_BUILD_NEED = false;
|
|
35
|
+
let IMAGE_BUILD_ARGS = [];
|
|
36
36
|
let CONTAINER_ENVS = [];
|
|
37
37
|
let CONTAINER_VOLUMES = [];
|
|
38
38
|
let MANYOYO_NAME = "manyoyo";
|
|
@@ -67,35 +67,34 @@ function showHelp() {
|
|
|
67
67
|
console.log(` ${MANYOYO_NAME} [--hp HOST_PATH] [-n CONTAINER_NAME] [--cp CONTAINER_PATH] [--ef ENV_FILE] [--sp COMMAND] [-s COMMAND] [-- COMMAND]`);
|
|
68
68
|
console.log("");
|
|
69
69
|
console.log(`${BLUE}Options:${NC}`);
|
|
70
|
-
console.log(" -l|--ls|--list
|
|
71
|
-
console.log(" --hp|--host-path PATH
|
|
72
|
-
console.log(" -n|--cn|--cont-name NAME
|
|
73
|
-
console.log(" --cp|--cont-path PATH
|
|
74
|
-
console.log(" --in|--image-name NAME
|
|
75
|
-
console.log(" --iv|--image-ver VERSION
|
|
76
|
-
console.log(" -e|--env
|
|
77
|
-
console.log(" --ef|--env-file ENV_FILE
|
|
78
|
-
console.log(" -v|--volume
|
|
79
|
-
console.log(" --rm|--remove-cont
|
|
80
|
-
console.log(" --sp|--shell-prefix COMMAND
|
|
81
|
-
console.log(" -s|--shell COMMAND
|
|
82
|
-
console.log(" --|--shell-suffix COMMAND
|
|
83
|
-
console.log(" -x|--shell-full COMMAND
|
|
84
|
-
console.log(" -y|--yolo CLI
|
|
85
|
-
console.log("
|
|
86
|
-
console.log(" -m|--cm|--cont-mode STRING
|
|
87
|
-
console.log("
|
|
88
|
-
console.log(" --ib|--image-build
|
|
89
|
-
console.log("
|
|
90
|
-
console.log("
|
|
91
|
-
console.log(" --
|
|
92
|
-
console.log("
|
|
93
|
-
console.log("
|
|
94
|
-
console.log(" -
|
|
95
|
-
console.log(" -h|--help 显示帮助");
|
|
70
|
+
console.log(" -l|--ls|--list 列举容器");
|
|
71
|
+
console.log(" --hp|--host-path PATH 设置宿主机工作目录 (默认当前路径)");
|
|
72
|
+
console.log(" -n|--cn|--cont-name NAME 设置容器名称");
|
|
73
|
+
console.log(" --cp|--cont-path PATH 设置容器工作目录");
|
|
74
|
+
console.log(" --in|--image-name NAME 指定镜像名称");
|
|
75
|
+
console.log(" --iv|--image-ver VERSION 指定镜像版本");
|
|
76
|
+
console.log(" -e|--env XXX=YYY 设置环境变量");
|
|
77
|
+
console.log(" --ef|--env-file ENV_FILE 设置环境变量通过文件");
|
|
78
|
+
console.log(" -v|--volume XXX:YYY 绑定挂载卷");
|
|
79
|
+
console.log(" --rm|--remove-cont 删除-n容器");
|
|
80
|
+
console.log(" --sp|--shell-prefix COMMAND 临时环境变量 (作为-s前缀)");
|
|
81
|
+
console.log(" -s|--shell COMMAND 指定命令执行");
|
|
82
|
+
console.log(" --|--shell-suffix COMMAND 指定命令参数, --后面全部直传 (作为-s后缀)");
|
|
83
|
+
console.log(" -x|--shell-full COMMAND 指定完整命令执行, -x后面全部直传 (代替--sp和-s和--命令)");
|
|
84
|
+
console.log(" -y|--yolo CLI 使AGENT无需确认 (代替-s命令)");
|
|
85
|
+
console.log(" 例如 claude / c, gemini / gm, codex / cx, opencode / oc");
|
|
86
|
+
console.log(" -m|--cm|--cont-mode STRING 设置容器嵌套容器模式");
|
|
87
|
+
console.log(" 例如 common, dind, sock");
|
|
88
|
+
console.log(" --ib|--image-build 构建镜像");
|
|
89
|
+
console.log(" --iba|--image-build-arg XXX=YYY 构建镜像时传参给dockerfile");
|
|
90
|
+
console.log(" --ip|--image-prune 清理悬空镜像和 <none> 镜像");
|
|
91
|
+
console.log(" --install NAME 安装manyoyo命令");
|
|
92
|
+
console.log(" 例如 docker-cli-plugin");
|
|
93
|
+
console.log(" -V|--version 显示版本");
|
|
94
|
+
console.log(" -h|--help 显示帮助");
|
|
96
95
|
console.log("");
|
|
97
96
|
console.log(`${BLUE}Example:${NC}`);
|
|
98
|
-
console.log(` ${MANYOYO_NAME} --ib
|
|
97
|
+
console.log(` ${MANYOYO_NAME} --ib 构建镜像`);
|
|
99
98
|
console.log(` ${MANYOYO_NAME} -n test --ef ./xxx.env -y c 设置环境变量并运行无需确认的AGENT`);
|
|
100
99
|
console.log(` ${MANYOYO_NAME} -n test -- -c 恢复之前会话`);
|
|
101
100
|
console.log(` ${MANYOYO_NAME} -x echo 123 指定命令执行`);
|
|
@@ -214,9 +213,9 @@ function setContMode(mode) {
|
|
|
214
213
|
console.log(`${GREEN}✅ 开启安全的容器嵌套容器模式, 手动在容器内启动服务: nohup dockerd &${NC}`);
|
|
215
214
|
break;
|
|
216
215
|
case 'mount-docker-socket':
|
|
217
|
-
case '
|
|
216
|
+
case 'sock':
|
|
218
217
|
case 's':
|
|
219
|
-
CONT_MODE = "--privileged --volume /var/run/docker.sock:/var/run/docker.sock";
|
|
218
|
+
CONT_MODE = "--privileged --volume /var/run/docker.sock:/var/run/docker.sock --env DOCKER_HOST=unix:///var/run/docker.sock --env CONTAINER_HOST=unix:///var/run/docker.sock";
|
|
220
219
|
console.log(`${RED}⚠️ 开启危险的容器嵌套容器模式, 危害: 容器可访问宿主机文件${NC}`);
|
|
221
220
|
break;
|
|
222
221
|
default:
|
|
@@ -326,7 +325,7 @@ function pruneDanglingImages() {
|
|
|
326
325
|
console.log(`${GREEN}✅ 清理完成${NC}`);
|
|
327
326
|
}
|
|
328
327
|
|
|
329
|
-
async function prepareBuildCache(
|
|
328
|
+
async function prepareBuildCache(imageTool) {
|
|
330
329
|
const cacheDir = path.join(__dirname, '../docker/cache');
|
|
331
330
|
const timestampFile = path.join(cacheDir, '.timestamps.json');
|
|
332
331
|
const cacheTTLDays = 2;
|
|
@@ -390,7 +389,7 @@ async function prepareBuildCache(ext) {
|
|
|
390
389
|
}
|
|
391
390
|
|
|
392
391
|
// Prepare JDT LSP cache (for java variant)
|
|
393
|
-
if (
|
|
392
|
+
if (imageTool === 'full' || imageTool.includes('java')) {
|
|
394
393
|
const jdtlsCacheDir = path.join(cacheDir, 'jdtls');
|
|
395
394
|
const jdtlsKey = 'jdtls/jdt-language-server-latest.tar.gz'; // 使用相对路径
|
|
396
395
|
const jdtlsPath = path.join(cacheDir, jdtlsKey);
|
|
@@ -417,7 +416,7 @@ async function prepareBuildCache(ext) {
|
|
|
417
416
|
}
|
|
418
417
|
|
|
419
418
|
// Prepare gopls cache (for go variant)
|
|
420
|
-
if (
|
|
419
|
+
if (imageTool === 'full' || imageTool.includes('go')) {
|
|
421
420
|
const goplsCacheDir = path.join(cacheDir, 'gopls');
|
|
422
421
|
const goplsKey = `gopls/gopls-linux-${arch}`; // 使用相对路径
|
|
423
422
|
const goplsPath = path.join(cacheDir, goplsKey);
|
|
@@ -475,16 +474,26 @@ async function prepareBuildCache(ext) {
|
|
|
475
474
|
console.log(`${GREEN}✅ 构建缓存准备完成${NC}\n`);
|
|
476
475
|
}
|
|
477
476
|
|
|
478
|
-
|
|
477
|
+
function addImageBuildArg(string) {
|
|
478
|
+
IMAGE_BUILD_ARGS.push("--build-arg", string);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async function buildImage(IMAGE_BUILD_ARGS, imageName, imageVersion) {
|
|
482
|
+
let imageTool = "full";
|
|
483
|
+
if (IMAGE_BUILD_ARGS.length === 0) {
|
|
484
|
+
IMAGE_BUILD_ARGS = ["--build-arg", `TOOL=${imageTool}`];
|
|
485
|
+
} else {
|
|
486
|
+
imageTool = IMAGE_BUILD_ARGS.filter(v => v.startsWith("TOOL=")).at(-1)?.slice("TOOL=".length) ?? imageTool;
|
|
487
|
+
}
|
|
479
488
|
// Use package.json imageVersion if not specified
|
|
480
489
|
const version = imageVersion || IMAGE_VERSION_BASE;
|
|
481
|
-
const fullImageTag = `${imageName}:${version}-${
|
|
490
|
+
const fullImageTag = `${imageName}:${version}-${imageTool}`;
|
|
482
491
|
|
|
483
492
|
console.log(`${CYAN}🔨 正在构建镜像: ${YELLOW}${fullImageTag}${NC}`);
|
|
484
|
-
console.log(`${BLUE}
|
|
493
|
+
console.log(`${BLUE}构建组件类型: ${imageTool}${NC}\n`);
|
|
485
494
|
|
|
486
495
|
// Prepare cache (自动检测并下载缺失的文件)
|
|
487
|
-
await prepareBuildCache(
|
|
496
|
+
await prepareBuildCache(imageTool);
|
|
488
497
|
|
|
489
498
|
// Find Dockerfile path
|
|
490
499
|
const dockerfilePath = path.join(__dirname, '../docker/manyoyo.Dockerfile');
|
|
@@ -494,7 +503,8 @@ async function buildImage(ext, imageName, imageVersion) {
|
|
|
494
503
|
}
|
|
495
504
|
|
|
496
505
|
// Build command
|
|
497
|
-
const
|
|
506
|
+
const imageBuildArgs = IMAGE_BUILD_ARGS.join(' ');
|
|
507
|
+
const buildCmd = `${DOCKER_CMD} build -t "${fullImageTag}" -f "${dockerfilePath}" "${path.join(__dirname, '..')}" ${imageBuildArgs} --load --progress=plain --no-cache`;
|
|
498
508
|
|
|
499
509
|
console.log(`${BLUE}准备执行命令:${NC}`);
|
|
500
510
|
console.log(`${buildCmd}\n`);
|
|
@@ -506,7 +516,7 @@ async function buildImage(ext, imageName, imageVersion) {
|
|
|
506
516
|
execSync(buildCmd, { stdio: 'inherit' });
|
|
507
517
|
console.log(`\n${GREEN}✅ 镜像构建成功: ${fullImageTag}${NC}`);
|
|
508
518
|
console.log(`${BLUE}使用镜像:${NC}`);
|
|
509
|
-
console.log(` manyoyo -n test --in ${imageName} --iv ${version}-${
|
|
519
|
+
console.log(` manyoyo -n test --in ${imageName} --iv ${version}-${imageTool} -y c`);
|
|
510
520
|
|
|
511
521
|
// Prune dangling images
|
|
512
522
|
pruneDanglingImages();
|
|
@@ -662,8 +672,13 @@ function parseArguments(argv) {
|
|
|
662
672
|
|
|
663
673
|
case '--ib':
|
|
664
674
|
case '--image-build':
|
|
665
|
-
|
|
666
|
-
|
|
675
|
+
IMAGE_BUILD_NEED = true;
|
|
676
|
+
i += 1;
|
|
677
|
+
break;
|
|
678
|
+
|
|
679
|
+
case '--iba':
|
|
680
|
+
case '--image-build-arg':
|
|
681
|
+
addImageBuildArg(args[i + 1]);
|
|
667
682
|
i += 2;
|
|
668
683
|
break;
|
|
669
684
|
|
|
@@ -867,8 +882,8 @@ async function main() {
|
|
|
867
882
|
parseArguments(process.argv);
|
|
868
883
|
|
|
869
884
|
// 3. Handle image build operation
|
|
870
|
-
if (
|
|
871
|
-
await buildImage(
|
|
885
|
+
if (IMAGE_BUILD_NEED) {
|
|
886
|
+
await buildImage(IMAGE_BUILD_ARGS, IMAGE_NAME, IMAGE_VERSION.split('-')[0]);
|
|
872
887
|
process.exit(0);
|
|
873
888
|
}
|
|
874
889
|
|
|
@@ -21,7 +21,7 @@ RUN <<EOX
|
|
|
21
21
|
if ls /cache/node/node-*-linux-${ARCH_NODE}.tar.gz 1> /dev/null 2>&1; then
|
|
22
22
|
echo "使用 Node.js 缓存"
|
|
23
23
|
NODE_TAR=$(ls /cache/node/node-*-linux-${ARCH_NODE}.tar.gz | head -1)
|
|
24
|
-
tar -xzf ${NODE_TAR} -C /opt/node --strip-components=1 --exclude='*.md' --exclude='LICENSE'
|
|
24
|
+
tar -xzf ${NODE_TAR} -C /opt/node --strip-components=1 --exclude='*.md' --exclude='LICENSE' --no-same-owner
|
|
25
25
|
else
|
|
26
26
|
echo "下载 Node.js"
|
|
27
27
|
NVM_NODEJS_ORG_MIRROR=https://mirrors.tencent.com/nodejs-release/
|
|
@@ -33,7 +33,7 @@ RUN <<EOX
|
|
|
33
33
|
mkdir -p /opt/jdtls
|
|
34
34
|
if [ -f /cache/jdtls/jdt-language-server-latest.tar.gz ]; then
|
|
35
35
|
echo "使用 JDT LSP 缓存"
|
|
36
|
-
tar -xzf /cache/jdtls/jdt-language-server-latest.tar.gz -C /opt/jdtls
|
|
36
|
+
tar -xzf /cache/jdtls/jdt-language-server-latest.tar.gz -C /opt/jdtls --no-same-owner
|
|
37
37
|
else
|
|
38
38
|
echo "下载 JDT LSP"
|
|
39
39
|
curl -fsSL https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz | tar -xz -C /opt/jdtls
|
|
@@ -59,7 +59,7 @@ FROM ubuntu:24.04
|
|
|
59
59
|
|
|
60
60
|
ARG TARGETARCH
|
|
61
61
|
ARG NODE_VERSION=24
|
|
62
|
-
ARG
|
|
62
|
+
ARG TOOL="full"
|
|
63
63
|
|
|
64
64
|
RUN <<EOX
|
|
65
65
|
# 部署 system
|
|
@@ -79,8 +79,13 @@ RUN <<EOX
|
|
|
79
79
|
tar zip unzip gzip make sqlite3 \
|
|
80
80
|
supervisor
|
|
81
81
|
|
|
82
|
+
# 安装 podman
|
|
83
|
+
case ",$TOOL," in *,full,*|*,podman,*)
|
|
84
|
+
apt-get install -y --no-install-recommends podman
|
|
85
|
+
;; esac
|
|
86
|
+
|
|
82
87
|
# 安装 docker
|
|
83
|
-
case ",$
|
|
88
|
+
case ",$TOOL," in *,full,*|*,docker,*)
|
|
84
89
|
apt-get install -y --no-install-recommends docker.io
|
|
85
90
|
;; esac
|
|
86
91
|
|
|
@@ -104,6 +109,7 @@ EOX
|
|
|
104
109
|
|
|
105
110
|
# 从 cache-stage 复制 Node.js(缓存或下载)
|
|
106
111
|
COPY --from=cache-stage /opt/node /usr/local
|
|
112
|
+
ARG GIT_SSL_NO_VERIFY=false
|
|
107
113
|
|
|
108
114
|
RUN <<EOX
|
|
109
115
|
# 配置 node.js
|
|
@@ -127,7 +133,7 @@ RUN <<EOX
|
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
EOF
|
|
130
|
-
claude plugin marketplace add anthropics/claude-plugins-official
|
|
136
|
+
GIT_SSL_NO_VERIFY=$GIT_SSL_NO_VERIFY claude plugin marketplace add anthropics/claude-plugins-official
|
|
131
137
|
claude plugin install ralph-loop@claude-plugins-official
|
|
132
138
|
claude plugin install typescript-lsp@claude-plugins-official
|
|
133
139
|
claude plugin install pyright-lsp@claude-plugins-official
|
|
@@ -135,7 +141,7 @@ EOF
|
|
|
135
141
|
claude plugin install jdtls-lsp@claude-plugins-official
|
|
136
142
|
|
|
137
143
|
# 安装 Gemini CLI
|
|
138
|
-
case ",$
|
|
144
|
+
case ",$TOOL," in *,full,*|*,gemini,*)
|
|
139
145
|
npm install -g @google/gemini-cli
|
|
140
146
|
mkdir -p ~/.gemini/
|
|
141
147
|
cat > ~/.gemini/settings.json <<EOF
|
|
@@ -161,12 +167,12 @@ EOF
|
|
|
161
167
|
;; esac
|
|
162
168
|
|
|
163
169
|
# 安装 Codex CLI
|
|
164
|
-
case ",$
|
|
170
|
+
case ",$TOOL," in *,full,*|*,codex,*)
|
|
165
171
|
npm install -g @openai/codex
|
|
166
172
|
;; esac
|
|
167
173
|
|
|
168
174
|
# 安装 Copilot CLI
|
|
169
|
-
case ",$
|
|
175
|
+
case ",$TOOL," in *,full,*|*,copilot,*)
|
|
170
176
|
npm install -g @github/copilot
|
|
171
177
|
mkdir -p ~/.copilot/
|
|
172
178
|
cat > ~/.copilot/config.json <<EOF
|
|
@@ -181,7 +187,7 @@ EOF
|
|
|
181
187
|
;; esac
|
|
182
188
|
|
|
183
189
|
# 安装 OpenCode CLI
|
|
184
|
-
case ",$
|
|
190
|
+
case ",$TOOL," in *,full,*|*,opencode,*)
|
|
185
191
|
npm install -g opencode-ai
|
|
186
192
|
mkdir -p ~/.config/opencode/
|
|
187
193
|
cat > ~/.config/opencode/opencode.json <<EOF
|
|
@@ -221,7 +227,7 @@ COPY --from=cache-stage /opt/jdtls /root/.local/share/jdtls
|
|
|
221
227
|
|
|
222
228
|
RUN <<EOX
|
|
223
229
|
# 安装 java
|
|
224
|
-
case ",$
|
|
230
|
+
case ",$TOOL," in *,full,*|*,java,*)
|
|
225
231
|
apt-get update -y
|
|
226
232
|
apt-get install -y --no-install-recommends openjdk-21-jdk maven
|
|
227
233
|
|
|
@@ -239,7 +245,7 @@ COPY --from=cache-stage /opt/gopls /tmp/gopls-cache
|
|
|
239
245
|
|
|
240
246
|
RUN <<EOX
|
|
241
247
|
# 安装 go
|
|
242
|
-
case ",$
|
|
248
|
+
case ",$TOOL," in *,full,*|*,go,*)
|
|
243
249
|
apt-get update -y
|
|
244
250
|
apt-get install -y --no-install-recommends golang golang-src gcc
|
|
245
251
|
go env -w GOPROXY=https://mirrors.tencent.com/go
|
package/docs/README_EN.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
**<[English](README_EN.md)>** | [中文](../README.md)
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
@@ -50,24 +50,20 @@ After installing manyoyo, use the built-in command to build images:
|
|
|
50
50
|
podman pull ubuntu:24.04
|
|
51
51
|
|
|
52
52
|
# Build using manyoyo (Recommended, auto-cache enabled)
|
|
53
|
-
manyoyo --ib
|
|
54
|
-
manyoyo --ib common
|
|
55
|
-
manyoyo --ib go,codex,java,gemini
|
|
53
|
+
manyoyo --ib # Build full version by default (Recommended)
|
|
54
|
+
manyoyo --ib --iba TOOL=common # Build common version
|
|
55
|
+
manyoyo --ib --iba TOOL=go,codex,java,gemini # Build custom combination
|
|
56
|
+
manyoyo --ib --iba --iba GIT_SSL_NO_VERIFY=true # Build the full version and skip Git SSL verification
|
|
57
|
+
manyoyo --ib all --in myimage --iv 2.0.0 # Customize the image name and version to produce myimage:2.0.0-all
|
|
58
|
+
manyoyo --ip # Clean dangling images and <none> images
|
|
56
59
|
|
|
57
60
|
# How it works:
|
|
58
61
|
# - First build: Auto-downloads Node.js, JDT LSP, gopls etc. to docker/cache/
|
|
59
62
|
# - Rebuild within 2 days: Uses local cache, ~5x faster
|
|
60
63
|
# - After cache expires: Auto-downloads latest versions
|
|
61
64
|
|
|
62
|
-
# Custom image name and version
|
|
63
|
-
manyoyo --ib all --in myimage --iv 2.0.0
|
|
64
|
-
# Builds: myimage:2.0.0-all
|
|
65
|
-
|
|
66
|
-
# Clean images
|
|
67
|
-
manyoyo --ip # Clean dangling images and <none> images
|
|
68
|
-
|
|
69
65
|
# Or build manually (Not recommended)
|
|
70
|
-
iv=1.4.0 && podman build -t localhost/xcanwin/manyoyo:$iv-all -f docker/manyoyo.Dockerfile . --build-arg
|
|
66
|
+
iv=1.4.0 && podman build -t localhost/xcanwin/manyoyo:$iv-all -f docker/manyoyo.Dockerfile . --build-arg TOOL=all --no-cache
|
|
71
67
|
podman image prune -f
|
|
72
68
|
```
|
|
73
69
|
|
|
@@ -177,11 +173,10 @@ After exiting a container session, you'll be prompted with options:
|
|
|
177
173
|
# Create a container with Docker-in-Docker support
|
|
178
174
|
manyoyo -n docker-dev -m dind -x /bin/bash
|
|
179
175
|
|
|
180
|
-
#
|
|
181
|
-
nohup dockerd &
|
|
176
|
+
podman ps -a # Now you can use podman commands inside the container
|
|
182
177
|
|
|
183
|
-
|
|
184
|
-
docker ps -a
|
|
178
|
+
nohup dockerd & # Inside the container, start dockerd
|
|
179
|
+
docker ps -a # Now you can use docker commands inside the container
|
|
185
180
|
```
|
|
186
181
|
|
|
187
182
|
#### Mount Docker socket Development
|
|
@@ -189,10 +184,11 @@ docker ps -a
|
|
|
189
184
|
```bash
|
|
190
185
|
# Mount Docker socket (dangerous!!! containers can access and execute everything on the host)
|
|
191
186
|
# Create a container mounting /var/run/docker.sock
|
|
192
|
-
manyoyo -n socket-dev -m
|
|
187
|
+
manyoyo -n socket-dev -m sock -x /bin/bash
|
|
188
|
+
|
|
189
|
+
podman ps -a # Now you can use podman commands inside the container
|
|
193
190
|
|
|
194
|
-
# Now you can use docker commands inside the container
|
|
195
|
-
docker ps -a
|
|
191
|
+
docker ps -a # Now you can use docker commands inside the container
|
|
196
192
|
```
|
|
197
193
|
|
|
198
194
|
### Command-Line Options
|
|
@@ -214,8 +210,9 @@ docker ps -a
|
|
|
214
210
|
| `--` | `--ss`, `--shell-suffix` | Command arguments (suffix for -s) |
|
|
215
211
|
| `-x CMD` | `--sf`, `--shell-full` | Full command (replaces --sp, -s, and --) |
|
|
216
212
|
| `-y CLI` | `--yolo` | Run AI agent without confirmation |
|
|
217
|
-
| `-m MODE` | `--cm`, `--cont-mode` | Set container mode (common, dind,
|
|
218
|
-
| `--ib
|
|
213
|
+
| `-m MODE` | `--cm`, `--cont-mode` | Set container mode (common, dind, sock) |
|
|
214
|
+
| `--ib` | `--image-build` | Build image |
|
|
215
|
+
| `--iba` | `--image-build-arg` | Pass arguments to a Dockerfile during image build |
|
|
219
216
|
| `--ip` | `--image-prune` | Clean dangling images and `<none>` images |
|
|
220
217
|
| `--install NAME` | | Install manyoyo command |
|
|
221
218
|
| `-V` | `--version` | Show version |
|
|
@@ -232,8 +229,8 @@ docker ps -a
|
|
|
232
229
|
|
|
233
230
|
### Requirements
|
|
234
231
|
|
|
235
|
-
- Node.js >=
|
|
236
|
-
-
|
|
232
|
+
- Node.js >= 22.0.0
|
|
233
|
+
- Podman or Docker
|
|
237
234
|
|
|
238
235
|
### Uninstall
|
|
239
236
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcanwin/manyoyo",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"imageVersion": "1.6.
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"imageVersion": "1.6.3",
|
|
5
5
|
"description": "AI Agent CLI Security Sandbox",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai", "agent", "sandbox", "docker", "cli", "container", "development"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/xcanwin/manyoyo",
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=22.0.0"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"bin/manyoyo.js",
|