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`);
|