Skip to content

增加导入cli工具的会话能查看电脑端正在使用的会话内容#74

Open
lusile2024 wants to merge 6 commits intoshuyu-labs:mainfrom
lusile2024:main
Open

增加导入cli工具的会话能查看电脑端正在使用的会话内容#74
lusile2024 wants to merge 6 commits intoshuyu-labs:mainfrom
lusile2024:main

Conversation

@lusile2024
Copy link
Copy Markdown

增加导入cli工具的会话能查看电脑端正在使用的会话内容
修复测试发现的bug

haiyan.lu and others added 6 commits March 22, 2026 16:31
Merge indexed and transcript-based discovery for external CLI sessions, add raw transcript history recovery, and document the updated workflow and local dev port.
Remember each user's Feishu bot start/stop preference, restore enabled bots on service startup, and surface the persisted restart behavior in admin status.
Recover missing CLI thread IDs from imported session titles and backfill them into ChatSession so imported sessions can reopen native histories. Also read Codex and Claude transcript/index files with shared access to avoid empty histories while the CLI is still writing.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 旨在让 WebCode 支持“发现/导入本机已有 CLI 会话(OpenCode/Codex/Claude Code)”,并能基于 CLI 原生 transcript 回放最近历史消息;同时修复测试发现的问题,并增强飞书机器人运行状态的持久化与自动恢复能力。

Changes:

  • 增加外部 CLI 会话的发现/导入能力(Web 端模态框 + API + 飞书卡片交互),并支持 /history 查看原生历史。
  • 会话模型与持久化增强:新增 CliThreadId、工作区绑定回写、CLI thread id 恢复逻辑与索引/增量字段初始化。
  • 飞书机器人运行状态增强:持久化“是否自动恢复连接”和 LastStartedAt,并在 HostedService 启动时自动恢复。

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
appsettings.json 端口从 5000 调整到 6001
WebCodeCli/appsettings.json 端口从 5000 调整到 6001
WebCodeCli/Properties/launchSettings.json 本地启动端口/sslPort 调整到 6001/6002
WebCodeCli/Program.cs 启用 UseStaticWebAssets(),避免静态资源 404
WebCodeCli/wwwroot/Resources/Localization/zh-CN.json 新增/整理本地化文案(但修改位置有问题)
WebCodeCli/wwwroot/Resources/Localization/en-US.json 新增/整理本地化文案(但修改位置有问题)
WebCodeCli/wwwroot/Resources/Localization/ja-JP.json 新增/整理本地化文案(但修改位置有问题)
WebCodeCli/wwwroot/Resources/Localization/ko-KR.json 新增/整理本地化文案(但修改位置有问题)
WebCodeCli/Pages/CodeAssistantMobile.razor.cs 增加 /history 命令处理、CLI thread id 恢复、导入模态框打开/回调
WebCodeCli/Pages/CodeAssistantMobile.razor 增加“导入本地会话”入口与导入模态框组件引用
WebCodeCli/Pages/CodeAssistant.razor.cs 增加 /history 命令处理、CLI thread id 恢复、侧边栏导入入口
WebCodeCli/Pages/CodeAssistant.razor 增加侧边栏“导入本地会话”入口与导入模态框组件引用
WebCodeCli/Controllers/SessionController.cs 新增外部 CLI 会话发现/导入 API
WebCodeCli/Controllers/AdminController.cs Feishu bot 状态 DTO 增加 ShouldAutoStart
WebCodeCli/Components/ExternalCliSessionImportModal.razor 新增“外部 CLI 会话导入”模态框 UI 与交互逻辑
WebCodeCli/Components/EnvironmentVariableConfigModal.razor 环境变量读写支持按用户覆盖(传入 username)
WebCodeCli/Components/AdminUserManagementModal.razor.cs 管理弹窗状态模型增加 ShouldAutoStart
WebCodeCli/Components/AdminUserManagementModal.razor 展示“服务重启后自动恢复”状态
WebCodeCli.Domain/Repositories/Base/UserFeishuBotConfig/UserFeishuBotConfigEntity.cs 新增 AutoStartEnabledLastStartedAt 持久化字段
WebCodeCli.Domain/Repositories/Base/ChatSession/IChatSessionRepository.cs 增加按 tool/thread 查找、更新 threadId、更新工作区绑定等接口
WebCodeCli.Domain/Repositories/Base/ChatSession/ChatSessionRepository.cs 实现新增查询/更新方法(导入/恢复依赖)
WebCodeCli.Domain/Repositories/Base/ChatSession/ChatSessionEntity.cs 新增 CliThreadId 字段
WebCodeCli.Domain/Domain/Service/UserFeishuBotRuntimeStatus.cs 运行时状态增加 ShouldAutoStart
WebCodeCli.Domain/Domain/Service/UserFeishuBotRuntimeService.cs 自动恢复逻辑、持久化运行偏好、Stop 行为区分手动/宿主停止
WebCodeCli.Domain/Domain/Service/UserFeishuBotConfigService.cs 增加自启候选查询与运行偏好更新方法
WebCodeCli.Domain/Domain/Service/UserContextService.cs 用户名解析优先已认证用户,避免 override 覆盖登录态
WebCodeCli.Domain/Domain/Service/SessionHistoryManager.cs SessionHistory 与 Entity 映射增加 CliThreadId/IsCustomWorkspace
WebCodeCli.Domain/Domain/Service/IUserFeishuBotConfigService.cs 接口增加自启候选/运行偏好更新能力
WebCodeCli.Domain/Domain/Service/ExternalCliSessionService.cs 新增外部会话发现/导入核心逻辑(含白名单与占用约束)
WebCodeCli.Domain/Domain/Service/ExternalCliSessionHistoryService.cs 新增外部会话历史读取与解析(Codex/Claude/OpenCode)
WebCodeCli.Domain/Domain/Service/CliToolEnvironmentService.cs 环境变量继承 + 用户覆盖叠加(支持显式移除继承值)
WebCodeCli.Domain/Domain/Service/CliExecutorService.cs CLI thread id 与工作区恢复/回写增强
WebCodeCli.Domain/Domain/Service/Channels/FeishuCommandService.cs 增加 /history 内置命令
WebCodeCli.Domain/Domain/Service/Channels/FeishuCardActionService.cs 飞书端增加发现/导入外部会话、切换后回显原生历史、支持 /history
WebCodeCli.Domain/Domain/Model/SessionHistory.cs 模型增加 CliThreadId
WebCodeCli.Domain/Domain/Model/ExternalCliSessionSummary.cs 新增外部会话发现/导入 DTO
WebCodeCli.Domain/Domain/Model/ExternalCliHistoryMessage.cs 新增外部历史消息 DTO
WebCodeCli.Domain/Domain/Model/Channels/FeishuHelpCardAction.cs 飞书卡片 action DTO 增加导入所需字段
WebCodeCli.Domain/Common/Extensions/DatabaseInitializer.cs ChatSession 增量字段保障、从标题回填 thread id、增加索引
WebCodeCli.Domain/Common/CliThreadIdRecoveryHelper.cs 新增从导入标题恢复 thread id 的辅助逻辑
WebCodeCli.Domain.Tests/UserFeishuBotRuntimeServiceTests.cs 覆盖自动恢复/持久化偏好相关测试
WebCodeCli.Domain.Tests/UserContextServiceTests.cs 覆盖用户名优先级修复测试
WebCodeCli.Domain.Tests/FeishuCommandServiceTests.cs 覆盖 /history 命令存在性测试
WebCodeCli.Domain.Tests/FeishuChannelServiceTests.cs 适配接口新增方法的桩实现
WebCodeCli.Domain.Tests/FeishuCardActionServiceTests.cs 覆盖飞书历史读取、发现外部会话分页等测试
WebCodeCli.Domain.Tests/ExternalCliSessionServiceTests.cs 覆盖 Claude Code index+jsonl 合并发现逻辑测试
WebCodeCli.Domain.Tests/ExternalCliSessionHistoryServiceTests.cs 覆盖 Codex/Claude/OpenCode transcript 解析测试
WebCodeCli.Domain.Tests/CliToolEnvironmentServiceTests.cs 覆盖用户覆盖与继承移除语义测试
WebCodeCli.Domain.Tests/CliExecutorServiceTests.cs 覆盖从导入标题恢复 thread id 的测试
README.md 文档补充外部会话导入/历史恢复能力与端口更新

Comment on lines +393 to +398
"save": "保存",
"profilesTitle": "設定プロファイル",
"profilesDesc": "複数の環境変数プロファイルを作成して、AI設定をすばやく切り替えられます",
"addProfile": "新規プロファイル",
"profileNamePlaceholder": "プロファイル名(例: OpenAI / DeepSeek / Anthropic)",
"activateProfile": "有効化",
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These localization edits are being made under wwwroot/Resources/Localization, but the project copies WebCodeCli/Resources/Localization/*.json into this directory at build time, so changes here will be overwritten. Please move the updates to WebCodeCli/Resources/Localization/ja-JP.json (and keep the other 3 languages in sync).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +393 to +398
"save": "저장",
"profilesTitle": "구성 프로파일",
"profilesDesc": "여러 환경 변수 프로파일을 생성하여 AI 구성을 빠르게 전환할 수 있습니다",
"addProfile": "새 프로파일",
"profileNamePlaceholder": "프로파일 이름 (예: OpenAI / DeepSeek / Anthropic)",
"activateProfile": "활성화",
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These localization edits are being made under wwwroot/Resources/Localization, but the project copies WebCodeCli/Resources/Localization/*.json into this directory at build time, so changes here will be overwritten. Please move the updates to WebCodeCli/Resources/Localization/ko-KR.json (and keep the other 3 languages in sync).

Copilot generated this review using guidance from repository custom instructions.
return "opencode";
}

return toolId.Trim();
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NormalizeToolId currently returns toolId.Trim() without normalizing casing, but GetRecentMessagesAsync switches on lowercase tool IDs ("codex"/"claude-code"/"opencode"). If a caller passes a different casing (e.g. "Codex"), this will silently return an empty history. Consider normalizing to lower-invariant (and trimming) here, or making the switch case-insensitive.

Suggested change
return toolId.Trim();
return toolId.Trim().ToLowerInvariant();

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +174
try
{
var occupied = await _chatSessionRepository.GetByToolAndCliThreadIdAsync(item.ToolId, item.CliThreadId);
if (occupied != null)
{
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DiscoverAsync checks occupation by calling GetByToolAndCliThreadIdAsync inside the per-session loop, which can result in many DB queries (N+1) when maxCount is large (e.g. the Feishu card uses up to 1000). Consider preloading occupied (ToolId, CliThreadId) for the discovered set in a single query (or providing a batch repository API) and filtering in-memory.

Copilot uses AI. Check for mistakes.
Comment on lines +197 to +201
var sessionRepo = scope.ServiceProvider.GetService<IChatSessionRepository>();
var session = sessionRepo?.GetByIdAsync(sessionId).GetAwaiter().GetResult();
var threadId = session?.CliThreadId;

if (string.IsNullOrWhiteSpace(threadId))
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetCliThreadId performs synchronous blocking waits on async DB calls (GetByIdAsync/GetBySessionIdAsync) via GetAwaiter().GetResult(). Under load this can contribute to thread-pool starvation and is risky if called from contexts with a synchronization context. Consider introducing an async version (e.g. GetCliThreadIdAsync) and using it from async call sites, or using truly synchronous data access for this fallback path.

Copilot uses AI. Check for mistakes.
Comment on lines +2117 to +2121
private async Task<bool> TryHandleHistoryCommandAsync(string message)
{
if (!IsHistoryCommand(message))
{
return false;
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /history handling logic (IsHistoryCommand / BuildExternalCliHistoryText / TrimHistoryContent) is duplicated between CodeAssistant and CodeAssistantMobile. Consider extracting this into a shared helper/service to avoid divergence and to keep formatting and limits consistent across clients.

Copilot uses AI. Check for mistakes.
Comment on lines +346 to +350
"save": "Save",
"profilesTitle": "Configuration Profiles",
"profilesDesc": "Create multiple environment variable profiles to quickly switch between AI configurations",
"addProfile": "New Profile",
"profileNamePlaceholder": "Profile name, e.g. OpenAI / DeepSeek / Anthropic",
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These localization edits are being made under wwwroot/Resources/Localization, but the project copies WebCodeCli/Resources/Localization/*.json into this directory at build time, so changes here will be overwritten. Please move the updates to WebCodeCli/Resources/Localization/en-US.json (and keep the other 3 languages in sync).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +348 to +352
"save": "保存",
"profilesTitle": "配置方案",
"profilesDesc": "创建多套环境变量方案,一键切换不同的 AI 配置",
"addProfile": "新建方案",
"profileNamePlaceholder": "方案名称,如 OpenAI / DeepSeek / Anthropic",
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These localization edits are being made under wwwroot/Resources/Localization, but the project copies WebCodeCli/Resources/Localization/*.json into this directory at build time, so changes here will be overwritten. Please move the updates to WebCodeCli/Resources/Localization/zh-CN.json (and keep the other 3 languages in sync).

Copilot generated this review using guidance from repository custom instructions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants