import{t as e}from"./lark-logger-xpMKNNtY.mjs";import{existsSync as t,mkdirSync as n,readFileSync as r,writeFileSync as i}from"node:fs";import{join as a}from"node:path";import{homedir as o}from"node:os";import{execSync as s,spawn as c}from"node:child_process";import{createInterface as l}from"node:readline";import*as u from"@larksuiteoapi/node-sdk";import d from"qrcode-terminal";async function f(e){let t=await(e.registerApp??p)({source:e.source??`larkpal`,signal:e.signal,onQRCodeReady:e.onQRCodeReady,onStatusChange:e.onStatusChange});if(!t.client_id||!t.client_secret)throw Error(`飞书应用创建完成但未返回 App ID 或 App Secret`);return await e.saveCredentials({appId:t.client_id,appSecret:t.client_secret}),{appId:t.client_id,appSecret:t.client_secret,creatorOpenId:t.user_info?.open_id,tenantBrand:t.user_info?.tenant_brand}}async function p(e){return u.registerApp(e)}function m(e){return[`  请扫码创建飞书智能体应用，或打开下面的链接：`,``,y(e.url,e.createQRCode??v),`  ${e.url}`,`  链接有效期 ${e.expireIn} 秒。`].join(`
`)}function h(e){switch(e){case`codex-app-server`:return[`已选择 Codex app-server 作为 agent runtime。`,`启动前请确保 Codex CLI 可用：codex`,`启动配置：LARKPAL_RUNTIME=codex-app-server`].join(`
`);case`larkpal-agent`:return[`已选择 larkpal-agent 作为 agent runtime。`,`启动前请配置 larkpal-agent 所需的 LLM 和 scenario provider 环境变量。`,`启动配置：LARKPAL_RUNTIME=larkpal-agent`].join(`
`);case`claude-code`:return[`已选择 Claude Code 作为 agent runtime。`,`启动前请确保 Claude Code CLI 可用：claude`,`启动配置：LARKPAL_RUNTIME=claude-code`].join(`
`)}}function g(e){return[`Agent runtime 选择`,``,`  [1] Claude Code (claude-code)${e===`claude-code`?`（当前）`:``}`,`  [2] Codex app-server (codex-app-server)${e===`codex-app-server`?`（当前）`:``}`,`  [3] larkpal-agent${e===`larkpal-agent`?`（当前）`:``}`].join(`
`)}function _(e,t){let n=e.trim().toLowerCase();return n?n===`1`||n===`claude`||n===`claude-code`?`claude-code`:n===`2`||n===`codex`||n===`codex-app-server`?`codex-app-server`:n===`3`||n===`larkpal-agent`?`larkpal-agent`:t:t}function v(e){let t=``;return d.setErrorLevel(`L`),d.generate(e,{small:!0},e=>{t=e}),t.trimEnd()}function y(e,t){try{return t(e).trimEnd()||`  [二维码渲染失败，请使用下方链接]`}catch{return`  [二维码渲染失败，请使用下方链接]`}}function b(e){let t=e.detectCli(`lark-cli`),n=x(e.runtimeName),r=n?e.detectCli(n):{installed:!0},i=[];return n&&!r.installed&&i.push(n===`codex`?`OpenAI Codex CLI is not installed. Feishu app credentials can still be configured now, but service startup with LARKPAL_RUNTIME=codex-app-server will require codex later.`:`Claude Code is not installed. Feishu app credentials can still be configured now, but service startup with the default runtime will require Claude Code later.`),t.installed||i.push(`lark-cli is not installed. Basic Feishu bot chat can be configured with app credentials, but execution-layer tools for documents, calendars, mail, tasks, and personal data will require lark-cli later.`),{canConfigureFeishuCredentials:!0,larkCli:{...t,ready:t.installed,requiredForBasicChat:!1},runtime:{...r,ready:r.installed,name:e.runtimeName,cliName:n??e.runtimeName},warnings:i}}function x(e){if(e===`codex-app-server`)return`codex`;if(e!==`larkpal-agent`)return`claude`}const S=e(`init`),C=`\x1B[36m`,w=`\x1B[32m`,T=`\x1B[33m`,E=`\x1B[31m`,D=`\x1B[1m`,O=`\x1B[2m`,k=`\x1B[0m`,A=a(o(),`.larkpal`),j=a(A,`credentials.json`);function M(e,t){return new Promise(n=>{e.question(t,e=>n(e.trim()))})}function N(e){try{return!!s(`which ${e}`,{encoding:`utf-8`,timeout:5e3}).trim()}catch{return!1}}function P(){try{let e=s(`lark-cli config show`,{encoding:`utf-8`,timeout:1e4,stdio:[`pipe`,`pipe`,`pipe`]}).match(/\{[\s\S]*\}/);if(e)return JSON.parse(e[0]).appId||null}catch{}return null}function F(e,r){try{return t(A)||(n(A,{recursive:!0}),S.info(`创建 LarkPal 配置目录`,{path:A})),i(j,JSON.stringify({app_id:e,app_secret:r},null,2)+`
`,{encoding:`utf-8`,mode:384}),S.info(`凭证已写入`,{path:j,appId:e}),!0}catch(e){let t=e instanceof Error?e.message:String(e);return S.error(`写入凭证文件失败`,{path:j,error:t}),!1}}async function I(e){if(!F(e.appId,e.appSecret))throw Error(`凭证保存失败`)}function L(){if(!t(j))return null;try{let e=r(j,`utf-8`),t=JSON.parse(e);if(t.app_id&&t.app_secret)return{appId:t.app_id,appSecret:t.app_secret}}catch{}return null}function R(e){console.log(`\n${D}🔍 检查前置依赖${k}\n`);let t=b({runtimeName:e,detectCli:e=>({installed:N(e)})});t.runtime.ready?console.log(`  ${w}✅ ${t.runtime.cliName} 已安装${k}`):console.log(`  ${T}⚠️  ${t.runtime.cliName} 未安装${k}`),t.larkCli.ready?console.log(`  ${w}✅ lark-cli 已安装${k}`):console.log(`  ${T}⚠️  lark-cli 未安装（基础飞书连接不阻塞）${k}`);for(let e of t.warnings)console.log(`  ${O}${e}${k}`);console.log()}async function z(e){let t=K(process.env.LARKPAL_RUNTIME);console.log(`\n${D}🤖 Agent runtime 配置${k}\n`),console.log(g(t)),console.log();let n=_(await M(e,`  请选择 [1/2/3]（默认当前）: `),t);return process.env.LARKPAL_RUNTIME=n,console.log(`\n${h(n)}\n`),S.info(`用户选择 agent runtime`,{runtimeName:n}),n}function B(){return new Promise(e=>{console.log(`\n${O}正在启动 lark-cli config init ...${k}\n`),S.info(`启动子进程: lark-cli config init`);let t=``,n=c(`lark-cli`,[`config`,`init`],{stdio:[`inherit`,`pipe`,`pipe`]});n.stdout?.on(`data`,e=>{let n=e.toString();t+=n,process.stdout.write(n)}),n.stderr?.on(`data`,e=>{let n=e.toString();t+=n,process.stderr.write(n)}),n.on(`error`,t=>{S.error(`lark-cli config init 启动失败`,{error:t.message}),console.log(`\n${E}启动 lark-cli config init 失败: ${t.message}${k}`),e(null)}),n.on(`close`,n=>{if(S.info(`lark-cli config init 执行完毕`,{exitCode:n,output:t.substring(0,500)}),n===0){let n=t.match(/App\s*ID:\s*(\S+)/i)?.[1]||null;n||=P(),n?(S.info(`lark-cli config init 成功`,{appId:n}),console.log(`\n${w}✅ 飞书应用创建成功${k} ${O}(App ID: ${n})${k}`)):console.log(`\n${w}✅ lark-cli config init 完成${k}`),e(n)}else console.log(`\n${T}⚠️  lark-cli config init 退出码: ${n}${k}`),e(null)})})}async function V(e,t){console.log(`\n${D}🔑 输入 App Secret${k}\n`),console.log(`  ${O}lark-cli 已完成应用配置，但 LarkPal 还需要 App Secret 来启动服务。${k}`),console.log(`  ${O}请在飞书开放平台的应用管理页面（凭证与基础信息）中复制 App Secret：${k}\n`),console.log(`    ${C}https://open.feishu.cn/app/${t}${k}\n`);let n=await M(e,`  App Secret: `);return n?F(t,n)?(console.log(`\n${w}✅ 凭证已保存${k} ${O}(${j})${k}`),!0):(console.log(`\n${E}凭证保存失败${k}`),!1):(console.log(`\n${E}App Secret 不能为空${k}`),!1)}async function H(e){console.log(`\n${D}📝 手动输入飞书应用凭证${k}\n`),console.log(`  ${O}你可以在飞书开放平台 (https://open.feishu.cn) 的应用管理页面找到这些信息。${k}\n`);let t=await M(e,`  App ID: `);if(!t)return console.log(`\n${E}App ID 不能为空${k}`),!1;let n=await M(e,`  App Secret: `);return n?F(t,n)?(console.log(`\n${w}✅ 凭证已保存${k} ${O}(${j})${k}`),!0):(console.log(`\n${E}凭证保存失败${k}`),!1):(console.log(`\n${E}App Secret 不能为空${k}`),!1)}async function U(){console.log(`\n${D}📱 扫码创建飞书智能体应用${k}\n`),console.log(`  LarkPal 会通过飞书官方一键创建应用能力获取 App ID 和 App Secret。`),console.log(`  ${O}这一步只配置应用凭据；个人日历、文档、邮件等能力后续通过 lark-cli auth login 授权。${k}\n`);try{let e=await f({saveCredentials:I,onQRCodeReady:({url:e,expireIn:t})=>{console.log(m({url:e,expireIn:t})),console.log()},onStatusChange:({status:e})=>{e===`polling`?console.log(`  ${O}等待飞书确认中...${k}`):e===`slow_down`?console.log(`  ${O}飞书要求降低轮询频率，继续等待...${k}`):e===`domain_switched`&&console.log(`  ${O}已根据租户切换认证域名，继续等待...${k}`)},source:`larkpal-init`});return console.log(`\n${w}✅ 飞书应用创建并保存成功${k} ${O}(App ID: ${e.appId})${k}`),!0}catch(e){return console.log(`\n${E}扫码创建飞书应用失败: ${e instanceof Error?e.message:String(e)}${k}`),!1}}async function W(e){if(process.env.LARK_APP_ID&&process.env.LARK_APP_SECRET)return console.log(`${w}✅ 飞书应用凭证已通过环境变量配置${k}`),S.info(`凭证已通过环境变量配置`),!0;let t=L();if(t)return console.log(`${w}✅ 飞书应用凭证已配置${k} ${O}(App ID: ${t.appId})${k}`),S.info(`LarkPal 凭证文件已存在`,{appId:t.appId}),!0;let n=P();if(n)return console.log(`${w}✅ 飞书应用已配置${k} ${O}(App ID: ${n})${k}`),console.log(`\n  ${T}但 LarkPal 还需要 App Secret 才能启动。${k}`),V(e,n);console.log(`${D}📋 飞书应用配置${k}\n`),console.log(`  LarkPal 需要飞书应用凭据才能进入飞书会话。推荐使用飞书官方扫码创建应用能力：
`),console.log(`  ${O}[1] 扫码创建飞书智能体应用（推荐）${k}`),console.log(`  ${O}[2] 手动输入 App ID 和 App Secret${k}`),console.log(`  ${O}[3] 使用 lark-cli config init（兼容旧流程）${k}\n`);let r=await M(e,`  请选择 [1/2/3]（默认 1）: `),i=r===`2`?2:r===`3`?3:1;if(S.info(`用户选择凭证配置方式`,{option:i}),i===1)return await U()?!0:(console.log(`\n  ${T}扫码创建未完成，是否手动输入凭证？${k}`),(await M(e,`  手动输入？ [y/N]: `)).toLowerCase()===`y`?H(e):!1);if(i===3){let t=await B();return t?V(e,t):(console.log(`\n  ${T}lark-cli 配置未成功，是否手动输入凭证？${k}`),(await M(e,`  手动输入？ [y/N]: `)).toLowerCase()===`y`?H(e):!1)}return H(e)}async function G(){console.log(`\n${D}${C}╔══════════════════════════════════════╗${k}`),console.log(`${D}${C}║         LarkPal 初始化向导           ║${k}`),console.log(`${D}${C}╚══════════════════════════════════════╝${k}\n`),S.info(`开始交互式初始化流程`);let e=l({input:process.stdin,output:process.stdout}),t,n;try{n=await z(e),R(n),t=await W(e)}finally{e.close()}return t?(console.log(`\n${D}${w}🎉 初始化完成！${k}\n`),console.log(`  ${O}下一步:${k}`),console.log(`    ${h(n)}`),console.log(`    运行 ${C}larkpal${k} 启动服务\n`),S.info(`交互式初始化流程完成`),0):(console.log(`\n${E}凭证配置未完成。你可以稍后运行 ${C}larkpal init${E} 重新配置。${k}\n`),1)}function K(e){return e===`codex-app-server`||e===`larkpal-agent`||e===`claude-code`?e:`claude-code`}export{G as runInteractiveInit};