@clawos-dev/clawd 0.2.496 → 0.2.497

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.
@@ -24513,8 +24513,11 @@ var RpcMethodInfoSchema = external_exports.object({
24513
24513
  argsSchema: external_exports.record(external_exports.unknown()).optional(),
24514
24514
  /**
24515
24515
  * `denied` 必带:daemon error code(`UNAUTHORIZED` / `FEISHU_LOGIN_REQUIRED` /
24516
- * `METHOD_NOT_IMPLEMENTED`)。`conditional` 必带:谁来做二次校验。
24517
- * `allowed` 恒无。
24516
+ * `METHOD_NOT_IMPLEMENTED`),外加一个不是 error code 的 `HUMAN_ONLY`——
24517
+ * 「这条只认人手,去界面上点」(daemon `HUMAN_ONLY_METHODS`)。
24518
+ * 它**故意**不复用 `UNAUTHORIZED`:这个字段是给 agent 看的,报 UNAUTHORIZED 它会去找
24519
+ * 「我缺哪个授权」,而正确的反应是「让人来点」,两者该分得开。
24520
+ * `conditional` 必带:谁来做二次校验。`allowed` 恒无。
24518
24521
  */
24519
24522
  reason: external_exports.string().optional()
24520
24523
  });
package/dist/cli.cjs CHANGED
@@ -9473,8 +9473,11 @@ var init_methods = __esm({
9473
9473
  argsSchema: external_exports.record(external_exports.unknown()).optional(),
9474
9474
  /**
9475
9475
  * `denied` 必带:daemon error code(`UNAUTHORIZED` / `FEISHU_LOGIN_REQUIRED` /
9476
- * `METHOD_NOT_IMPLEMENTED`)。`conditional` 必带:谁来做二次校验。
9477
- * `allowed` 恒无。
9476
+ * `METHOD_NOT_IMPLEMENTED`),外加一个不是 error code 的 `HUMAN_ONLY`——
9477
+ * 「这条只认人手,去界面上点」(daemon `HUMAN_ONLY_METHODS`)。
9478
+ * 它**故意**不复用 `UNAUTHORIZED`:这个字段是给 agent 看的,报 UNAUTHORIZED 它会去找
9479
+ * 「我缺哪个授权」,而正确的反应是「让人来点」,两者该分得开。
9480
+ * `conditional` 必带:谁来做二次校验。`allowed` 恒无。
9478
9481
  */
9479
9482
  reason: external_exports.string().optional()
9480
9483
  });
@@ -59882,6 +59885,8 @@ var LocalWsServer = class {
59882
59885
  const subscribedSessions = /* @__PURE__ */ new Map();
59883
59886
  const handle = {
59884
59887
  id,
59888
+ // 界面(桌面 UI / 安卓 / iOS)都从这里进来——人手入口
59889
+ transport: "ws",
59885
59890
  subscribedSessions,
59886
59891
  send: (frame) => this.safeSend(socket, frame),
59887
59892
  close: (reason) => socket.close(1e3, reason ?? "closed")
@@ -65586,6 +65591,16 @@ var METHOD_GRANT_MAP = {
65586
65591
  "appBuilder:publish": CAPABILITY_SCOPED,
65587
65592
  "appBuilder:dismissPublishJob": CAPABILITY_SCOPED
65588
65593
  };
65594
+ var HUMAN_ONLY_METHODS = [
65595
+ "deploy:start",
65596
+ "deploy:release",
65597
+ "deploy:putSecret",
65598
+ "deploy:rerunJob"
65599
+ ];
65600
+ var HUMAN_ONLY = new Set(HUMAN_ONLY_METHODS);
65601
+ function isHumanOnlyDenied(method, transport) {
65602
+ return transport === "http" && HUMAN_ONLY.has(method);
65603
+ }
65589
65604
  function computeGrant(method) {
65590
65605
  const rule = METHOD_GRANT_MAP[method];
65591
65606
  if (!rule) return { kind: "public" };
@@ -65594,7 +65609,7 @@ function computeGrant(method) {
65594
65609
  return { kind: "check", resource: rule.resource, action: rule.action };
65595
65610
  }
65596
65611
  function computeMethodAccess(args) {
65597
- const { method, grants, feishuActive, isImplemented } = args;
65612
+ const { method, grants, feishuActive, isImplemented, transport } = args;
65598
65613
  const description = METHOD_DOCS[method].summary;
65599
65614
  const argFields = methodArgFields(method);
65600
65615
  if (!isImplemented(method)) {
@@ -65603,6 +65618,9 @@ function computeMethodAccess(args) {
65603
65618
  if (!feishuActive && FEISHU_GATED_METHODS.includes(method)) {
65604
65619
  return { name: method, description, args: argFields, status: "denied", reason: "FEISHU_LOGIN_REQUIRED" };
65605
65620
  }
65621
+ if (isHumanOnlyDenied(method, transport)) {
65622
+ return { name: method, description, args: argFields, status: "denied", reason: "HUMAN_ONLY" };
65623
+ }
65606
65624
  if (METHOD_GRANT_MAP[method]?.kind === "capability-scoped") {
65607
65625
  return {
65608
65626
  name: method,
@@ -65620,7 +65638,7 @@ function computeMethodAccess(args) {
65620
65638
  }
65621
65639
 
65622
65640
  // src/version.ts
65623
- var version = "0.2.496".length > 0 ? "0.2.496" : "dev";
65641
+ var version = "0.2.497".length > 0 ? "0.2.497" : "dev";
65624
65642
 
65625
65643
  // src/cli-probe/probe.ts
65626
65644
  var fs72 = __toESM(require("fs"), 1);
@@ -65717,14 +65735,17 @@ function buildMetaHandlers(deps) {
65717
65735
  };
65718
65736
  }
65719
65737
  function buildMetaMethodsHandler(deps) {
65720
- return async (frame, _client, ctx) => {
65738
+ return async (frame, client, ctx) => {
65721
65739
  const grants = ctx?.grants ?? [];
65722
65740
  const { method } = MetaMethodsArgs.parse(frame);
65723
65741
  const compute = (m2) => computeMethodAccess({
65724
65742
  method: m2,
65725
65743
  grants,
65726
65744
  feishuActive: deps.feishuActive(),
65727
- isImplemented: deps.isImplemented
65745
+ isImplemented: deps.isImplemented,
65746
+ // 只认人手的 method 对程序调用方报 denied(HUMAN_ONLY)——`list` tool 唯一的消费场景
65747
+ // 就是 agent,让它一开始就看不见,省掉「先发现再撞墙」那一轮。
65748
+ transport: client.transport
65728
65749
  });
65729
65750
  if (method !== void 0) {
65730
65751
  if (!isMethodName(method)) {
@@ -69270,6 +69291,12 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
69270
69291
  `${method} requires feishu login (People/remote identity)`
69271
69292
  );
69272
69293
  }
69294
+ if (isHumanOnlyDenied(method, client.transport)) {
69295
+ throw new ClawdError(
69296
+ ERROR_CODES.UNAUTHORIZED,
69297
+ `${method} \u53EA\u80FD\u4ECE\u754C\u9762\u4E0A\u70B9\u2014\u2014\u5B83\u4F1A\u5728\u7EC4\u7EC7\u91CC\u5EFA\u4ED3\u5E93 / \u628A\u955C\u50CF\u63A8\u4E0A\u7EBF / \u5199\u51ED\u636E\uFF0C\u4E0D\u63A5\u53D7\u7A0B\u5E8F\u8C03\u7528`
69298
+ );
69299
+ }
69273
69300
  const verdict = computeGrant(method);
69274
69301
  if (verdict.kind === "check") {
69275
69302
  const ok = assertGrant(ctx.grants, verdict.resource, verdict.action);
@@ -70969,6 +70996,8 @@ async function startDaemon(config) {
70969
70996
  dispatch: (method, body, ctx) => {
70970
70997
  const client = {
70971
70998
  id: "http-rpc",
70999
+ // 本机 MCP server / 跨设备 peer / web 应用都从这条进来——程序入口,不是人手
71000
+ transport: "http",
70972
71001
  subscribedSessions: /* @__PURE__ */ new Map(),
70973
71002
  send() {
70974
71003
  },
@@ -24505,8 +24505,11 @@ var RpcMethodInfoSchema = external_exports.object({
24505
24505
  argsSchema: external_exports.record(external_exports.unknown()).optional(),
24506
24506
  /**
24507
24507
  * `denied` 必带:daemon error code(`UNAUTHORIZED` / `FEISHU_LOGIN_REQUIRED` /
24508
- * `METHOD_NOT_IMPLEMENTED`)。`conditional` 必带:谁来做二次校验。
24509
- * `allowed` 恒无。
24508
+ * `METHOD_NOT_IMPLEMENTED`),外加一个不是 error code 的 `HUMAN_ONLY`——
24509
+ * 「这条只认人手,去界面上点」(daemon `HUMAN_ONLY_METHODS`)。
24510
+ * 它**故意**不复用 `UNAUTHORIZED`:这个字段是给 agent 看的,报 UNAUTHORIZED 它会去找
24511
+ * 「我缺哪个授权」,而正确的反应是「让人来点」,两者该分得开。
24512
+ * `conditional` 必带:谁来做二次校验。`allowed` 恒无。
24510
24513
  */
24511
24514
  reason: external_exports.string().optional()
24512
24515
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.496",
3
+ "version": "0.2.497",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",