@larktask/aamp-feishu-task-agent 0.1.1-dev.2 → 0.1.1-dev.4
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/README.md
CHANGED
|
@@ -5,8 +5,10 @@ user-owned Feishu Bots and running the corresponding Task bridges.
|
|
|
5
5
|
|
|
6
6
|
## Install and bind
|
|
7
7
|
|
|
8
|
-
Run the standalone one-click command.
|
|
9
|
-
|
|
8
|
+
Run the standalone one-click command. The launcher checks for Node.js and npm
|
|
9
|
+
before setup. When either is unavailable, it stops before authorization and
|
|
10
|
+
links to the official Node.js LTS download page; it does not install or modify
|
|
11
|
+
the user's package managers automatically:
|
|
10
12
|
|
|
11
13
|
```bash
|
|
12
14
|
npx -y --package @larktask/aamp-feishu-task-agent@dev \
|
|
@@ -75,6 +75,10 @@ const FEISHU_START_CONCURRENCY = 4;
|
|
|
75
75
|
const CONFIG_SCHEMA = 'aamp.feishu-task-agent.bindings';
|
|
76
76
|
const CONFIG_VERSION = 1;
|
|
77
77
|
const PROFILE_DOMAINS = ['task'];
|
|
78
|
+
const OPEN_API_DOMAIN_BY_TENANT_BRAND = Object.freeze({
|
|
79
|
+
feishu: 'https://open.feishu.cn',
|
|
80
|
+
lark: 'https://open.larksuite.com',
|
|
81
|
+
});
|
|
78
82
|
|
|
79
83
|
const secrets = new Set();
|
|
80
84
|
const managedProcesses = new Set();
|
|
@@ -782,6 +786,7 @@ function validateBinding(binding, index) {
|
|
|
782
786
|
assertString(binding.environment?.name, `bindings[${index}].environment.name`);
|
|
783
787
|
assertString(binding.bot?.app_id, `bindings[${index}].bot.app_id`);
|
|
784
788
|
assertString(binding.bot?.app_secret, `bindings[${index}].bot.app_secret`);
|
|
789
|
+
normalizeTenantBrand(binding.bot?.tenant_brand, `bindings[${index}].bot.tenant_brand`);
|
|
785
790
|
const metadata = resolveTaskAgentMetadata(binding.agent_type);
|
|
786
791
|
if (metadata.executionLocation === 'local') {
|
|
787
792
|
assertString(binding.bot?.lark_cli_profile, `bindings[${index}].bot.lark_cli_profile`);
|
|
@@ -841,12 +846,26 @@ function bindingExpectation(binding) {
|
|
|
841
846
|
};
|
|
842
847
|
}
|
|
843
848
|
|
|
849
|
+
function normalizeTenantBrand(value, field = 'tenant_brand') {
|
|
850
|
+
if (value === undefined || value === null || value === '') return 'feishu';
|
|
851
|
+
if (value !== 'feishu' && value !== 'lark') {
|
|
852
|
+
throw new Error(`${field} 仅支持 feishu/lark`);
|
|
853
|
+
}
|
|
854
|
+
return value;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function openApiDomainForTenantBrand(value) {
|
|
858
|
+
return OPEN_API_DOMAIN_BY_TENANT_BRAND[normalizeTenantBrand(value)];
|
|
859
|
+
}
|
|
860
|
+
|
|
844
861
|
function sameBindingRelationship(existing, candidate) {
|
|
845
862
|
return Boolean(existing && candidate
|
|
846
863
|
&& existing.agent_type === candidate.agent_type
|
|
847
864
|
&& existing.aamp_host === candidate.aamp_host
|
|
848
865
|
&& existing.environment?.name === candidate.environment?.name
|
|
849
|
-
&& existing.bot?.app_id === candidate.bot?.app_id
|
|
866
|
+
&& existing.bot?.app_id === candidate.bot?.app_id
|
|
867
|
+
&& normalizeTenantBrand(existing.bot?.tenant_brand)
|
|
868
|
+
=== normalizeTenantBrand(candidate.bot?.tenant_brand));
|
|
850
869
|
}
|
|
851
870
|
|
|
852
871
|
async function upsertBindings(intents) {
|
|
@@ -2140,6 +2159,7 @@ function feishuArgs(binding, larkCliBin, target) {
|
|
|
2140
2159
|
...targetArgs,
|
|
2141
2160
|
'--app-id', binding.bot.app_id,
|
|
2142
2161
|
'--bot-name', binding.bot.display_name || binding.bot.app_id,
|
|
2162
|
+
'--domain', openApiDomainForTenantBrand(binding.bot.tenant_brand),
|
|
2143
2163
|
...(metadata.executionLocation === 'local' ? [
|
|
2144
2164
|
'--use-feishu-cli',
|
|
2145
2165
|
'--feishu-cli-profile', binding.bot.lark_cli_profile,
|
|
@@ -3093,21 +3113,8 @@ async function discoverAgents() {
|
|
|
3093
3113
|
return agents;
|
|
3094
3114
|
}
|
|
3095
3115
|
|
|
3096
|
-
|
|
3097
|
-
const agent = DEFAULT_AGENT || await chooseOne('请选择要绑定的智能体:', agents, agentSelectionDisplayName);
|
|
3098
|
-
const registered = await runBootstrapHelper('__register-binding', agent);
|
|
3099
|
-
addSecret(registered.app_secret);
|
|
3116
|
+
function buildPendingBinding(agent, registered, bindingId = randomId(), timestamp = nowIso()) {
|
|
3100
3117
|
const metadata = resolveTaskAgentMetadata(agent);
|
|
3101
|
-
if (!registered.app_id || !registered.app_secret
|
|
3102
|
-
|| (metadata.executionLocation === 'local' && !registered.lark_cli_profile)) {
|
|
3103
|
-
throw new Error('飞书应用授权结果不完整');
|
|
3104
|
-
}
|
|
3105
|
-
if (selectedAppIds.has(registered.app_id)) {
|
|
3106
|
-
throw new Error(`Bot ${registered.app_id} 已经选择过,不能重复绑定`);
|
|
3107
|
-
}
|
|
3108
|
-
selectedAppIds.add(registered.app_id);
|
|
3109
|
-
const bindingId = randomId();
|
|
3110
|
-
const timestamp = nowIso();
|
|
3111
3118
|
return {
|
|
3112
3119
|
binding_id: bindingId,
|
|
3113
3120
|
agent_type: agent,
|
|
@@ -3115,6 +3122,7 @@ async function createDraft(agents, selectedAppIds) {
|
|
|
3115
3122
|
app_id: registered.app_id,
|
|
3116
3123
|
app_secret: registered.app_secret,
|
|
3117
3124
|
display_name: registered.display_name || registered.app_id,
|
|
3125
|
+
tenant_brand: normalizeTenantBrand(registered.tenant_brand, 'registered.tenant_brand'),
|
|
3118
3126
|
...(metadata.executionLocation === 'local' ? { lark_cli_profile: registered.lark_cli_profile } : {}),
|
|
3119
3127
|
},
|
|
3120
3128
|
environment: { name: 'online' },
|
|
@@ -3126,6 +3134,22 @@ async function createDraft(agents, selectedAppIds) {
|
|
|
3126
3134
|
};
|
|
3127
3135
|
}
|
|
3128
3136
|
|
|
3137
|
+
async function createDraft(agents, selectedAppIds) {
|
|
3138
|
+
const agent = DEFAULT_AGENT || await chooseOne('请选择要绑定的智能体:', agents, agentSelectionDisplayName);
|
|
3139
|
+
const registered = await runBootstrapHelper('__register-binding', agent);
|
|
3140
|
+
addSecret(registered.app_secret);
|
|
3141
|
+
const metadata = resolveTaskAgentMetadata(agent);
|
|
3142
|
+
if (!registered.app_id || !registered.app_secret
|
|
3143
|
+
|| (metadata.executionLocation === 'local' && !registered.lark_cli_profile)) {
|
|
3144
|
+
throw new Error('飞书应用授权结果不完整');
|
|
3145
|
+
}
|
|
3146
|
+
if (selectedAppIds.has(registered.app_id)) {
|
|
3147
|
+
throw new Error(`Bot ${registered.app_id} 已经选择过,不能重复绑定`);
|
|
3148
|
+
}
|
|
3149
|
+
selectedAppIds.add(registered.app_id);
|
|
3150
|
+
return buildPendingBinding(agent, registered);
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3129
3153
|
async function runBindingSession(mode) {
|
|
3130
3154
|
const store = await loadStore();
|
|
3131
3155
|
throwIfStopping();
|
|
@@ -3437,6 +3461,7 @@ if (isMainModule) {
|
|
|
3437
3461
|
}
|
|
3438
3462
|
|
|
3439
3463
|
export {
|
|
3464
|
+
buildPendingBinding,
|
|
3440
3465
|
bindingExpectation,
|
|
3441
3466
|
acpBridgeAgentPolicy,
|
|
3442
3467
|
commitPreparedAgentBindings,
|
|
@@ -5,6 +5,7 @@ umask 077
|
|
|
5
5
|
AGENT=""
|
|
6
6
|
APP_ID=""
|
|
7
7
|
APP_SECRET=""
|
|
8
|
+
APP_TENANT_BRAND="feishu"
|
|
8
9
|
BOT_NAME=""
|
|
9
10
|
LARK_CLI_PROFILE=""
|
|
10
11
|
AGENT_EXECUTION_LOCATION=""
|
|
@@ -111,7 +112,7 @@ AAMP_TASK_DEFAULT_FEISHU_BRIDGE_PKG="$FEISHU_BRIDGE_PKG"
|
|
|
111
112
|
AAMP_TASK_DEFAULT_AIME_ACP_PKG="$AIME_ACP_PKG"
|
|
112
113
|
AAMP_TASK_AGENT_NAME="${AAMP_TASK_AGENT_NAME:-@larktask/aamp-feishu-task-agent}"
|
|
113
114
|
AAMP_TASK_AGENT_LEGACY_NAME="${AAMP_TASK_AGENT_LEGACY_NAME:-@zengxingyuan/aamp-feishu-task-agent}"
|
|
114
|
-
AAMP_TASK_AGENT_VERSION="0.1.1-dev.
|
|
115
|
+
AAMP_TASK_AGENT_VERSION="0.1.1-dev.4"
|
|
115
116
|
AAMP_TASK_AGENT_CHANNEL="${AAMP_TASK_AGENT_CHANNEL:-dev}"
|
|
116
117
|
AAMP_STALE_PROCESS_CLEANUP="${AAMP_STALE_PROCESS_CLEANUP:-false}"
|
|
117
118
|
AAMP_STALE_PROCESS_SECONDS="${AAMP_STALE_PROCESS_SECONDS:-86400}"
|
|
@@ -682,98 +683,57 @@ path_prepend() {
|
|
|
682
683
|
esac
|
|
683
684
|
}
|
|
684
685
|
|
|
685
|
-
run_brew() {
|
|
686
|
-
# Feed one "yes" for Homebrew prompts such as dependency installation confirmation.
|
|
687
|
-
printf 'y\n' | HOMEBREW_NO_ENV_HINTS=1 brew "$@"
|
|
688
|
-
}
|
|
689
|
-
|
|
690
686
|
refresh_node_toolchain_bins() {
|
|
691
687
|
NPM_BIN="$(command -v npm || true)"
|
|
692
688
|
NPX_BIN="$(command -v npx || true)"
|
|
693
689
|
}
|
|
694
690
|
|
|
695
|
-
|
|
691
|
+
print_missing_node_help() {
|
|
696
692
|
cat >&2 <<'HELP'
|
|
697
693
|
|
|
698
|
-
|
|
699
|
-
Install it manually with one of these commands, then reopen the terminal or fix PATH:
|
|
700
|
-
Homebrew: brew install node
|
|
701
|
-
Volta: volta install node npm
|
|
702
|
-
fnm: fnm install --lts
|
|
703
|
-
nvm: nvm install --lts
|
|
694
|
+
未检测到 Node.js 环境。
|
|
704
695
|
|
|
705
|
-
|
|
706
|
-
|
|
696
|
+
请安装 Node.js LTS:
|
|
697
|
+
https://nodejs.org/en/download
|
|
707
698
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
699
|
+
安装完成后:
|
|
700
|
+
1. 重新打开终端
|
|
701
|
+
2. 执行 node -v && npm -v 验证
|
|
702
|
+
3. 重新运行本安装命令
|
|
711
703
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
volta install node npm
|
|
715
|
-
return $?
|
|
716
|
-
fi
|
|
704
|
+
HELP
|
|
705
|
+
}
|
|
717
706
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
fnm install --lts
|
|
721
|
-
eval "$(fnm env --shell bash)"
|
|
722
|
-
return 0
|
|
723
|
-
fi
|
|
707
|
+
print_incomplete_node_help() {
|
|
708
|
+
cat >&2 <<'HELP'
|
|
724
709
|
|
|
725
|
-
|
|
726
|
-
if [ -s "$nvm_dir/nvm.sh" ] && { [ -z "$node_path" ] || [[ "$node_path" == *"/.nvm/"* ]]; }; then
|
|
727
|
-
agent_log "installing Node.js/npm with nvm"
|
|
728
|
-
# shellcheck disable=SC1090
|
|
729
|
-
source "$nvm_dir/nvm.sh"
|
|
730
|
-
nvm install --lts
|
|
731
|
-
nvm use --lts
|
|
732
|
-
return 0
|
|
733
|
-
fi
|
|
710
|
+
Node.js 环境不完整,缺少 npm。
|
|
734
711
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if brew list --versions node@22 >/dev/null 2>&1; then
|
|
738
|
-
formula="node@22"
|
|
739
|
-
elif brew list --versions node >/dev/null 2>&1; then
|
|
740
|
-
formula="node"
|
|
741
|
-
fi
|
|
712
|
+
请重新安装 Node.js LTS:
|
|
713
|
+
https://nodejs.org/en/download
|
|
742
714
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
agent_log "installing Node.js/npm with Homebrew"
|
|
748
|
-
run_brew install "$formula"
|
|
749
|
-
fi
|
|
750
|
-
return $?
|
|
751
|
-
fi
|
|
715
|
+
安装完成后:
|
|
716
|
+
1. 重新打开终端
|
|
717
|
+
2. 执行 node -v && npm -v 验证
|
|
718
|
+
3. 重新运行本安装命令
|
|
752
719
|
|
|
753
|
-
|
|
754
|
-
return 1
|
|
720
|
+
HELP
|
|
755
721
|
}
|
|
756
722
|
|
|
757
723
|
ensure_node_toolchain() {
|
|
724
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
725
|
+
print_missing_node_help
|
|
726
|
+
agent_fail "未检测到 Node.js,请先安装 Node.js LTS"
|
|
727
|
+
fi
|
|
728
|
+
|
|
758
729
|
refresh_node_toolchain_bins
|
|
759
|
-
if [ -n "$NPM_BIN" ]
|
|
730
|
+
if [ -n "$NPM_BIN" ]; then
|
|
760
731
|
configure_npm_registry
|
|
761
732
|
return 0
|
|
762
733
|
fi
|
|
763
734
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
print_node_toolchain_help
|
|
767
|
-
agent_fail "failed to install Node.js/npm automatically"
|
|
768
|
-
fi
|
|
769
|
-
|
|
770
|
-
hash -r 2>/dev/null || true
|
|
771
|
-
refresh_node_toolchain_bins
|
|
772
|
-
[ -n "$NPM_BIN" ] && [ -n "$NPX_BIN" ] || {
|
|
773
|
-
print_node_toolchain_help
|
|
774
|
-
agent_fail "npm/npx is still unavailable after installation"
|
|
775
|
-
}
|
|
776
|
-
configure_npm_registry
|
|
735
|
+
print_incomplete_node_help
|
|
736
|
+
agent_fail "Node.js 环境不完整,请重新安装 Node.js LTS"
|
|
777
737
|
}
|
|
778
738
|
|
|
779
739
|
configure_npm_registry() {
|
|
@@ -1815,12 +1775,13 @@ for (const bot of bots) {
|
|
|
1815
1775
|
const profile = String(bot?.profile || "").trim();
|
|
1816
1776
|
const name = String(bot?.display_name || appId).trim();
|
|
1817
1777
|
const appSecret = String(bot?.app_secret || "").trim();
|
|
1778
|
+
const tenantBrand = bot?.tenant_brand === "lark" ? "lark" : "feishu";
|
|
1818
1779
|
if (!appId || !profile || seen.has(appId) || activeAppIds.has(appId)) continue;
|
|
1819
1780
|
if (!appSecret) {
|
|
1820
1781
|
continue;
|
|
1821
1782
|
}
|
|
1822
1783
|
seen.add(appId);
|
|
1823
|
-
console.log([appId, name, profile, appSecret].join("\t"));
|
|
1784
|
+
console.log([appId, name, profile, appSecret, tenantBrand].join("\t"));
|
|
1824
1785
|
}
|
|
1825
1786
|
'
|
|
1826
1787
|
}
|
|
@@ -2003,7 +1964,12 @@ process.exit(bots.some((bot) => String(bot?.app_id || "").trim() && String(bot?.
|
|
|
2003
1964
|
|
|
2004
1965
|
task_profile_name_for_app_id() {
|
|
2005
1966
|
local app_id="$1"
|
|
2006
|
-
|
|
1967
|
+
local tenant_brand="${2:-feishu}"
|
|
1968
|
+
case "$tenant_brand" in
|
|
1969
|
+
feishu) printf 'aamp-feishu-task-%s' "$app_id" ;;
|
|
1970
|
+
lark) printf 'aamp-feishu-task-%s-lark' "$app_id" ;;
|
|
1971
|
+
*) agent_fail "unsupported tenant brand: $tenant_brand" ;;
|
|
1972
|
+
esac
|
|
2007
1973
|
}
|
|
2008
1974
|
|
|
2009
1975
|
save_bot_config() {
|
|
@@ -2011,14 +1977,20 @@ save_bot_config() {
|
|
|
2011
1977
|
local app_id="$2"
|
|
2012
1978
|
local profile="$3"
|
|
2013
1979
|
local app_secret="${4:-}"
|
|
1980
|
+
local tenant_brand="${5:-feishu}"
|
|
2014
1981
|
mkdir -p "$(dirname "$BOT_CONFIG_FILE")"
|
|
2015
|
-
|
|
1982
|
+
case "$tenant_brand" in
|
|
1983
|
+
feishu|lark) ;;
|
|
1984
|
+
*) agent_fail "unsupported tenant brand: $tenant_brand" ;;
|
|
1985
|
+
esac
|
|
1986
|
+
BOT_CONFIG_FILE="$BOT_CONFIG_FILE" BOT_NAME="$bot_name" BOT_APP_ID="$app_id" BOT_PROFILE="$profile" BOT_APP_SECRET="$app_secret" BOT_TENANT_BRAND="$tenant_brand" FEISHU_TASK_PROFILE_DOMAINS="$FEISHU_TASK_PROFILE_DOMAINS" FEISHU_SCOPE_MANIFEST_VERSION="$FEISHU_SCOPE_MANIFEST_VERSION" FEISHU_USER_AUTH_MODE="$FEISHU_USER_AUTH_MODE" node -e '
|
|
2016
1987
|
const fs = require("fs");
|
|
2017
1988
|
const file = process.env.BOT_CONFIG_FILE;
|
|
2018
1989
|
const appSecret = String(process.env.BOT_APP_SECRET || "").trim();
|
|
2019
1990
|
const next = {
|
|
2020
1991
|
display_name: process.env.BOT_NAME || process.env.BOT_APP_ID,
|
|
2021
1992
|
app_id: process.env.BOT_APP_ID,
|
|
1993
|
+
tenant_brand: process.env.BOT_TENANT_BRAND || "feishu",
|
|
2022
1994
|
...(appSecret ? { app_secret: appSecret } : {}),
|
|
2023
1995
|
profile: process.env.BOT_PROFILE,
|
|
2024
1996
|
auth_mode: "lark-cli",
|
|
@@ -2621,11 +2593,16 @@ ensure_lark_cli_profile_locked() {
|
|
|
2621
2593
|
local app_id="$1"
|
|
2622
2594
|
local app_secret="$2"
|
|
2623
2595
|
local profile="$3"
|
|
2596
|
+
local tenant_brand="${4:-feishu}"
|
|
2624
2597
|
local auth_excludes
|
|
2625
2598
|
local required_scopes
|
|
2626
2599
|
|
|
2627
2600
|
initialize_feishu_scope_manifest
|
|
2628
2601
|
validate_feishu_user_auth_mode
|
|
2602
|
+
case "$tenant_brand" in
|
|
2603
|
+
feishu|lark) ;;
|
|
2604
|
+
*) agent_fail "unsupported tenant brand: $tenant_brand" ;;
|
|
2605
|
+
esac
|
|
2629
2606
|
|
|
2630
2607
|
if "$LARK_CLI_CMD" profile list 2>/dev/null | grep -F "\"$profile\"" >/dev/null 2>&1; then
|
|
2631
2608
|
agent_detail "lark-cli profile already exists: $profile"
|
|
@@ -2635,6 +2612,7 @@ ensure_lark_cli_profile_locked() {
|
|
|
2635
2612
|
printf '%s\n' "$app_secret" | "$LARK_CLI_CMD" profile add \
|
|
2636
2613
|
--name "$profile" \
|
|
2637
2614
|
--app-id "$app_id" \
|
|
2615
|
+
--brand "$tenant_brand" \
|
|
2638
2616
|
--app-secret-stdin
|
|
2639
2617
|
fi
|
|
2640
2618
|
|
|
@@ -2705,17 +2683,19 @@ select_existing_bot_or_create() {
|
|
|
2705
2683
|
local names=()
|
|
2706
2684
|
local profiles=()
|
|
2707
2685
|
local app_secrets=()
|
|
2686
|
+
local tenant_brands=()
|
|
2708
2687
|
local bot_labels=()
|
|
2709
|
-
local app_id name profile app_secret
|
|
2688
|
+
local app_id name profile app_secret tenant_brand
|
|
2710
2689
|
local index create_index selected
|
|
2711
2690
|
|
|
2712
2691
|
acquire_bot_selection_lock
|
|
2713
|
-
while IFS=$'\t' read -r app_id name profile app_secret; do
|
|
2692
|
+
while IFS=$'\t' read -r app_id name profile app_secret tenant_brand; do
|
|
2714
2693
|
[ -n "$app_id" ] || continue
|
|
2715
2694
|
app_ids+=("$app_id")
|
|
2716
2695
|
names+=("${name:-$app_id}")
|
|
2717
2696
|
profiles+=("$profile")
|
|
2718
2697
|
app_secrets+=("$app_secret")
|
|
2698
|
+
tenant_brands+=("${tenant_brand:-feishu}")
|
|
2719
2699
|
bot_labels+=("${name:-$app_id} ($app_id)")
|
|
2720
2700
|
done < <(load_bot_configs)
|
|
2721
2701
|
|
|
@@ -2754,11 +2734,12 @@ select_existing_bot_or_create() {
|
|
|
2754
2734
|
BOT_NAME="${names[$index]}"
|
|
2755
2735
|
LARK_CLI_PROFILE="${profiles[$index]}"
|
|
2756
2736
|
APP_SECRET="${app_secrets[$index]:-}"
|
|
2737
|
+
APP_TENANT_BRAND="${tenant_brands[$index]:-feishu}"
|
|
2757
2738
|
reserve_selected_bot "$APP_ID" "$LARK_CLI_PROFILE" "$BOT_NAME"
|
|
2758
2739
|
release_bot_selection_lock
|
|
2759
2740
|
agent_detail "using Feishu bot: $BOT_NAME ($APP_ID, profile=$LARK_CLI_PROFILE)"
|
|
2760
2741
|
agent_log "正在检查飞书授权..."
|
|
2761
|
-
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE"
|
|
2742
|
+
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE" "$APP_TENANT_BRAND"
|
|
2762
2743
|
}
|
|
2763
2744
|
|
|
2764
2745
|
register_feishu_app() {
|
|
@@ -2808,6 +2789,7 @@ const userScopes = splitList(process.env.FEISHU_APP_SCOPES_USER);
|
|
|
2808
2789
|
const tenantEvents = splitList(process.env.FEISHU_APP_EVENTS_TENANT);
|
|
2809
2790
|
const userEvents = splitList(process.env.FEISHU_APP_EVENTS_USER);
|
|
2810
2791
|
const appName = process.env.FEISHU_APP_PRESET_NAME || '飞书 CLI';
|
|
2792
|
+
let detectedTenantBrand = 'feishu';
|
|
2811
2793
|
|
|
2812
2794
|
function userLog(message) {
|
|
2813
2795
|
writeSync(5, `${message}\n`);
|
|
@@ -2860,15 +2842,24 @@ const result = await lark.registerApp({
|
|
|
2860
2842
|
},
|
|
2861
2843
|
onStatusChange(info) {
|
|
2862
2844
|
if (info.status === 'polling') return;
|
|
2845
|
+
if (info.status === 'domain_switched') detectedTenantBrand = 'lark';
|
|
2863
2846
|
console.log(`[aamp-one-click] registerApp status: ${info.status}`);
|
|
2864
2847
|
},
|
|
2865
2848
|
});
|
|
2866
2849
|
|
|
2867
|
-
|
|
2850
|
+
const reportedTenantBrand = result?.user_info?.tenant_brand;
|
|
2851
|
+
const tenantBrand = reportedTenantBrand === undefined || reportedTenantBrand === null || reportedTenantBrand === ''
|
|
2852
|
+
? detectedTenantBrand
|
|
2853
|
+
: reportedTenantBrand;
|
|
2854
|
+
const tenantBrandIsSupported = tenantBrand === 'feishu' || tenantBrand === 'lark';
|
|
2855
|
+
const openApiDomain = tenantBrand === 'lark' ? lark.Domain.Lark : lark.Domain.Feishu;
|
|
2856
|
+
|
|
2857
|
+
async function fetchRegisteredAppName(appId, appSecret, domain) {
|
|
2868
2858
|
try {
|
|
2869
2859
|
const client = new lark.Client({
|
|
2870
2860
|
appId,
|
|
2871
2861
|
appSecret,
|
|
2862
|
+
domain,
|
|
2872
2863
|
});
|
|
2873
2864
|
const response = await client.application.application.get({
|
|
2874
2865
|
path: { app_id: appId },
|
|
@@ -2882,11 +2873,14 @@ async function fetchRegisteredAppName(appId, appSecret) {
|
|
|
2882
2873
|
}
|
|
2883
2874
|
}
|
|
2884
2875
|
|
|
2885
|
-
const registeredAppName =
|
|
2876
|
+
const registeredAppName = tenantBrandIsSupported
|
|
2877
|
+
? await fetchRegisteredAppName(result.client_id, result.client_secret, openApiDomain)
|
|
2878
|
+
: '';
|
|
2886
2879
|
const resultPayload = {
|
|
2887
2880
|
app_id: result.client_id,
|
|
2888
2881
|
app_secret: result.client_secret,
|
|
2889
2882
|
app_name: registeredAppName || appName,
|
|
2883
|
+
tenant_brand: tenantBrand,
|
|
2890
2884
|
};
|
|
2891
2885
|
await import('node:fs/promises').then(({ writeFile }) => writeFile(process.env.AAMP_REGISTER_APP_RESULT_FILE, JSON.stringify(resultPayload)));
|
|
2892
2886
|
console.log(`[aamp-one-click] Feishu app registration completed: ${result.client_id}`);
|
|
@@ -2914,24 +2908,29 @@ NODE
|
|
|
2914
2908
|
APP_ID="$(node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(data.app_id || "")' "$register_result_file")"
|
|
2915
2909
|
APP_SECRET="$(node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(data.app_secret || "")' "$register_result_file")"
|
|
2916
2910
|
bot_name="$(node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(data.app_name || "")' "$register_result_file")"
|
|
2911
|
+
APP_TENANT_BRAND="$(node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(data.tenant_brand || "feishu")' "$register_result_file")"
|
|
2917
2912
|
: >"$register_result_file"
|
|
2918
2913
|
[ -n "$APP_ID" ] && [ -n "$APP_SECRET" ] || agent_fail "Feishu app registration returned incomplete credentials"
|
|
2914
|
+
case "$APP_TENANT_BRAND" in
|
|
2915
|
+
feishu|lark) ;;
|
|
2916
|
+
*) agent_fail "Feishu app registration returned unsupported tenant brand: $APP_TENANT_BRAND" ;;
|
|
2917
|
+
esac
|
|
2919
2918
|
|
|
2920
2919
|
bot_name="${bot_name:-$default_name}"
|
|
2921
2920
|
BOT_NAME="$bot_name"
|
|
2922
2921
|
if [ "$AGENT_EXECUTION_LOCATION" = "remote" ]; then
|
|
2923
2922
|
LARK_CLI_PROFILE=""
|
|
2924
2923
|
else
|
|
2925
|
-
LARK_CLI_PROFILE="$(task_profile_name_for_app_id "$APP_ID")"
|
|
2924
|
+
LARK_CLI_PROFILE="$(task_profile_name_for_app_id "$APP_ID" "$APP_TENANT_BRAND")"
|
|
2926
2925
|
source_lark_env
|
|
2927
|
-
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE"
|
|
2926
|
+
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE" "$APP_TENANT_BRAND"
|
|
2928
2927
|
fi
|
|
2929
2928
|
if [ "$AAMP_TASK_INTERNAL" = "true" ]; then
|
|
2930
2929
|
agent_detail "Feishu Bot 已授权:$BOT_NAME ($APP_ID)"
|
|
2931
2930
|
return 0
|
|
2932
2931
|
fi
|
|
2933
2932
|
acquire_bot_selection_lock
|
|
2934
|
-
save_bot_config "$bot_name" "$APP_ID" "$LARK_CLI_PROFILE" "$APP_SECRET"
|
|
2933
|
+
save_bot_config "$bot_name" "$APP_ID" "$LARK_CLI_PROFILE" "$APP_SECRET" "$APP_TENANT_BRAND"
|
|
2935
2934
|
reserve_selected_bot "$APP_ID" "$LARK_CLI_PROFILE" "$bot_name"
|
|
2936
2935
|
release_bot_selection_lock
|
|
2937
2936
|
agent_log "saved Feishu task profile config: $bot_name ($APP_ID, profile=$LARK_CLI_PROFILE)"
|
|
@@ -4941,9 +4940,9 @@ run_internal_register_binding() {
|
|
|
4941
4940
|
load_agent_metadata
|
|
4942
4941
|
register_feishu_app
|
|
4943
4942
|
if [ "$AGENT_EXECUTION_LOCATION" = "remote" ]; then
|
|
4944
|
-
emit_internal_result "{\"app_id\":\"$(json_escape "$APP_ID")\",\"app_secret\":\"$(json_escape "$APP_SECRET")\",\"display_name\":\"$(json_escape "$BOT_NAME")\",\"auth_mode\":\"app-secret\"}"
|
|
4943
|
+
emit_internal_result "{\"app_id\":\"$(json_escape "$APP_ID")\",\"app_secret\":\"$(json_escape "$APP_SECRET")\",\"display_name\":\"$(json_escape "$BOT_NAME")\",\"tenant_brand\":\"$(json_escape "$APP_TENANT_BRAND")\",\"auth_mode\":\"app-secret\"}"
|
|
4945
4944
|
else
|
|
4946
|
-
emit_internal_result "{\"app_id\":\"$(json_escape "$APP_ID")\",\"app_secret\":\"$(json_escape "$APP_SECRET")\",\"display_name\":\"$(json_escape "$BOT_NAME")\",\"lark_cli_profile\":\"$(json_escape "$LARK_CLI_PROFILE")\",\"auth_mode\":\"lark-cli\"}"
|
|
4945
|
+
emit_internal_result "{\"app_id\":\"$(json_escape "$APP_ID")\",\"app_secret\":\"$(json_escape "$APP_SECRET")\",\"display_name\":\"$(json_escape "$BOT_NAME")\",\"tenant_brand\":\"$(json_escape "$APP_TENANT_BRAND")\",\"lark_cli_profile\":\"$(json_escape "$LARK_CLI_PROFILE")\",\"auth_mode\":\"lark-cli\"}"
|
|
4947
4946
|
fi
|
|
4948
4947
|
}
|
|
4949
4948
|
|
|
@@ -5002,11 +5001,13 @@ run_internal_ensure_profile() {
|
|
|
5002
5001
|
APP_ID="$(binding_json_field bot.app_id)"
|
|
5003
5002
|
APP_SECRET="$(binding_json_field bot.app_secret)"
|
|
5004
5003
|
BOT_NAME="$(binding_json_field bot.display_name)"
|
|
5004
|
+
APP_TENANT_BRAND="$(binding_json_field bot.tenant_brand)"
|
|
5005
|
+
APP_TENANT_BRAND="${APP_TENANT_BRAND:-feishu}"
|
|
5005
5006
|
LARK_CLI_PROFILE="$(binding_json_field bot.lark_cli_profile)"
|
|
5006
5007
|
[ -n "$APP_ID" ] && [ -n "$APP_SECRET" ] && [ -n "$LARK_CLI_PROFILE" ] || agent_fail "binding is missing Feishu credentials or profile"
|
|
5007
5008
|
AAMP_TASK_INTERNAL_BINDING_JSON=""
|
|
5008
5009
|
source_lark_env
|
|
5009
|
-
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE"
|
|
5010
|
+
ensure_lark_cli_profile "$APP_ID" "$APP_SECRET" "$LARK_CLI_PROFILE" "$APP_TENANT_BRAND"
|
|
5010
5011
|
APP_SECRET=""
|
|
5011
5012
|
emit_internal_result "{\"lark_cli_bin\":\"$(json_escape "$LARK_CLI_CMD")\",\"lark_cli_config_dir\":\"$(json_escape "${LARKSUITE_CLI_CONFIG_DIR:-}")\"}"
|
|
5012
5013
|
}
|