@clawos-dev/clawd 0.2.151 → 0.2.152-beta.320.c7b0769

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +20 -65
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -4536,6 +4536,9 @@ var init_persona_schemas = __esm({
4536
4536
  enabled: external_exports.boolean().optional(),
4537
4537
  autoAllowBashIfSandboxed: external_exports.boolean().optional(),
4538
4538
  allowUnsandboxedCommands: external_exports.boolean().optional(),
4539
+ // 命令前缀白名单(CC `sandbox.excludedCommands`):匹配的命令在沙箱外运行,
4540
+ // 用于需逃出沙箱的工具(如 'docker *' / 'aliyun *' 要访问宿主 socket / 凭证)。
4541
+ excludedCommands: external_exports.array(external_exports.string()).optional(),
4539
4542
  filesystem: external_exports.object({
4540
4543
  denyRead: external_exports.array(external_exports.string()).optional(),
4541
4544
  allowRead: external_exports.array(external_exports.string()).optional(),
@@ -32009,6 +32012,9 @@ function applyProfile(base, profile) {
32009
32012
  if (pn.allowedDomains) n.allowedDomains = unionArr(n.allowedDomains, pn.allowedDomains);
32010
32013
  if (pn.allowLocalBinding !== void 0) n.allowLocalBinding = pn.allowLocalBinding;
32011
32014
  }
32015
+ if (profile.sandbox?.excludedCommands) {
32016
+ base.sandbox.excludedCommands = unionArr(base.sandbox.excludedCommands, profile.sandbox.excludedCommands);
32017
+ }
32012
32018
  return base;
32013
32019
  }
32014
32020
  function composeGuestSandbox(base, userWorkDir, spawnCwd) {
@@ -35695,34 +35701,11 @@ var DEFAULT_PERSONAS = [
35695
35701
  model: "opus",
35696
35702
  iconKey: "doc",
35697
35703
  public: false,
35698
- // app-builder 对齐"调用阿里云的工作方式"owner 2026-06-17 要求):开发型 profile —— 放开文件/web
35699
- // 工具 + node/pnpm 工具链精确路径 + 出站 TLD 通配白名单。html-slides 需要联网(git clone frontend-slides
35700
- // skill、调阿里云 CLI/SDK)。
35701
- // 阿里云凭证:**复用共享 deploy-kit 单源**($HOME/.clawd/deploy-kit/.secrets/aliyun.env,全 FC persona 共用、
35702
- // seedDeployKit 每次安装都铺),不在 persona 目录另存一份。app-builder 的 FC 部署走 daemon 侧脚本(沙箱外)
35703
- // 故其 profile 无需 carve 这个路径;html-slides 没有 daemon 侧流程、要在 cc 沙箱内直接 `set -a; . $HOME/.clawd/
35704
- // deploy-kit/.secrets/aliyun.env; set +a` 后调 aliyun CLI(env 凭证绕过沙箱外的 ~/.aliyun/),所以这里**额外**把
35705
- // 这个凭证文件加进 allowRead(denyRead '~/' 之上的精确凿洞,单文件、最小暴露,同 ~/.npmrc 先例)。
35704
+ // DEFAULT_BYPASS_PROFILEbypassPermissions + 最严格沙箱),额外把 aliyun CLI 放沙箱外跑:
35705
+ // 上传 HTML 演示稿到 OSS aliyun 读宿主凭证 / 外联,沙箱内会被拦。
35706
35706
  sandboxProfile: {
35707
- permissions: {
35708
- defaultMode: "bypassPermissions",
35709
- allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"]
35710
- },
35711
- sandbox: {
35712
- filesystem: {
35713
- allowRead: ["~/.npmrc", "~/Library/Preferences/pnpm", "~/.nvm", "~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store", "~/.clawd/deploy-kit/.secrets/aliyun.env"],
35714
- allowWrite: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"]
35715
- },
35716
- network: {
35717
- allowedDomains: ["*.com", "*.org", "*.io", "*.net", "*.dev", "*.app", "*.cn", "*.co", "*.chat", "*.ai"],
35718
- allowLocalBinding: true
35719
- }
35720
- }
35721
- },
35722
- codexSandbox: {
35723
- writableRoots: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"],
35724
- denyRead: [".secrets/**"],
35725
- network: true
35707
+ permissions: { defaultMode: "bypassPermissions" },
35708
+ sandbox: { excludedCommands: ["aliyun *"] }
35726
35709
  }
35727
35710
  }
35728
35711
  ];
@@ -37189,68 +37172,40 @@ function observeReady(surface, opts) {
37189
37172
  }
37190
37173
  };
37191
37174
  }
37192
- var BYPASS_SETTLE_MS = 300;
37193
37175
  function createBootGate(pty, logger) {
37194
37176
  const stripAnsi = (s) => s.replace(/\x1b\[[0-9;?]*C/g, " ").replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, "").replace(/\x1b\][^\x07]*\x07/g, "").replace(/\x1b[NOPM=>78]/g, "").replace(/[\x00-\x1f\x7f]/g, " ");
37195
37177
  const popups = {
37196
- trust: {
37197
- handled: false,
37198
- fired: false,
37199
- timer: void 0,
37200
- regex: /trust\s*this\s*folder/i,
37201
- accept: "\r",
37202
- settleMs: 0,
37203
- label: "trust-folder"
37204
- },
37178
+ trust: { handled: false, regex: /trust this folder/i, accept: "\r", label: "trust-folder" },
37205
37179
  bypass: {
37206
37180
  handled: false,
37207
- fired: false,
37208
- timer: void 0,
37209
- regex: /Bypass\s*Permissions\s*mode|By\s*proceeding/i,
37181
+ regex: /Bypass Permissions mode|By proceeding/i,
37210
37182
  accept: "2\r",
37211
- settleMs: BYPASS_SETTLE_MS,
37212
37183
  label: "bypass-warning"
37213
37184
  }
37214
37185
  };
37215
37186
  let scanBuf = "";
37216
- const press = (popup) => {
37217
- popup.fired = true;
37218
- logger?.debug(`${popup.label} popup auto-yes`);
37219
- try {
37220
- pty.write(popup.accept);
37221
- } catch (err) {
37222
- logger?.warn(`${popup.label} auto-yes write failed`, {
37223
- error: err.message
37224
- });
37225
- }
37226
- };
37227
- let disposed = false;
37228
37187
  return {
37229
37188
  feedBytes(data) {
37230
- if (disposed) return;
37231
37189
  scanBuf += data.toString("utf8");
37232
37190
  const cleanBuf = stripAnsi(scanBuf).replace(/\s+/g, " ");
37233
37191
  for (const popup of Object.values(popups)) {
37234
37192
  if (popup.handled) continue;
37235
37193
  if (popup.regex.test(cleanBuf)) {
37236
37194
  popup.handled = true;
37195
+ logger?.debug(`${popup.label} popup auto-yes`);
37196
+ try {
37197
+ pty.write(popup.accept);
37198
+ } catch (err) {
37199
+ logger?.warn(`${popup.label} auto-yes write failed`, {
37200
+ error: err.message
37201
+ });
37202
+ }
37237
37203
  scanBuf = "";
37238
- if (popup.settleMs === 0) press(popup);
37239
- }
37240
- }
37241
- for (const popup of Object.values(popups)) {
37242
- if (popup.handled && popup.settleMs > 0 && !popup.fired) {
37243
- if (popup.timer) clearTimeout(popup.timer);
37244
- popup.timer = setTimeout(() => press(popup), popup.settleMs);
37245
37204
  }
37246
37205
  }
37247
37206
  if (scanBuf.length > 8192) scanBuf = scanBuf.slice(-4096);
37248
37207
  },
37249
37208
  dispose() {
37250
- disposed = true;
37251
- for (const popup of Object.values(popups)) {
37252
- if (popup.timer) clearTimeout(popup.timer);
37253
- }
37254
37209
  }
37255
37210
  };
37256
37211
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.151",
3
+ "version": "0.2.152-beta.320.c7b0769",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",