larkin 0.5.12 → 0.5.13

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.
@@ -16,7 +16,7 @@ import { collectSetupAgentChoice, missingRuntimeInstallMessage, terminalSetupQue
16
16
  import { documentCommentSubscriptionCapability, markDocumentCommentSubscriptionVerified, } from "../platform/callback-capability.mjs";
17
17
  import { openPlatformHost, parseLarkinTenant, registerAppAccountsHost, } from "../feishu/platform-hosts.mjs";
18
18
  import { authorizationUrlFailureMessage, presentAuthorizationUrl } from "./setup-authorization-url.mjs";
19
- import { reconcileTenantScopes, tenantScopeRecoveryMessage } from "./tenant-scope-grant.mjs";
19
+ import { missingOptionalScopeImpacts, reconcileTenantScopes, tenantScopeRecoveryMessage } from "./tenant-scope-grant.mjs";
20
20
  // qrcode-terminal does not publish TypeScript declarations.
21
21
  // @ts-expect-error bundled CommonJS dependency
22
22
  import qrcodePackage from "qrcode-terminal";
@@ -770,8 +770,11 @@ Lark 必须用 --tenant lark:授权二维码是官方 /page/cli(begin 仍走
770
770
  : "Tenant scopes 对账未验证:权威 API 失败或响应无效,不能确认任何申请项已授予。");
771
771
  if (!grants.verified)
772
772
  say("请检查所选 Agent 的受管 bot CLI 与网络后重跑原 larkin setup 命令,保留 --tenant/--runtime 参数;不要重建 Agent,也不要据此修改应用权限。");
773
- if (grants.verified && !grants.missingRequired.length && grants.missingOptional.length)
774
- say("! 可选权限未授予,setup 可继续;相关能力仍不可用或未验证。");
773
+ if (grants.verified && !grants.missingRequired.length && grants.missingOptional.length) {
774
+ say("! 可选权限未授予,setup 可继续;以下能力可能受限(实际以平台校验为准):");
775
+ for (const impact of missingOptionalScopeImpacts(grants.missingOptional))
776
+ say(` - ${impact}`);
777
+ }
775
778
  if (missing.length)
776
779
  say(tenantScopeRecoveryMessage(tenant, id, missing));
777
780
  if (!grants.verified || grants.missingRequired.length > 0) {
@@ -11,7 +11,7 @@ import { managedOfficialLarkCli } from "../app/agent-lark-cli-workspace.mjs";
11
11
  import { loadValidatedBotCredential } from "./run-credential-preflight.mjs";
12
12
  import { parseLarkinTenant, registerAppAccountsHost } from "../feishu/platform-hosts.mjs";
13
13
  import { presentAuthorizationUrl } from "./setup-authorization-url.mjs";
14
- import { reconcileTenantScopes, tenantScopeRecoveryMessage } from "./tenant-scope-grant.mjs";
14
+ import { missingOptionalScopeImpacts, reconcileTenantScopes, tenantScopeRecoveryMessage } from "./tenant-scope-grant.mjs";
15
15
  // qrcode-terminal does not publish TypeScript declarations.
16
16
  // @ts-expect-error bundled CommonJS dependency
17
17
  import qrcodePackage from "qrcode-terminal";
@@ -178,8 +178,11 @@ export async function main() {
178
178
  const missing = [...grants.missingRequired, ...grants.missingOptional];
179
179
  if (!grants.verified)
180
180
  throw new Error("Bot tenant scope 未验证;请检查所选 Agent 的受管 bot CLI 与网络,再重跑原 setup 命令并保留 --tenant/--runtime;不要据此修改应用权限。");
181
- if (!grants.missingRequired.length && grants.missingOptional.length)
182
- log("! 可选权限未授予,setup 可继续;相关能力仍不可用或未验证。");
181
+ if (!grants.missingRequired.length && grants.missingOptional.length) {
182
+ log("! 可选权限未授予,setup 可继续;以下能力可能受限(实际以平台校验为准):");
183
+ for (const impact of missingOptionalScopeImpacts(grants.missingOptional))
184
+ log(` - ${impact}`);
185
+ }
183
186
  if (missing.length)
184
187
  log(tenantScopeRecoveryMessage(TENANT, APP_ID, missing));
185
188
  if (grants.missingRequired.length)
@@ -31,6 +31,33 @@ export function reconcileTenantScopes(payload, requested) {
31
31
  missingOptional: verified ? missingGrantedTenantScopes(payload, optional) : [],
32
32
  };
33
33
  }
34
+ /**
35
+ * Capability each requested-but-optional tenant scope backs. The freshness gate
36
+ * keeps `im:message.group_msg` as the only blocking requirement, but a missing
37
+ * optional scope still degrades a named capability at runtime — an im:chat* gap
38
+ * surfaces as "成员表拉取失败" in the daemon log, for example. Setup reports the
39
+ * impact beside the scope names so the gap is visible before the first run.
40
+ */
41
+ const OPTIONAL_SCOPE_CAPABILITIES = [
42
+ { capability: "群与成员信息(成员姓名/群名解析)", scopes: ["im:chat:readonly", "im:chat.group_info:readonly", "im:chat.members:read"] },
43
+ { capability: "群管理(建群/改名/成员变更/退群)", scopes: ["im:chat", "im:chat:create", "im:chat:update", "im:chat.members:write_only", "im:chat:operate_as_owner"] },
44
+ { capability: "云文档评论事件与回复", scopes: ["drive:drive", "docs:document.comment:read", "docs:document.comment:create"] },
45
+ { capability: "应用可用范围自动设为全员可见", scopes: ["admin:app.visibility"] },
46
+ { capability: "发送者签名中的工号(employee_id)", scopes: ["contact:user.employee_id:readonly"] },
47
+ { capability: "机器人消息搜索", scopes: ["search:message"] },
48
+ { capability: "消息收发与资源(基本消息能力)", scopes: ["im:message", "im:message.p2p_msg:readonly", "im:message.group_at_msg:readonly", "im:message:send_as_bot", "im:resource"] },
49
+ ];
50
+ /** Missing optional scopes grouped by the capability they degrade, in declaration order. */
51
+ export function missingOptionalScopeImpacts(missing) {
52
+ const names = new Set(missing);
53
+ const lines = OPTIONAL_SCOPE_CAPABILITIES.flatMap(({ capability, scopes }) => {
54
+ const hit = scopes.filter((scope) => names.has(scope));
55
+ return hit.length ? [`${capability}:${hit.join(", ")}`] : [];
56
+ });
57
+ const covered = new Set(OPTIONAL_SCOPE_CAPABILITIES.flatMap(({ scopes }) => scopes));
58
+ const rest = missing.filter((scope) => !covered.has(scope));
59
+ return rest.length ? [...lines, `其他权限:${rest.join(", ")}`] : lines;
60
+ }
34
61
  /** Official console recovery form used by lark-cli; scopes are tenant permissions. */
35
62
  export function tenantScopeRecoveryMessage(tenant, appId, scopes) {
36
63
  const url = new URL(`${openPlatformHost(tenant)}/app/${encodeURIComponent(appId)}/auth`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "larkin",
3
- "version": "0.5.12",
3
+ "version": "0.5.13",
4
4
  "private": false,
5
5
  "larkinPackageRole": "npm-published",
6
6
  "files": [