Skip to content

[feat] project scope 安装后隔离 user scope(pull/recall 不再处理 user,uninstall 提示 scope) #73

Description

@jeff-r2026

背景

当前 teamai 对 user scope 与 project scope 采用「叠加」语义:只要装了 project scope,user scope 仍会被一起处理。具体表现:

  • pullsrc/pull.ts pull(),Scheme B):永远先 pull user scope,再检测 cwd 是否有 .teamai/config.yaml (scope: project),有就额外再 pull 一遍 project。即两个 scope 都会执行。
  • recallsrc/recall.ts recall()):同时检索 user + project 两个索引并合并去重(project 优先),输出 Top5。
  • auto-recallsrc/auto-recall.ts):已通过 autoDetectInit() 选择单一 scope 的索引(project 存在时优先 project),实际上已经是隔离的。
  • uninstallsrc/uninstall.ts uninstall()):已通过 autoDetectInit() 选择单一 scope(project 存在时优先 project),但未在交互/摘要中告知用户当前卸载的是哪个 scope,存在误删风险。

这造成各路径行为不一致,且在「项目已经是一套自洽的 project scope 知识库」的场景下,user scope 的团队通用资源会被一并拉取/检索,污染项目上下文,也增加同步耗时。相关历史:#58 解决了 project scope 下的「数据落点」隔离(索引/votes 写到 <projectRoot>/.teamai),但没有解决「project 装了仍会拉/查 user」的问题。

需求

当检测到当前目录存在 project scope 安装时,user scope 不再随 pull/recall 一起处理;uninstall 需明确提示作用的 scope。

  • 触发方式:改默认行为,无需新增配置项或 CLI flag。判定依据沿用 detectProjectConfig()(cwd 下 .teamai/config.yamlscope: project)。
  • 当 cwd 没有 project scope 时,行为保持不变(仍走 user scope)。

期望行为

命令 无 project scope(现状不变) 有 project scope(本次变更)
teamai pull 拉 user scope 只拉 project scope,跳过 user;并打印提示「检测到 project scope,已跳过 user scope」
teamai recall 查 user 索引 只查 project 索引,跳过 user
teamai auto-recall 用 user 索引 用 project 索引(已隔离,保持)
teamai uninstall 卸载 user scope 卸载 project scope;摘要中明确标注卸载的 scope 与路径

已确认决策

  1. 跨团队 source 技能(pullSources):project-only 模式下仍要拉。pull 即便短路掉 user scope 的资源同步,pullSources 仍照常执行(保持团队外部 source 技能可用)。
  2. reconcile 只作用于 project。 reconcileHooksAllScopes 在 project 命中时只对 project scope 做 hooks/builtin reconcile,不再 reconcile user 目录。
  3. pull 输出提示。 project 命中并跳过 user 时,打印一行明确提示(如:检测到 project scope,已跳过 user scope),避免用户困惑。
  4. uninstall 提示卸载哪个 scope。printSummary / 确认环节明确展示当前卸载的是 user 还是 project(含 teamaiHome 路径);当 user 与 project 同时存在时,提示用户当前作用对象,避免误删另一个 scope。

实现草案

  1. src/pull.ts pull():先 detectProjectConfig();命中 project → 只 pullForScope(projectConfig) 并打印跳过提示,执行 user 的 pullForScope;未命中 → 维持现有 user 逻辑。
    • reconcileHooksAllScopes(userConfig, projectConfig, options):project 命中时只传 project(user 传 null)。
    • pullSources(...)保留执行(决策 1)。注意其入参当前是 userConfig,需改为「project 命中时用 projectConfig,否则 userConfig」,确保 source 在 project-only 下仍可用且落点正确。
  2. src/recall.ts recall()detectProjectConfig() 命中时 scopeIndexes 只放 project,不追加 user。
  3. src/uninstall.ts:在 printSummary(及最小卸载分支)顶部输出当前 scope 标识(localConfig.scope + teamaiHome)。
  4. auto-recall:无需改动(已用单一 scope 索引)。
  5. 底层 pullForScope / loadOrBuildScopeIndex / buildRemovalPlan 按 scope 工作的能力不变,仅在顶层编排处做 user 短路与提示。

向后兼容

  • 仅当 cwd 存在 project scope 时行为改变;纯 user scope 用户零感知。
  • 现有 project 用户:之前「user + project 都拉」,变更后「只拉 project(但仍拉 source)」。属预期内语义收紧,需在 CHANGELOG / README 说明。

测试

  • pull:同时存在 user + project config 时,断言 project 命中 → user 分支不执行(user state.json/资源无变化)、打印跳过提示、pullSources 仍被调用。
  • recall:project 命中时结果只含 [project],不含 [user]
  • uninstall:project 命中时摘要含 project scope 标识与 <projectRoot>/.teamai 路径;纯 user 时显示 user。
  • 回归:无 project config 时 pull/recall/uninstall 行为与现状一致。
  • 参考夹具:src/__tests__/scope.test.tspull-skip-sync.test.tsrecall-rules.test.tsuninstall.test.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions