@xcanwin/manyoyo 3.4.0 → 3.4.5

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 CHANGED
@@ -50,24 +50,20 @@ npm install -g .
50
50
  podman pull ubuntu:24.04
51
51
 
52
52
  # 使用 manyoyo 构建镜像(推荐,自动使用缓存加速)
53
- manyoyo --ib all # 构建 all 版本(自动使用缓存,首次下载后 2 天内极速构建)
54
- manyoyo --ib common # 构建 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-all -f docker/manyoyo.Dockerfile . --build-arg EXT=all --no-cache
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
 
@@ -215,7 +211,8 @@ docker ps -a
215
211
  | `-x CMD` | `--sf`, `--shell-full` | 完整命令(替代 --sp, -s 和 --) |
216
212
  | `-y CLI` | `--yolo` | 无需确认运行 AI 智能体 |
217
213
  | `-m MODE` | `--cm`, `--cont-mode` | 设置容器模式(common, dind, mdsock) |
218
- | `--ib EXT` | `--image-build` | 构建镜像,EXT 为镜像变体,自动使用缓存加速 |
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` | 显示版本 |
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}-all`;
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 SHOULD_BUILD_IMAGE = false;
35
- let BUILD_IMAGE_EXT = "";
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 STRING 设置环境变量");
77
- console.log(" --ef|--env-file ENV_FILE 设置环境变量通过文件");
78
- console.log(" -v|--volume STRING 绑定挂载卷");
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, mdsock");
88
- console.log(" --ib|--image-build EXT 构建镜像,EXT 为镜像变体,逗号分割");
89
- console.log(" 例如 \"common\" (默认值), \"all\", \"go,codex,java,gemini\" ...");
90
- console.log(" (自动使用缓存加速,缓存过期后自动重新下载)");
91
- console.log(" --ip|--image-prune 清理悬空镜像和 <none> 镜像");
92
- console.log(" --install NAME 安装manyoyo命令");
93
- console.log(" 例如 docker-cli-plugin");
94
- console.log(" -V|--version 显示版本");
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, mdsock");
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 all 构建 all 版本镜像`);
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 指定命令执行`);
@@ -326,7 +325,7 @@ function pruneDanglingImages() {
326
325
  console.log(`${GREEN}✅ 清理完成${NC}`);
327
326
  }
328
327
 
329
- async function prepareBuildCache(ext) {
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 (ext === 'all' || ext.includes('java')) {
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 (ext === 'all' || ext.includes('go')) {
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
- async function buildImage(ext, imageName, imageVersion) {
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}-${ext}`;
490
+ const fullImageTag = `${imageName}:${version}-${imageTool}`;
482
491
 
483
492
  console.log(`${CYAN}🔨 正在构建镜像: ${YELLOW}${fullImageTag}${NC}`);
484
- console.log(`${BLUE}构建参数: EXT=${ext}${NC}\n`);
493
+ console.log(`${BLUE}构建组件类型: ${imageTool}${NC}\n`);
485
494
 
486
495
  // Prepare cache (自动检测并下载缺失的文件)
487
- await prepareBuildCache(ext);
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 buildCmd = `${DOCKER_CMD} build -t "${fullImageTag}" -f "${dockerfilePath}" "${path.join(__dirname, '..')}" --build-arg EXT=${ext} --no-cache`;
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}-${ext} -y c`);
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
- SHOULD_BUILD_IMAGE = true;
666
- BUILD_IMAGE_EXT = args[i + 1];
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 (SHOULD_BUILD_IMAGE) {
871
- await buildImage(BUILD_IMAGE_EXT, IMAGE_NAME, IMAGE_VERSION.split('-')[0]);
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 EXT="common"
62
+ ARG TOOL="full"
63
63
 
64
64
  RUN <<EOX
65
65
  # 部署 system
@@ -80,7 +80,7 @@ RUN <<EOX
80
80
  supervisor
81
81
 
82
82
  # 安装 docker
83
- case ",$EXT," in *,all,*|*,docker,*)
83
+ case ",$TOOL," in *,full,*|*,docker,*)
84
84
  apt-get install -y --no-install-recommends docker.io
85
85
  ;; esac
86
86
 
@@ -104,6 +104,7 @@ EOX
104
104
 
105
105
  # 从 cache-stage 复制 Node.js(缓存或下载)
106
106
  COPY --from=cache-stage /opt/node /usr/local
107
+ ARG GIT_SSL_NO_VERIFY=false
107
108
 
108
109
  RUN <<EOX
109
110
  # 配置 node.js
@@ -127,7 +128,7 @@ RUN <<EOX
127
128
  }
128
129
  }
129
130
  EOF
130
- claude plugin marketplace add anthropics/claude-plugins-official
131
+ GIT_SSL_NO_VERIFY=$GIT_SSL_NO_VERIFY claude plugin marketplace add anthropics/claude-plugins-official
131
132
  claude plugin install ralph-loop@claude-plugins-official
132
133
  claude plugin install typescript-lsp@claude-plugins-official
133
134
  claude plugin install pyright-lsp@claude-plugins-official
@@ -135,7 +136,7 @@ EOF
135
136
  claude plugin install jdtls-lsp@claude-plugins-official
136
137
 
137
138
  # 安装 Gemini CLI
138
- case ",$EXT," in *,all,*|*,gemini,*)
139
+ case ",$TOOL," in *,full,*|*,gemini,*)
139
140
  npm install -g @google/gemini-cli
140
141
  mkdir -p ~/.gemini/
141
142
  cat > ~/.gemini/settings.json <<EOF
@@ -161,12 +162,12 @@ EOF
161
162
  ;; esac
162
163
 
163
164
  # 安装 Codex CLI
164
- case ",$EXT," in *,all,*|*,codex,*)
165
+ case ",$TOOL," in *,full,*|*,codex,*)
165
166
  npm install -g @openai/codex
166
167
  ;; esac
167
168
 
168
169
  # 安装 Copilot CLI
169
- case ",$EXT," in *,all,*|*,copilot,*)
170
+ case ",$TOOL," in *,full,*|*,copilot,*)
170
171
  npm install -g @github/copilot
171
172
  mkdir -p ~/.copilot/
172
173
  cat > ~/.copilot/config.json <<EOF
@@ -181,7 +182,7 @@ EOF
181
182
  ;; esac
182
183
 
183
184
  # 安装 OpenCode CLI
184
- case ",$EXT," in *,all,*|*,opencode,*)
185
+ case ",$TOOL," in *,full,*|*,opencode,*)
185
186
  npm install -g opencode-ai
186
187
  mkdir -p ~/.config/opencode/
187
188
  cat > ~/.config/opencode/opencode.json <<EOF
@@ -221,7 +222,7 @@ COPY --from=cache-stage /opt/jdtls /root/.local/share/jdtls
221
222
 
222
223
  RUN <<EOX
223
224
  # 安装 java
224
- case ",$EXT," in *,all,*|*,java,*)
225
+ case ",$TOOL," in *,full,*|*,java,*)
225
226
  apt-get update -y
226
227
  apt-get install -y --no-install-recommends openjdk-21-jdk maven
227
228
 
@@ -239,7 +240,7 @@ COPY --from=cache-stage /opt/gopls /tmp/gopls-cache
239
240
 
240
241
  RUN <<EOX
241
242
  # 安装 go
242
- case ",$EXT," in *,all,*|*,go,*)
243
+ case ",$TOOL," in *,full,*|*,go,*)
243
244
  apt-get update -y
244
245
  apt-get install -y --no-install-recommends golang golang-src gcc
245
246
  go env -w GOPROXY=https://mirrors.tencent.com/go
package/docs/README_EN.md CHANGED
@@ -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 all # Build all version (auto-cache, blazing fast after first build within 2 days)
54
- manyoyo --ib common # Build common version
55
- manyoyo --ib go,codex,java,gemini # Build custom combination
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 EXT=all --no-cache
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
 
@@ -215,7 +211,8 @@ docker ps -a
215
211
  | `-x CMD` | `--sf`, `--shell-full` | Full command (replaces --sp, -s, and --) |
216
212
  | `-y CLI` | `--yolo` | Run AI agent without confirmation |
217
213
  | `-m MODE` | `--cm`, `--cont-mode` | Set container mode (common, dind, mdsock) |
218
- | `--ib EXT` | `--image-build` | Build image with auto-cache, EXT is image variant |
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 |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xcanwin/manyoyo",
3
- "version": "3.4.0",
4
- "imageVersion": "1.6.0",
3
+ "version": "3.4.5",
4
+ "imageVersion": "1.6.2",
5
5
  "description": "AI Agent CLI Security Sandbox",
6
6
  "keywords": [
7
7
  "ai", "agent", "sandbox", "docker", "cli", "container", "development"