feat(tui): workspace 项目模式 + @ 文件引用补全(v2/v3) (#607)

* feat(tui): workspace 项目模式 + @ 文件引用补全(v2/v3)

- workspace: /workspace 设/off/picker、junction 复用 project_mode 记忆、
  per-session(v2)/进程级(v3)、/continue 恢复、session map 持久化绑定状态
- @ 补全(completion-only): 子序列模糊 + path-like 目录补全(~/ / ./ C:\)、
  提交期 @路径作为普通文本交 agent
- v3 filterable 焦点链 picker(输入框作焦点环对象、free_input)
- 新增共享模块 at_complete.py / workspace_cmd.py;核心零改动

* feat(tui): @ 路径绝对化 + 默认根=temp + 未绑显示完整路径

- 默认根 os.getcwd() → agent 工作目录 <GA根>/temp(与 file_read/code_run 一致、不随启动 cwd 飘)
- 提交期 @相对 → @绝对(display 保留相对短路径),让 agent file_read(相对自身 cwd)找得到
- 未绑 workspace 时候选显示完整路径(根不直观);索引忽略 model_responses 会话日志噪音
- 启动预热 temp 索引 + candidates_for 惰性兜底(任何根首次访问自动建)
This commit is contained in:
nianyucatfish authored and GitHub committed 2026-06-14 09:10:04 +08:00
1 parent 1d2f3597eb
commit 84254ad762
6 files changed
+1516 -55

No files matched your search

+14 -3
View File
@@ -41,9 +41,20 @@ def _cleanup_stale_anchors():
_cleanup_stale_anchors()
def _active_project():
"""读文件锚,返回当前激活的项目名;未激活返回 None。
def _active_project(ctx=None):
"""返回当前激活的项目名;未激活返回 None。
兼容策略:
- 新 TUI 多会话可在当前 GenericAgent 实例上设置 _ga_project_mode_name。
只要该属性存在,就以它为准;值为 None/空串表示该 agent 普通模式。
- 其它 UI / 旧 SOP 不设置该属性,继续读取 pid 键控文件锚。
异常不在此捕获——hooks.trigger 统一捕获并打印,保持可观测。"""
parent = None
if isinstance(ctx, dict):
handler = ctx.get('handler')
parent = getattr(handler, 'parent', None)
if parent is not None and hasattr(parent, '_ga_project_mode_name'):
return getattr(parent, '_ga_project_mode_name', None) or None
if not os.path.isfile(_ANCHOR):
return None
return open(_ANCHOR, encoding='utf-8').read().strip() or None
@@ -101,7 +112,7 @@ def _build_injection(name):
@hooks.register('agent_before')
def inject_project_context(ctx):
"""每个用户轮起始时,若项目模式激活,把项目上下文追加到 user message。"""
name = _active_project()
name = _active_project(ctx)
if not name:
return # 未激活,普通模式,什么都不做