@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. Its existing Node.js/npm dependency
9
- installation flow is unchanged:
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
- async function createDraft(agents, selectedAppIds) {
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.2"
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
- print_node_toolchain_help() {
691
+ print_missing_node_help() {
696
692
  cat >&2 <<'HELP'
697
693
 
698
- Automatic Node.js/npm installation did not complete.
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
- HELP
706
- }
696
+ 请安装 Node.js LTS:
697
+ https://nodejs.org/en/download
707
698
 
708
- try_install_node_toolchain() {
709
- local node_path
710
- node_path="$(command -v node || true)"
699
+ 安装完成后:
700
+ 1. 重新打开终端
701
+ 2. 执行 node -v && npm -v 验证
702
+ 3. 重新运行本安装命令
711
703
 
712
- if command -v volta >/dev/null 2>&1 && { [ -z "$node_path" ] || [[ "$node_path" == *"/.volta/"* ]]; }; then
713
- agent_log "installing Node.js/npm with Volta"
714
- volta install node npm
715
- return $?
716
- fi
704
+ HELP
705
+ }
717
706
 
718
- if command -v fnm >/dev/null 2>&1 && { [ -z "$node_path" ] || [[ "$node_path" == *"/.fnm/"* ]]; }; then
719
- agent_log "installing Node.js/npm with fnm"
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
- local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
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
- if command -v brew >/dev/null 2>&1; then
736
- local formula="node"
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
- if brew list --versions "$formula" >/dev/null 2>&1; then
744
- agent_log "reinstalling $formula with Homebrew to restore npm/npx"
745
- run_brew reinstall "$formula"
746
- else
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
- agent_log "no supported Node.js installer found; tried Volta, fnm, nvm, and Homebrew"
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" ] && [ -n "$NPX_BIN" ]; then
730
+ if [ -n "$NPM_BIN" ]; then
760
731
  configure_npm_registry
761
732
  return 0
762
733
  fi
763
734
 
764
- agent_log "npm/npx not found; installing Node.js/npm automatically"
765
- if ! try_install_node_toolchain; then
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
- printf 'aamp-feishu-task-%s' "$app_id"
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
- BOT_CONFIG_FILE="$BOT_CONFIG_FILE" BOT_NAME="$bot_name" BOT_APP_ID="$app_id" BOT_PROFILE="$profile" BOT_APP_SECRET="$app_secret" 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 '
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
- async function fetchRegisteredAppName(appId, appSecret) {
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 = await fetchRegisteredAppName(result.client_id, result.client_secret);
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
  }
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "README.md"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.1.1-dev.2",
9
+ "version": "0.1.1-dev.4",
10
10
  "description": "One-click manager for local Agent and Feishu Bot bindings.",
11
11
  "type": "module",
12
12
  "bin": {