@clawos-dev/clawd 0.2.250 → 0.2.251

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.
@@ -3227,8 +3227,8 @@ var require_utils = __commonJS({
3227
3227
  }
3228
3228
  return ind;
3229
3229
  }
3230
- function removeDotSegments(path2) {
3231
- let input = path2;
3230
+ function removeDotSegments(path4) {
3231
+ let input = path4;
3232
3232
  const output = [];
3233
3233
  let nextSlash = -1;
3234
3234
  let len = 0;
@@ -3480,8 +3480,8 @@ var require_schemes = __commonJS({
3480
3480
  wsComponent.secure = void 0;
3481
3481
  }
3482
3482
  if (wsComponent.resourceName) {
3483
- const [path2, query] = wsComponent.resourceName.split("?");
3484
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3483
+ const [path4, query] = wsComponent.resourceName.split("?");
3484
+ wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
3485
3485
  wsComponent.query = query;
3486
3486
  wsComponent.resourceName = void 0;
3487
3487
  }
@@ -6874,12 +6874,12 @@ var require_dist = __commonJS({
6874
6874
  throw new Error(`Unknown format "${name}"`);
6875
6875
  return f;
6876
6876
  };
6877
- function addFormats(ajv, list, fs4, exportName) {
6877
+ function addFormats(ajv, list, fs6, exportName) {
6878
6878
  var _a;
6879
6879
  var _b;
6880
6880
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6881
6881
  for (const f of list)
6882
- ajv.addFormat(f, fs4[f]);
6882
+ ajv.addFormat(f, fs6[f]);
6883
6883
  }
6884
6884
  module2.exports = exports2 = formatsPlugin;
6885
6885
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6895,7 +6895,7 @@ __export(mcp_server_exports, {
6895
6895
  handlePersonaDispatchToolCall: () => handlePersonaDispatchToolCall
6896
6896
  });
6897
6897
  module.exports = __toCommonJS(mcp_server_exports);
6898
- var import_node_fs3 = __toESM(require("fs"), 1);
6898
+ var import_node_fs5 = __toESM(require("fs"), 1);
6899
6899
 
6900
6900
  // ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
6901
6901
  var external_exports = {};
@@ -7375,8 +7375,8 @@ function getErrorMap() {
7375
7375
 
7376
7376
  // ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
7377
7377
  var makeIssue = (params) => {
7378
- const { data, path: path2, errorMaps, issueData } = params;
7379
- const fullPath = [...path2, ...issueData.path || []];
7378
+ const { data, path: path4, errorMaps, issueData } = params;
7379
+ const fullPath = [...path4, ...issueData.path || []];
7380
7380
  const fullIssue = {
7381
7381
  ...issueData,
7382
7382
  path: fullPath
@@ -7492,11 +7492,11 @@ var errorUtil;
7492
7492
 
7493
7493
  // ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
7494
7494
  var ParseInputLazyPath = class {
7495
- constructor(parent, value, path2, key) {
7495
+ constructor(parent, value, path4, key) {
7496
7496
  this._cachedPath = [];
7497
7497
  this.parent = parent;
7498
7498
  this.data = value;
7499
- this._path = path2;
7499
+ this._path = path4;
7500
7500
  this._key = key;
7501
7501
  }
7502
7502
  get path() {
@@ -11133,10 +11133,10 @@ function assignProp(target, prop, value) {
11133
11133
  configurable: true
11134
11134
  });
11135
11135
  }
11136
- function getElementAtPath(obj, path2) {
11137
- if (!path2)
11136
+ function getElementAtPath(obj, path4) {
11137
+ if (!path4)
11138
11138
  return obj;
11139
- return path2.reduce((acc, key) => acc?.[key], obj);
11139
+ return path4.reduce((acc, key) => acc?.[key], obj);
11140
11140
  }
11141
11141
  function promiseAllObject(promisesObj) {
11142
11142
  const keys = Object.keys(promisesObj);
@@ -11456,11 +11456,11 @@ function aborted(x, startIndex = 0) {
11456
11456
  }
11457
11457
  return false;
11458
11458
  }
11459
- function prefixIssues(path2, issues) {
11459
+ function prefixIssues(path4, issues) {
11460
11460
  return issues.map((iss) => {
11461
11461
  var _a;
11462
11462
  (_a = iss).path ?? (_a.path = []);
11463
- iss.path.unshift(path2);
11463
+ iss.path.unshift(path4);
11464
11464
  return iss;
11465
11465
  });
11466
11466
  }
@@ -22904,11 +22904,11 @@ Diff.prototype = {
22904
22904
  }
22905
22905
  }
22906
22906
  },
22907
- addToPath: function addToPath(path2, added, removed, oldPosInc, options) {
22908
- var last = path2.lastComponent;
22907
+ addToPath: function addToPath(path4, added, removed, oldPosInc, options) {
22908
+ var last = path4.lastComponent;
22909
22909
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
22910
22910
  return {
22911
- oldPos: path2.oldPos + oldPosInc,
22911
+ oldPos: path4.oldPos + oldPosInc,
22912
22912
  lastComponent: {
22913
22913
  count: last.count + 1,
22914
22914
  added,
@@ -22918,7 +22918,7 @@ Diff.prototype = {
22918
22918
  };
22919
22919
  } else {
22920
22920
  return {
22921
- oldPos: path2.oldPos + oldPosInc,
22921
+ oldPos: path4.oldPos + oldPosInc,
22922
22922
  lastComponent: {
22923
22923
  count: 1,
22924
22924
  added,
@@ -23413,6 +23413,80 @@ var CLAUDE_CAPABILITIES = {
23413
23413
  ]
23414
23414
  };
23415
23415
 
23416
+ // src/tools/codex.ts
23417
+ var import_node_child_process5 = require("child_process");
23418
+ var import_node_fs4 = __toESM(require("fs"), 1);
23419
+
23420
+ // src/tools/codex-session.ts
23421
+ var import_node_child_process4 = require("child_process");
23422
+ var import_node_path3 = __toESM(require("path"), 1);
23423
+
23424
+ // src/tools/codex-app-server-client.ts
23425
+ var import_node_readline = require("readline");
23426
+
23427
+ // src/tools/codex-mcp-config.ts
23428
+ var import_node_fs3 = __toESM(require("fs"), 1);
23429
+ var import_node_path2 = __toESM(require("path"), 1);
23430
+
23431
+ // src/tools/codex-features.ts
23432
+ var import_node_child_process3 = require("child_process");
23433
+
23434
+ // src/tools/codex.ts
23435
+ var CODEX_MODEL_IDS = ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"];
23436
+ var CODEX_MODELS = [
23437
+ { id: "", label: "Default", description: "codex config.toml \u9ED8\u8BA4", contextWindowSize: 258400, default: true },
23438
+ { id: "gpt-5.5", label: "GPT-5.5", description: "Frontier model for complex coding", contextWindowSize: 258400 },
23439
+ { id: "gpt-5.4", label: "GPT-5.4", contextWindowSize: 258400 },
23440
+ { id: "gpt-5.4-mini", label: "GPT-5.4-Mini", contextWindowSize: 258400 }
23441
+ ];
23442
+ var CODEX_EFFORTS = [
23443
+ { value: "low", label: "Low", description: "Fast responses with lighter reasoning" },
23444
+ { value: "medium", label: "Medium", description: "Balances speed and reasoning depth for everyday tasks" },
23445
+ { value: "high", label: "High", description: "Greater reasoning depth for complex problems" },
23446
+ { value: "xhigh", label: "Extra high", description: "Extra high reasoning depth for complex problems" }
23447
+ ];
23448
+ var CODEX_APPROVAL_PRESETS = [
23449
+ { id: "untrusted", label: "Ask for approval", description: "\u51E0\u4E4E\u6BCF\u6761\u547D\u4EE4\u90FD\u95EE\u4F60\uFF08\u6700\u8C28\u614E\uFF09" },
23450
+ { id: "on-request", label: "Approve for me", description: "\u6A21\u578B\u81EA\u5DF1\u5224\u65AD\uFF0C\u53EA\u5BF9\u9AD8\u98CE\u9669\u64CD\u4F5C\u95EE\u4F60\uFF08\u9ED8\u8BA4\uFF09" },
23451
+ { id: "never", label: "Full Access", description: "\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" }
23452
+ ];
23453
+ var CODEX_CAPABILITIES = {
23454
+ tool: "codex",
23455
+ toolSessionIdLabel: "Codex Thread ID",
23456
+ models: CODEX_MODELS,
23457
+ permissionModes: CODEX_APPROVAL_PRESETS,
23458
+ // codex 不支持这些 clawd 功能(rewind 无 file-snapshot / 无子 agent / 无 TUI pty /
23459
+ // 无 observe 推送 / 无文件分享 / fork 是 claude jsonl 专用);UI 据此 gate 入口。
23460
+ features: { rewind: false, subagents: false, tui: false, observe: false, fileSharing: false, fork: false },
23461
+ configSchema: [
23462
+ {
23463
+ name: "model",
23464
+ type: "select",
23465
+ label: "Model",
23466
+ scope: "core",
23467
+ options: CODEX_MODELS.map((m) => ({ value: m.id, label: m.label, description: m.description })),
23468
+ default: ""
23469
+ },
23470
+ {
23471
+ name: "permissionMode",
23472
+ type: "select",
23473
+ label: "Approval",
23474
+ scope: "core",
23475
+ options: CODEX_APPROVAL_PRESETS.map((m) => ({ value: m.id, label: m.label, description: m.description })),
23476
+ default: "on-request"
23477
+ },
23478
+ {
23479
+ name: "effort",
23480
+ type: "select",
23481
+ label: "Reasoning effort",
23482
+ scope: "tool-specific",
23483
+ // 渲染在 Advanced 区(与 claude effort 一致)
23484
+ options: CODEX_EFFORTS,
23485
+ default: "medium"
23486
+ }
23487
+ ]
23488
+ };
23489
+
23416
23490
  // src/dispatch/mcp-server.ts
23417
23491
  var DISPATCH_LOG = process.env.CLAWD_DISPATCH_LOG;
23418
23492
  function log(msg, info) {
@@ -23420,7 +23494,7 @@ function log(msg, info) {
23420
23494
  `;
23421
23495
  if (DISPATCH_LOG) {
23422
23496
  try {
23423
- import_node_fs3.default.appendFileSync(DISPATCH_LOG, line);
23497
+ import_node_fs5.default.appendFileSync(DISPATCH_LOG, line);
23424
23498
  return;
23425
23499
  } catch {
23426
23500
  }
@@ -23648,9 +23722,10 @@ async function main() {
23648
23722
  "contact deviceId of the remote device when delegating cross-device (omit for a local persona)"
23649
23723
  ),
23650
23724
  // T-20: dispatch model override. Enum 走 MCP tool JSON schema 硬约束,
23651
- // caller LLM 只能从可选值挑,避免瞎填历史模型名。
23652
- model: external_exports.enum(CLAUDE_MODEL_IDS).optional().describe(
23653
- "override the target persona's default claude model. Omit to use the persona default. Allowed: " + CLAUDE_MODEL_IDS.join(" / ") + "."
23725
+ // caller LLM 只能从可选值挑,避免瞎填历史模型名。claude / codex 两表 union——
23726
+ // 精确校验(按 target persona tool 选表)在 daemon handler 层做(fail-fast)。
23727
+ model: external_exports.enum([...CLAUDE_MODEL_IDS, ...CODEX_MODEL_IDS]).optional().describe(
23728
+ "override the target persona's default model. Omit to use the persona default. Claude personas: " + CLAUDE_MODEL_IDS.join(" / ") + ". Codex personas: " + CODEX_MODEL_IDS.join(" / ") + "."
23654
23729
  )
23655
23730
  }
23656
23731
  },
@@ -290,7 +290,7 @@ await app.listen(Number(process.env.CLAWD_PREVIEW_PORT));
290
290
  - 引入新数据表 / 迁移 / 新接口 / 新认证流程
291
291
  - 预估 ≥ 3 个非平凡步骤
292
292
 
293
- **简单任务(TodoWrite 跟踪即可)**:单文件改动、文案/样式/配置调整、删 dead code、单点 bug 修复。
293
+ **简单任务(TodoWrite 跟踪即可;codex 会话没有 TodoWrite,用内置 plan 工具同样效果)**:单文件改动、文案/样式/配置调整、删 dead code、单点 bug 修复。
294
294
 
295
295
  判不准时倾向走 superpowers。
296
296
 
@@ -21,9 +21,12 @@ clawd daemon 启动 / 刷新时扫 `~/.clawd/personas/`,凡是含 `.clawd/pers
21
21
  ~/.clawd/personas/<persona-id>/
22
22
  .clawd/
23
23
  persona.json # 元信息(必需)
24
- sandbox-settings.json # 沙箱配置(必需,用 daemon 默认模板原样)
24
+ sandbox-settings.json # 沙箱配置(必需,用 daemon 默认模板原样,claude 会话用)
25
+ codex-sandbox.json # codex 沙箱配置(可不写,daemon 启动 migrate 会补默认断网版)
25
26
  CLAUDE.md # 人设(必需)
26
- .claude/skills/ # 可选,老板要装的 skill 会在这里
27
+ AGENTS.md # 人设镜像(必需,内容与 CLAUDE.md 完全一致——claude 读
28
+ # CLAUDE.md、codex 读 AGENTS.md,写完 CLAUDE.md 原样复制一份)
29
+ .claude/skills/ # 可选,老板要装的 skill 会在这里(两种 agent 都认这个目录)
27
30
  ```
28
31
 
29
32
  # 工作流(轻互动模式,默认)
@@ -98,7 +101,7 @@ mkdir -p ~/.clawd/personas/$ID/.clawd || { echo "sandbox 拦了,需要 owner
98
101
 
99
102
  **`CLAUDE.md`** —— 人格文件,这是真正的"灵魂"。**风格灵活**,每个 persona 应该长得不一样,按老板需求 / 你对人设的理解写。但保底要有这几块:
100
103
 
101
- 1. **第一句**:定位("你是老板的 xxx 助手"),让任何打开它的 Claude Code 一秒进入角色
104
+ 1. **第一句**:定位("你是老板的 xxx 助手"),让任何打开它的 agent(Claude Code / Codex)一秒进入角色
102
105
  2. **何时找它**:trigger 场景(老板会在什么情况下切到这个 persona)
103
106
  3. **工作方式 / 边界**:它该做什么、不做什么;该问还是该先做;有没有红线
104
107
  4. **行为规范**:跟老板对话的风格(简洁 vs 详细、是否质疑老板的判断、要不要解释思路)
@@ -66,7 +66,7 @@ clawd 的 OwnerProfile 是 `~/.clawd/profile.json`,schema v1 只有一个字
66
66
  - **clawos 仓库本地路径**:<absolute-path>
67
67
  ```
68
68
 
69
- 这样下次会话 Claude Code 加载 CLAUDE.md 时会直接看到这条,不必再探测/问。
69
+ 这样下次会话 agent 加载人格文件(Claude Code CLAUDE.md / Codex 读 AGENTS.md,clawd 双写保持一致)时会直接看到这条,不必再探测/问。
70
70
 
71
71
  两步都跑完后简短确认一下,进入正常工作。
72
72
 
@@ -106,7 +106,7 @@ clawd 的 OwnerProfile 是 `~/.clawd/profile.json`,schema v1 只有一个字
106
106
 
107
107
  老板问"clawd 是什么 / 有什么亮点 / 我能拿它做什么"时,对着下面讲,按相关度挑 3-5 条即可,不用全列。每条都是**用户能直接感知**的功能,不是内部机制。
108
108
 
109
- clawd 一句话:**它是 ClawOS 里的一个 Extension —— 在 ClawOS 桌面端装上 clawd 之后,您的 Claude Code 就长出多个"AI 助手分身",能用、能分享、能远程接,每个分身都有自己的记忆和性格。**
109
+ clawd 一句话:**它是 ClawOS 里的一个 Extension —— 在 ClawOS 桌面端装上 clawd 之后,您的 AI 编码助手(Claude Code / Codex 都支持)就长出多个"AI 助手分身",能用、能分享、能远程接,每个分身都有自己的记忆和性格。**
110
110
 
111
111
  亮点清单:
112
112
 
@@ -114,7 +114,7 @@ clawd 一句话:**它是 ClawOS 里的一个 Extension —— 在 ClawOS 桌
114
114
  2. **多个 AI 助手并存** —— 您可以自己再创建任意多个 AI 助手(每个叫一个 persona),每个有不同的性格、工作记忆、技能包,互相不串台
115
115
  3. **把助手分享给朋友** —— 一键给某个助手生成"邀请码",朋友拿这个码就能连进来跟它聊天;朋友只能在助手的小房间里活动,碰不到您电脑上其他文件(操作系统级隔离)
116
116
  4. **每个朋友一份独立对话** —— 朋友 A 和朋友 B 即使用同一个助手聊,对话历史也是各自一份,互相看不到
117
- 5. **远程接入您的本机 AI** —— 一行命令开一条公网隧道,您手机上、外网都能连回家里电脑的 Claude Code,不用部署服务器
117
+ 5. **远程接入您的本机 AI** —— 一行命令开一条公网隧道,您手机上、外网都能连回家里电脑的 AI 助手,不用部署服务器
118
118
  6. **临时借身份**(`@persona/xxx`) —— 当前对话里想让另一个助手客串一句话,输入框 `@` 一下选它,不用切会话
119
119
  7. **对话能分叉 / 回滚** —— 任何一条 AI 的回答都能 fork 出新会话分支,或者把会话回滚到之前某一步重来
120
120
  8. **助手按需装技能包** —— 每个助手第一次会话会引导您一键装它需要的技能(比如「调研员」引导装 deep-research,「知识库管理员」引导装 karpathy-llm-wiki,「飞书助理」引导装 larksuite/cli 整套 24 个 skill),走标准 skills 渠道、可独立升级,您也可以给自己建的助手装 skill
@@ -88,7 +88,7 @@ cd ~/.clawd/personas/persona-feishu-assistant
88
88
  npx skills add larksuite/cli -a claude-code --copy -y
89
89
  ```
90
90
 
91
- `-a claude-code --copy` 让 25 个 skill 直接拷到 `.claude/skills/` 下,不走 `.agents/skills/` 这条 universal canonical 路径 —— Claude Code 原生只识别 `.claude/skills/`,这样 persona 目录最干净。只有这个 persona 看得见。
91
+ `-a claude-code --copy` 让 25 个 skill 直接拷到 `.claude/skills/` 下,不走 `.agents/skills/` 这条 universal canonical 路径 —— persona 目录最干净,且 clawd 对两种 agent 都认这个目录(claude 原生识别;codex 会话由 daemon 注入 extraRoots 同样识别)。只有这个 persona 看得见。
92
92
 
93
93
  装完 `ls .claude/skills/` 应该能看到 `lark-shared` / `lark-calendar` / `lark-im` 等 25 项。
94
94