@clawos-dev/clawd 0.2.234 → 0.2.235

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/dist/cli.cjs CHANGED
@@ -5745,8 +5745,10 @@ var init_contact = __esm({
5745
5745
  */
5746
5746
  sshAllowed: external_exports.boolean().default(false),
5747
5747
  /**
5748
- * 授权访问的目录白名单(绝对路径)。空数组 + sshAllowed=true 意味 SSH 通道能拨到但无处可读,
5749
- * jail 会拒绝 shell 启动。由 clawd-ssh-jail 运行时读,生成 sbpl / bwrap policy 白名单。
5748
+ * @deprecated T-29 去沙箱后废弃。原为授权访问的目录白名单(clawd-ssh-jail 生成 sbpl/bwrap
5749
+ * policy 用);去掉 OS 沙箱后不再有目录级限制,SSH 授权即 on/off(见 sshAllowed)。
5750
+ * 字段仅为兼容老 contacts.json 保留(default [] 保证 strict parse 不炸),不再有代码读写它,
5751
+ * 也不再进 setSshAccess RPC / ContactSettingsDrawer / jail。勿新增消费方。
5750
5752
  */
5751
5753
  exposedDirs: external_exports.array(external_exports.string()).default([])
5752
5754
  }).strict();
@@ -5795,14 +5797,12 @@ var init_contact_ssh = __esm({
5795
5797
  init_zod();
5796
5798
  ContactSetSshAccessArgsSchema = external_exports.object({
5797
5799
  deviceId: external_exports.string().min(1),
5798
- sshAllowed: external_exports.boolean(),
5799
- exposedDirs: external_exports.array(external_exports.string())
5800
+ sshAllowed: external_exports.boolean()
5800
5801
  }).strict();
5801
5802
  ContactSetSshAccessOkSchema = external_exports.object({
5802
5803
  type: external_exports.literal("contact:setSshAccess:ok"),
5803
5804
  deviceId: external_exports.string().min(1),
5804
- sshAllowed: external_exports.boolean(),
5805
- exposedDirs: external_exports.array(external_exports.string())
5805
+ sshAllowed: external_exports.boolean()
5806
5806
  }).strict();
5807
5807
  ContactSshKeyIssueArgsSchema = external_exports.object({
5808
5808
  deviceId: external_exports.string().min(1)
@@ -5815,8 +5815,7 @@ var init_contact_ssh = __esm({
5815
5815
  ContactSshAccessUpdatedFrameSchema = external_exports.object({
5816
5816
  type: external_exports.literal("contact:ssh-access-updated"),
5817
5817
  deviceId: external_exports.string().min(1),
5818
- sshAllowed: external_exports.boolean(),
5819
- exposedDirs: external_exports.array(external_exports.string())
5818
+ sshAllowed: external_exports.boolean()
5820
5819
  }).strict();
5821
5820
  }
5822
5821
  });
@@ -41995,10 +41994,10 @@ var CONTACT_SSH_SYSTEM_PROMPT_HINT = `## \u8DE8\u8BBE\u5907\u6587\u4EF6\u8BBF\u9
41995
41994
  # execPath+cliPath\uFF0C\u4FDD\u8BC1 relay \u8DDF daemon \u7248\u672C\u540C\u6B65\u3002\u4E0D\u8981\u7528\u88F8 \`clawd\`\uFF08\u8D70 $PATH \u4F1A\u6F02\uFF09\u3002
41996
41995
  \`\`\`
41997
41996
 
41998
- **A \u5EFA\u8BAE\u5728\u54EA\u4E9B\u76EE\u5F55\u5E72\u6D3B**\uFF1AA \u4FA7 jail \u8FDB shell \u524D\u4F1A\u628A\u5EFA\u8BAE\u76EE\u5F55\u5217\u8868\u5199\u5230 stderr\uFF08\u683C\u5F0F \`[clawd-ssh-jail] Suggested working directories for this contact: ...\`\uFF09\u4F5C\u4E3A\u53C2\u8003\u3002\u6CE8\u610F\uFF1A**\u6CA1\u6709\u76EE\u5F55\u7EA7\u5F3A\u5236\u9650\u5236**\u2014\u2014\u4F60\u8BBF\u95EE\u7684\u662F A \u673A\u5668\u4E0A\u8BE5 SSH \u7528\u6237\u6743\u9650\u5185\u7684\u6587\u4EF6\uFF0C\u8BF7\u53EA\u5728 A \u6388\u6743/\u9700\u8981\u7684\u8303\u56F4\u5185\u64CD\u4F5C\uFF0C\u4E0D\u8981\u8D8A\u754C\u7FFB\u770B\u65E0\u5173\u76EE\u5F55\u3002
41997
+ **\u4F60\u80FD\u8BBF\u95EE\u4EC0\u4E48**\uFF1A**\u6CA1\u6709\u76EE\u5F55\u7EA7\u9650\u5236**\u2014\u2014\u4F60\u4EE5 A \u673A\u5668\u4E0A\u8BE5 SSH \u7528\u6237\u7684\u6743\u9650\u8BBF\u95EE\u6587\u4EF6\uFF08\u7B49\u540C\u4E8E A \u7ED9\u4F60\u5F00\u4E86\u4E00\u4E2A shell\uFF09\u3002\u8BF7\u53EA\u5728 A \u6388\u6743/\u9700\u8981\u7684\u8303\u56F4\u5185\u64CD\u4F5C\uFF0C\u4E0D\u8981\u8D8A\u754C\u7FFB\u770B\u65E0\u5173\u76EE\u5F55\u3002
41999
41998
 
42000
41999
  **\u6CE8\u610F**\uFF1A
42001
- - \u5EFA\u8BAE\u76EE\u5F55\u6570\u636E\u6E90\u5B9E\u65F6\uFF08jail \u6BCF\u6B21\u8BFB A \u4FA7\u6700\u65B0\u914D\u7F6E\uFF09\uFF0CA \u6539\u4E86 exposedDirs \u540E\u4F60\u4E0B\u4E00\u6B21\u62E8\u53F7\u7ACB\u5373\u611F\u77E5
42000
+ - \u6388\u6743\u662F\u5B9E\u65F6\u7684\uFF1AA \u64A4\u9500 sshAllowed \u540E\u4F60\u4E0B\u4E00\u6B21\u62E8\u53F7\u7ACB\u5373\u5931\u6548\uFF08authorized_keys \u7ACB\u5373\u5237\uFF09
42002
42001
  - \u6392\u969C\uFF1A\u672C\u673A debug \u65E5\u5FD7\u5728 \`~/.clawd/log/contact-ssh.log\`\uFF08\u7528\u6237\u53EF \`tail -f\` \u770B\u6BCF\u4E00\u6B65\uFF09\uFF0C\u4F60\u51FA\u9519\u65F6\u544A\u8BC9\u7528\u6237\u67E5\u8FD9\u4E2A\u6587\u4EF6
42003
42002
  - \u5982\u679C \`ls ~/.clawd/contact-ssh-keys/\` \u4E3A\u7A7A\uFF0C\u8BF4\u660E\u8FD8\u6CA1\u6709\u5BF9\u7AEF\u6388\u6743\u4F60\u6216 key \u8FD8\u6CA1\u62C9\u5230\uFF08B \u4FA7 daemon \u6BCF 60s \u4E00\u6B21\u81EA\u52A8\u62C9\uFF09\uFF0C\u5982\u5B9E\u544A\u8BC9\u7528\u6237
42004
42003
  `;
@@ -51213,9 +51212,8 @@ var ContactStore = class {
51213
51212
  return true;
51214
51213
  }
51215
51214
  /**
51216
- * 更新单条 contact 的 SSH 授权(PR: contact-ssh-sandbox)。对齐 setPin pattern:
51217
- * store 只做原始 mutation,不做业务校验(如"sshAllowed=false 时清空 exposedDirs")——
51218
- * 那是 handler / UI 的责任。数组语义是完全替换(不 append)。
51215
+ * 更新单条 contact 的 SSH 授权开关(对齐 setPin pattern)。T-29 去沙箱后只改 sshAllowed;
51216
+ * exposedDirs 已废弃,本方法不再触碰它(保留 contact 原值不动)。
51219
51217
  * @returns 是否命中:deviceId 不存在返 false;命中即 flush.
51220
51218
  */
51221
51219
  setSshAccess(deviceId, opts) {
@@ -51223,8 +51221,7 @@ var ContactStore = class {
51223
51221
  if (!existing) return false;
51224
51222
  this.contacts.set(deviceId, {
51225
51223
  ...existing,
51226
- sshAllowed: opts.sshAllowed,
51227
- exposedDirs: opts.exposedDirs
51224
+ sshAllowed: opts.sshAllowed
51228
51225
  });
51229
51226
  this.flush();
51230
51227
  return true;
@@ -53533,8 +53530,8 @@ var CLAWD_SSH_JAIL_SCRIPT = String.raw`#!/usr/bin/env bash
53533
53530
  # 真实请求(interactive shell 时为空)。
53534
53531
  #
53535
53532
  # 职责:
53536
- # 1. 读 ~/.clawd/contacts.json 校验 contact.sshAllowed,读 exposedDirs 作为提示
53537
- # 2. 直接 exec shell(去沙箱后无目录级限制;exposedDirs 仅 echo 给对端参考)
53533
+ # 1. 读 ~/.clawd/contacts.json 校验 contact.sshAllowed(不通过即拒)
53534
+ # 2. 直接 exec shell(去沙箱后无目录级限制)
53538
53535
 
53539
53536
  set -euo pipefail
53540
53537
 
@@ -53561,13 +53558,15 @@ log_line INFO jail.entered "clawd-ssh-jail 起来 device=${"${DEVICE_ID}"} cmd=$
53561
53558
 
53562
53559
  CONTACTS="${"${HOME}"}/.clawd/contacts.json"
53563
53560
  if [ ! -f "$CONTACTS" ]; then
53564
- log_line ERROR jail.entered "contacts.json 不存在,无法查 exposedDirs"
53561
+ log_line ERROR jail.entered "contacts.json 不存在,无法校验 sshAllowed"
53565
53562
  echo "clawd-ssh-jail: contacts.json missing" >&2
53566
53563
  exit 1
53567
53564
  fi
53568
53565
 
53569
- # contact 的 exposedDirs (mac/linux 都自带 python3)
53570
- EXPOSED_JSON=$(python3 -c "
53566
+ # 校验该 contact 的 sshAllowed(mac/linux 都自带 python3)。去沙箱后不再读目录白名单:
53567
+ # sshAllowed=false DENIED exit 2;deviceId 未命中 → NOT_FOUND exit 3;命中且允许 → exit 0。
53568
+ # set -e 下 python 非 0 退出即终止脚本(不进 exec),只有 exit 0 才继续 exec shell。
53569
+ python3 -c "
53571
53570
  import json, sys
53572
53571
  with open('$CONTACTS') as f:
53573
53572
  data = json.load(f)
@@ -53575,25 +53574,11 @@ for c in data.get('contacts', []):
53575
53574
  if c.get('deviceId') == '$DEVICE_ID':
53576
53575
  if not c.get('sshAllowed'):
53577
53576
  print('DENIED', file=sys.stderr); sys.exit(2)
53578
- for d in c.get('exposedDirs', []):
53579
- print(d)
53580
53577
  sys.exit(0)
53581
- sys.exit(3)
53582
- ")
53583
-
53584
- # exposedDirs 可能为空(sshAllowed=true 但未配目录)——去沙箱后不再因空目录拒绝,直接放行。
53585
- if [ -n "$EXPOSED_JSON" ]; then
53586
- log_line INFO jail.entered "exposedDirs 提示已加载,放行 exec shell"
53587
- # 告知 SSH client 建议目录(发到 stderr)。去沙箱后这些只是建议,不做目录级强制限制;
53588
- # exposedDirs 仅供对端参考,运行时读,A 改后下次拨号即感知。
53589
- echo "[clawd-ssh-jail] Suggested working directories for this contact:" >&2
53590
- while IFS= read -r d; do
53591
- echo " - $d" >&2
53592
- done <<< "$EXPOSED_JSON"
53593
- echo "[clawd-ssh-jail] Note: no directory-level restriction is enforced." >&2
53594
- else
53595
- log_line INFO jail.entered "sshAllowed=true 且未配 exposedDirs,直接放行 exec shell"
53596
- fi
53578
+ print('NOT_FOUND', file=sys.stderr); sys.exit(3)
53579
+ "
53580
+
53581
+ log_line INFO jail.entered "sshAllowed 校验通过,放行 exec shell"
53597
53582
 
53598
53583
  CMD="${"${SSH_ORIGINAL_COMMAND:-}"}"
53599
53584
  if [ -z "$CMD" ]; then
@@ -56066,8 +56051,7 @@ function buildContactSshHandlers(deps) {
56066
56051
  const { type: _t, requestId: _r, ...rest } = frame;
56067
56052
  const args = ContactSetSshAccessArgsSchema.parse(rest);
56068
56053
  const hit = deps.store.setSshAccess(args.deviceId, {
56069
- sshAllowed: args.sshAllowed,
56070
- exposedDirs: args.exposedDirs
56054
+ sshAllowed: args.sshAllowed
56071
56055
  });
56072
56056
  if (!hit) {
56073
56057
  sshLog.warn("authz.setSshAccess", "owner \u5C1D\u8BD5\u6539 SSH \u6388\u6743\u4F46 contact \u4E0D\u5728 store", {
@@ -56081,21 +56065,18 @@ function buildContactSshHandlers(deps) {
56081
56065
  rebuildAuthorizedKeys(deps.store, deps.sshdDir);
56082
56066
  sshLog.info("authz.setSshAccess", "owner \u6539\u4E86 SSH \u6388\u6743 \u2192 authorized_keys \u5DF2\u91CD\u5EFA", {
56083
56067
  peerDeviceId: args.deviceId,
56084
- sshAllowed: args.sshAllowed,
56085
- exposedDirs: args.exposedDirs
56068
+ sshAllowed: args.sshAllowed
56086
56069
  });
56087
56070
  deps.broadcast({
56088
56071
  type: "contact:ssh-access-updated",
56089
56072
  deviceId: args.deviceId,
56090
- sshAllowed: args.sshAllowed,
56091
- exposedDirs: args.exposedDirs
56073
+ sshAllowed: args.sshAllowed
56092
56074
  });
56093
56075
  return {
56094
56076
  response: {
56095
56077
  type: "contact:setSshAccess:ok",
56096
56078
  deviceId: args.deviceId,
56097
- sshAllowed: args.sshAllowed,
56098
- exposedDirs: args.exposedDirs
56079
+ sshAllowed: args.sshAllowed
56099
56080
  }
56100
56081
  };
56101
56082
  };
@@ -40755,8 +40755,10 @@ var ContactSchema = external_exports.object({
40755
40755
  */
40756
40756
  sshAllowed: external_exports.boolean().default(false),
40757
40757
  /**
40758
- * 授权访问的目录白名单(绝对路径)。空数组 + sshAllowed=true 意味 SSH 通道能拨到但无处可读,
40759
- * jail 会拒绝 shell 启动。由 clawd-ssh-jail 运行时读,生成 sbpl / bwrap policy 白名单。
40758
+ * @deprecated T-29 去沙箱后废弃。原为授权访问的目录白名单(clawd-ssh-jail 生成 sbpl/bwrap
40759
+ * policy 用);去掉 OS 沙箱后不再有目录级限制,SSH 授权即 on/off(见 sshAllowed)。
40760
+ * 字段仅为兼容老 contacts.json 保留(default [] 保证 strict parse 不炸),不再有代码读写它,
40761
+ * 也不再进 setSshAccess RPC / ContactSettingsDrawer / jail。勿新增消费方。
40760
40762
  */
40761
40763
  exposedDirs: external_exports.array(external_exports.string()).default([])
40762
40764
  }).strict();
@@ -40798,14 +40800,12 @@ var ContactPinnedFrameSchema = external_exports.object({
40798
40800
  // ../protocol/src/contact-ssh.ts
40799
40801
  var ContactSetSshAccessArgsSchema = external_exports.object({
40800
40802
  deviceId: external_exports.string().min(1),
40801
- sshAllowed: external_exports.boolean(),
40802
- exposedDirs: external_exports.array(external_exports.string())
40803
+ sshAllowed: external_exports.boolean()
40803
40804
  }).strict();
40804
40805
  var ContactSetSshAccessOkSchema = external_exports.object({
40805
40806
  type: external_exports.literal("contact:setSshAccess:ok"),
40806
40807
  deviceId: external_exports.string().min(1),
40807
- sshAllowed: external_exports.boolean(),
40808
- exposedDirs: external_exports.array(external_exports.string())
40808
+ sshAllowed: external_exports.boolean()
40809
40809
  }).strict();
40810
40810
  var ContactSshKeyIssueArgsSchema = external_exports.object({
40811
40811
  deviceId: external_exports.string().min(1)
@@ -40818,8 +40818,7 @@ var ContactSshKeyIssueOkSchema = external_exports.object({
40818
40818
  var ContactSshAccessUpdatedFrameSchema = external_exports.object({
40819
40819
  type: external_exports.literal("contact:ssh-access-updated"),
40820
40820
  deviceId: external_exports.string().min(1),
40821
- sshAllowed: external_exports.boolean(),
40822
- exposedDirs: external_exports.array(external_exports.string())
40821
+ sshAllowed: external_exports.boolean()
40823
40822
  }).strict();
40824
40823
 
40825
40824
  // ../protocol/src/extension.ts