@clawos-dev/clawd 0.2.135-beta.284.17b2ea2 → 0.2.136-beta.285.b451e3c

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
@@ -33079,6 +33079,11 @@ var SessionManager = class {
33079
33079
  // manager.resizePty 用此映射把 UI 的 session:pty:resize 同步到 surface 内部 buffer,
33080
33080
  // 保证 snapshot serialize 时 cursor positioning 与 UI xterm 实际尺寸一致。
33081
33081
  surfacesByToolSid = /* @__PURE__ */ new Map();
33082
+ // TUI 模式:sessionId → UI 最近一次上报的 xterm 尺寸。resizePty 入口无条件记录(含 pty
33083
+ // 尚未 spawn / runner 尚未创建的早到 resize),registerPty / registerSurface 时回放——
33084
+ // 修「mount resize 早于 lazy spawn 被丢」与「respawn 回到 120×40 后无人补发」的尺寸错配。
33085
+ // 键用 sessionId 而非 toolSessionId:/clear 会 reassign tsid,sessionId 跨 respawn 稳定
33086
+ lastUiSizeBySessionId = /* @__PURE__ */ new Map();
33082
33087
  // 仅 mode='tui' 需要:index.ts 装配阶段在 observer 构造后注入。
33083
33088
  // observer.onEvent 要回灌 manager.feedObserverEvents,所以 observer 必须晚于 manager
33084
33089
  // 构造;反过来 manager 又要在 mode='tui' 下 spawn session 时 attach observer。setter 解循环
@@ -33615,6 +33620,7 @@ var SessionManager = class {
33615
33620
  });
33616
33621
  this.runners.delete(args.sessionId);
33617
33622
  this.realUuidBySynth.delete(args.sessionId);
33623
+ this.lastUiSizeBySessionId.delete(args.sessionId);
33618
33624
  return { response: { sessionId: args.sessionId }, broadcast };
33619
33625
  }
33620
33626
  this.deleteOwned(args.sessionId);
@@ -34130,6 +34136,7 @@ var SessionManager = class {
34130
34136
  });
34131
34137
  this.runners.delete(args.sessionId);
34132
34138
  this.realUuidBySynth.delete(args.sessionId);
34139
+ this.lastUiSizeBySessionId.delete(args.sessionId);
34133
34140
  return { response: { sessionId: args.sessionId }, broadcast };
34134
34141
  }
34135
34142
  this.storeFor(args.scope).delete(args.sessionId);
@@ -34295,6 +34302,14 @@ var SessionManager = class {
34295
34302
  /** ClaudeTuiAdapter.spawn 后调用,让 manager 持有 pty handle 供 handler input/resize 路由 */
34296
34303
  registerPty(toolSessionId, pty) {
34297
34304
  this.ptyTransports.set(toolSessionId, pty);
34305
+ const sid = this.sessionIdByToolSid(toolSessionId);
34306
+ const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
34307
+ if (size) {
34308
+ try {
34309
+ pty.resize(size.cols, size.rows);
34310
+ } catch {
34311
+ }
34312
+ }
34298
34313
  }
34299
34314
  /** spawn 进程 exit 时调用,清理映射防止后续 input 写到已死 pty + 释放 replay 闭包 */
34300
34315
  unregisterPty(toolSessionId) {
@@ -34384,6 +34399,9 @@ var SessionManager = class {
34384
34399
  /** ClaudeTuiAdapter spawn 时注册 surface ref;同一 tsid 重 spawn 会覆盖 */
34385
34400
  registerSurface(toolSessionId, surface) {
34386
34401
  this.surfacesByToolSid.set(toolSessionId, surface);
34402
+ const sid = this.sessionIdByToolSid(toolSessionId);
34403
+ const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
34404
+ if (size) surface.resize(size.cols, size.rows);
34387
34405
  }
34388
34406
  /** spawn 进程 exit 时清理 */
34389
34407
  unregisterSurface(toolSessionId) {
@@ -34396,6 +34414,7 @@ var SessionManager = class {
34396
34414
  * 找不到 runner / toolSessionId / pty 任一缺失 → 返 false,handler 静默给 UI 报 ok=false 不抛错。
34397
34415
  */
34398
34416
  resizePty(sessionId, cols, rows) {
34417
+ this.lastUiSizeBySessionId.set(sessionId, { cols, rows });
34399
34418
  const runner = this.runners.get(sessionId);
34400
34419
  if (!runner) return false;
34401
34420
  const tsid = runner.getState().file.toolSessionId;
@@ -40034,6 +40053,14 @@ var StateFileManager = class {
40034
40053
  }
40035
40054
  };
40036
40055
 
40056
+ // src/discovery/source-from-env.ts
40057
+ function readDaemonSourceFromEnv(env = process.env) {
40058
+ const v2 = env.CLAWD_DAEMON_SOURCE;
40059
+ if (typeof v2 !== "string") return void 0;
40060
+ const trimmed = v2.trim();
40061
+ return trimmed.length > 0 ? trimmed : void 0;
40062
+ }
40063
+
40037
40064
  // src/tunnel/tunnel-manager.ts
40038
40065
  var import_node_fs24 = __toESM(require("fs"), 1);
40039
40066
  var import_node_path25 = __toESM(require("path"), 1);
@@ -45929,7 +45956,8 @@ async function startDaemon(config) {
45929
45956
  protocolVersion: PROTOCOL_VERSION,
45930
45957
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
45931
45958
  authMode,
45932
- authToken: resolvedAuthToken ?? void 0
45959
+ authToken: resolvedAuthToken ?? void 0,
45960
+ source: readDaemonSourceFromEnv()
45933
45961
  };
45934
45962
  stateMgr.write(stateSnapshot);
45935
45963
  process.stdout.write(`Ready: ${url}
@@ -70,6 +70,19 @@ done
70
70
  - **显式优于隐式**(数据流和依赖清晰可见)
71
71
  - **测试驱动**(先写测试)
72
72
 
73
+ ## 模块边界:deep-leaf 优先
74
+
75
+ 划模块边界时按这两条判据,理想是"既 deep 又 leaf"的节点:
76
+
77
+ - **deep**(接口窄、内部厚):调用方不需要知道实现细节就能正确用。改实现 → 调用方无感
78
+ - **leaf**(爆炸半径小):没有其他模块依赖它的内部状态。它出 bug / 被重写不会污染上游
79
+
80
+ **反面**:浅模块(接口比实现还复杂,把简单逻辑拆碎成 N 个文件)、伪主干(本可叶子的功能因偷懒共享状态而长成主干)。
81
+
82
+ **AI 协作处方**:叶子节点可以放手让 AI vibe;主干 / 跨模块改动必须人工 review 接口设计。
83
+
84
+ 参考 Ousterhout *A Philosophy of Software Design* 的 deep module 概念。
85
+
73
86
  ## 跨模块设计
74
87
 
75
88
  **推迟逻辑分叉**:同一条数据/事件链路跨多个模块时,分叉尽量在最末端消费方。中间层默认复用上游 schema 透传,下游按需 narrow。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.135-beta.284.17b2ea2",
3
+ "version": "0.2.136-beta.285.b451e3c",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",