teamai-cli 0.21.0-beta.0 → 0.21.0-beta.2

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
@@ -30,9 +30,7 @@ npm install -g teamai-cli
30
30
 
31
31
  ### Team admin / solo user
32
32
 
33
- Create a shared-experience repo on your git host (GitHub, TGit, CNB, or a self-hosted Git service), **grant write access to team members**, then have them run `teamai init https://github.com/yourorg/yourrepo`.
34
-
35
- > Solo use needs no separate repo setup: `teamai init` checks the target repo and creates it automatically if it doesn't exist.
33
+ Create a shared-experience repo on your git host (GitHub, GitLab (incl. self-hosted), CNB, TGit, or any private/self-hosted Git service), **grant write access to team members**, then have them run `teamai init https://github.com/yourorg/yourrepo`.
36
34
 
37
35
  > Self-hosted GitLab/Gitea-style services use your HTTPS credential helper or SSH key. Create the repository first; merge requests are created manually for now. See [Git Provider docs](docs/providers.md).
38
36
 
@@ -47,11 +45,6 @@ teamai init https://github.com/yourorg/yourrepo
47
45
 
48
46
  # User-scope init (resources installed under ~/)
49
47
  teamai init https://github.com/yourorg/yourrepo --scope user
50
-
51
- # Optional layered setup: keep a project repo active while inheriting safe
52
- # resources and searchable knowledge from an initialized user-scope repo
53
- cd /path/to/my-project
54
- teamai init https://github.com/yourorg/project-repo --inherit-user-scope
55
48
  ```
56
49
 
57
50
  Once initialized, every AI session automatically pulls the latest skills / rules and other Harness updates published by admins — no manual sync needed.
@@ -66,16 +59,39 @@ teamai init . # interactive: pick which AI tools to set u
66
59
  teamai init . --agent claude,codex # non-interactive: Claude Code + Codex
67
60
  ```
68
61
 
69
- - **Knowledge** (skills / rules / docs / learnings) is committed to your repo's **main branch** under `.teamai/`, so a plain `git clone` already carries the whole team setup.
70
- - **Reports** (member registrations, session summaries, votes, usage stats) go to a separate **`teamai-reports` orphan branch** — they never touch main.
71
- - **You choose which AI tools to set up.** `--agent claude,codex` (repeatable/comma-separated), an interactive picker when omitted, or — in non-interactive contexts — whichever tools you already use under `~/`. teamai creates each selected tool's dir, injects hooks, and commits its settings.
72
- - **Clone = initialized.** When a teammate clones the repo, the next `teamai` command (or AI session) auto-detects the `mode: self` marker in `.teamai/teamai.yaml` and finishes local setup automatically — no need to re-type repo/role.
73
- - All of teamai's git operations run in isolated worktrees, so your working tree and current branch are never touched.
74
-
75
- `teamai init .` commits `.teamai/` (skills, rules, docs, learnings, `teamai.yaml`, `.gitignore`) plus each selected tool's settings (e.g. `.claude/settings.json`, `.codex/hooks.json`) for you; just push main so teammates get auto-initialized on clone.
76
-
77
62
  > **Full usage guide:** [docs/usage-guide.md](docs/usage-guide.md) ([中文版](docs/usage-guide.zh-CN.md)) — covers everything from team creation to day-to-day use.
78
63
 
64
+ ## Overview
65
+
66
+ <table>
67
+ <thead>
68
+ <tr>
69
+ <th rowspan="2">Agent</th>
70
+ <th colspan="7">Harness</th>
71
+ <th colspan="3">Knowledge Base</th>
72
+ <th colspan="3">Governance</th>
73
+ </tr>
74
+ <tr>
75
+ <th>skills</th><th>rules</th><th>docs</th><th>env</th><th>agents</th><th>hooks</th><th>mcp</th>
76
+ <th>learnings</th><th>codebase</th><th>teamwiki</th>
77
+ <th>usage</th><th>sessions</th><th>dashboard</th>
78
+ </tr>
79
+ </thead>
80
+ <tbody>
81
+ <tr><td>Claude Code</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
82
+ <tr><td>Codex</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
83
+ <tr><td>Cursor</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
84
+ <tr><td>CodeBuddy</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
85
+ <tr><td>OpenCode</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
86
+ <tr><td>WorkBuddy</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
87
+ <tr><td>OpenClaw</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
88
+ <tr><td>Hermes</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
89
+ <tr><td>DeepSeek Harness</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
90
+ </tbody>
91
+ </table>
92
+
93
+ **Git providers** — GitHub · GitLab (incl. self-hosted) · CNB · TGit · any private/self-hosted Git service.
94
+
79
95
  ## Harness Management & Distribution
80
96
 
81
97
  TeamAI keeps skills, rules, docs, and hooks in a shared git repo and distributes them to every member's local AI tools through a "push → review & merge → pull" flow — with support for subscribing to other teams' Harness.
@@ -180,21 +196,6 @@ Author: member-b | Score: 12.0 | Tags: deploy, config
180
196
  Matched: conflict | Missing: port
181
197
  ```
182
198
 
183
- A `Matched: … | Missing: …` line appears whenever a hit does not cover every
184
- query term (omitted when all terms matched). Recall returns its top matches by
185
- score without filtering on coverage: a hit missing all of your distinctive
186
- terms is topically adjacent, not an answer. Judging that is the caller's job —
187
- the score alone cannot express it. Entries matching on title, date, author and
188
- content are collapsed, so the same learning shared twice does not occupy two
189
- slots.
190
-
191
- **Coverage spans two parts:**
192
-
193
- - **Shared search index** (`search-index.json`): four categories — learnings (session experience), docs (team docs), rules (coding rules), and skills (each `SKILL.md`) — sourced from the corresponding team-repo directories, (re)built on `teamai pull` / `teamai contribute`.
194
- - **Codebase knowledge graph** (`teamwiki/`): produced by `teamai import`, queried live at search time.
195
-
196
- Ranking uses BM25 + graph-boost. When the current working directory contains a project-scope config, Recall searches that project; if the project enables `--inherit-user-scope`, it then searches user knowledge, tags each result with its origin, and lets an identical project entry override the user entry. Without a project config in the current directory, Recall searches the user scope. Active-scope hits are implicitly upvoted; inherited user hits remain read-only while the project is active.
197
-
198
199
  ### Codebase Knowledge Graph
199
200
 
200
201
  `teamai import` parses source repos into a structured graph under `teamwiki/`, enabling structurally-aware retrieval:
@@ -232,8 +233,6 @@ When a recall hit comes from a codebase page, the result includes a `Sources:` l
232
233
  | `teamai doctor` | Diagnose configuration issues |
233
234
  | `teamai uninstall` | Remove all teamai resources and hooks |
234
235
 
235
- Global options: `--dry-run`, `--verbose`
236
-
237
236
  ## License
238
237
 
239
238
  [MIT](LICENSE)
package/README.zh-CN.md CHANGED
@@ -30,9 +30,7 @@ npm install -g teamai-cli
30
30
 
31
31
  ### 团队管理员 / 个人使用者
32
32
 
33
- 在 Git 托管平台(GitHub、TGit、CNB 或自建 Git 服务)创建共享经验仓库,**授予团队成员写权限**,然后让他们运行 `teamai init https://github.com/yourorg/yourrepo`。
34
-
35
- > 个人使用无需单独建仓:`teamai init` 会检查目标仓库,不存在时自动创建。
33
+ 在 Git 托管平台(GitHub、GitLab(含自建)、CNB、TGit,或任意私有/自建 Git 服务)创建共享经验仓库,**授予团队成员写权限**,然后让他们运行 `teamai init https://github.com/yourorg/yourrepo`。
36
34
 
37
35
  > 自建 GitLab/Gitea 等服务支持 HTTPS Credential Helper 或 SSH Key;需预先创建仓库,MR 暂时手动创建。详见 [Git Provider 说明](docs/providers.md)。
38
36
 
@@ -47,11 +45,6 @@ teamai init https://github.com/yourorg/yourrepo
47
45
 
48
46
  # 用户级初始化(资源安装到 ~/ 下)
49
47
  teamai init https://github.com/yourorg/yourrepo --scope user
50
-
51
- # 可选的分层模式:项目仓库保持为当前 scope,同时继承已初始化的
52
- # user scope 中的安全资源和可检索知识
53
- cd /path/to/my-project
54
- teamai init https://github.com/yourorg/project-repo --inherit-user-scope
55
48
  ```
56
49
 
57
50
  初始化完成后,每次开启 AI 会话时都会自动拉取管理员发布的 skills / rules 等 Harness 更新,无需手动同步。
@@ -66,16 +59,39 @@ teamai init . # 交互式:选择要启用哪些 AI 工
66
59
  teamai init . --agent claude,codex # 非交互:启用 Claude Code + Codex
67
60
  ```
68
61
 
69
- - **知识资产**(skills / rules / docs / learnings)提交到仓库 **main 分支**的 `.teamai/` 目录,因此一次普通 `git clone` 就带上了整套团队配置。
70
- - **上报数据**(成员注册、会话摘要、投票、使用统计)走独立的 **`teamai-reports` 孤儿分支** —— 永不污染 main。
71
- - **由你选择启用哪些 AI 工具。** `--agent claude,codex`(可重复/逗号分隔),省略时弹交互选择框,非交互场景则按你本机 `~/` 下已装的工具来建。teamai 为每个所选工具建目录、注入 hooks、并提交其 settings。
72
- - **克隆即初始化。** 团队成员 clone 仓库后,下一条 `teamai` 命令(或 AI 会话)会自动识别 `.teamai/teamai.yaml` 里的 `mode: self` 标记并自动完成本机初始化 —— 无需手抄 repo/role 参数。
73
- - teamai 的所有 git 操作都在隔离的 worktree 中进行,绝不触碰你的工作区和当前分支。
74
-
75
- `teamai init .` 会帮你把 `.teamai/`(skills、rules、docs、learnings、`teamai.yaml`、`.gitignore`)以及每个所选工具的 settings(如 `.claude/settings.json`、`.codex/hooks.json`)提交好;推送 main 后团队成员 clone 即可自动初始化。
76
-
77
62
  > **完整使用指南**:[docs/usage-guide.zh-CN.md](docs/usage-guide.zh-CN.md)([English](docs/usage-guide.md))— 涵盖从团队创建到日常使用的全流程。
78
63
 
64
+ ## 功能概览
65
+
66
+ <table>
67
+ <thead>
68
+ <tr>
69
+ <th rowspan="2">Agent</th>
70
+ <th colspan="7">Harness</th>
71
+ <th colspan="3">知识库</th>
72
+ <th colspan="3">治理</th>
73
+ </tr>
74
+ <tr>
75
+ <th>skills</th><th>rules</th><th>docs</th><th>env</th><th>agents</th><th>hooks</th><th>mcp</th>
76
+ <th>learnings</th><th>codebase</th><th>teamwiki</th>
77
+ <th>usage</th><th>sessions</th><th>dashboard</th>
78
+ </tr>
79
+ </thead>
80
+ <tbody>
81
+ <tr><td>Claude Code</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
82
+ <tr><td>Codex</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
83
+ <tr><td>Cursor</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
84
+ <tr><td>CodeBuddy</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
85
+ <tr><td>OpenCode</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
86
+ <tr><td>WorkBuddy</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td></tr>
87
+ <tr><td>OpenClaw</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
88
+ <tr><td>Hermes</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
89
+ <tr><td>DeepSeek Harness</td><td align="center">✓</td><td align="center">—</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">—</td><td align="center">✓</td><td align="center">✓</td><td align="center">✓</td><td align="center">—</td><td align="center">—</td><td align="center">—</td></tr>
90
+ </tbody>
91
+ </table>
92
+
93
+ **Git 托管平台** —— GitHub · GitLab(含自建)· CNB · TGit · 任意私有/自建 Git 服务。
94
+
79
95
  ## Harness 管理和分发
80
96
 
81
97
  TeamAI 把 skills、rules、docs、hooks 统一存放在共享 Git 仓库,通过「push → 评审合并 → pull」的流程分发到每位成员的本地 AI 工具,并支持订阅其他团队的 Harness。
@@ -180,18 +196,6 @@ Author: member-b | Score: 12.0 | Tags: deploy, config
180
196
  Matched: conflict | Missing: port
181
197
  ```
182
198
 
183
- 当某条结果未覆盖全部查询词时,会输出 `Matched: … | Missing: …` 行(全部命中时省略)。
184
- recall 按分数返回 top 结果,**不会**按覆盖度过滤:若你的关键区分词全在 `Missing:` 里,
185
- 说明这条只是主题相邻,并非答案。这个判断由调用方来做 —— 分数本身无法表达它。
186
- 标题、日期、作者与内容均相同的条目会被合并,因此同一条 learning 被分享两次不会占用两个名额。
187
-
188
- **检索内容覆盖两部分**:
189
-
190
- - **共享检索索引**(`search-index.json`):learnings(session 经验)、docs(团队文档)、rules(编码规则)、skills(各 `SKILL.md`)四类,源自团队仓库对应目录,在 `teamai pull` / `teamai contribute` 时构建重建。
191
- - **代码知识图谱**(`teamwiki/`):由 `teamai import` 生成,检索时实时查询。
192
-
193
- 排序采用 BM25 + 图谱增强。当前工作目录包含 project scope 配置时,Recall 先检索该项目;如果项目启用了 `--inherit-user-scope`,再检索 user 知识并标注结果来源,相同条目由 project 版本覆盖 user 版本。当前目录没有 project 配置时,Recall 检索 user scope。当前 scope 的命中会隐式投票,项目运行期间继承的 user 命中保持只读。
194
-
195
199
  ### 代码知识图谱
196
200
 
197
201
  `teamai import` 将源码仓库解析为 `teamwiki/` 下的结构化图谱,实现结构感知的检索:
@@ -229,8 +233,6 @@ teamai codebase --lint # 健康检查
229
233
  | `teamai doctor` | 诊断配置问题 |
230
234
  | `teamai uninstall` | 移除所有 teamai 资源和 hooks |
231
235
 
232
- 全局选项:`--dry-run`、`--verbose`
233
-
234
236
  ## 许可证
235
237
 
236
238
  [MIT](LICENSE)
package/dist/index.js CHANGED
@@ -497,6 +497,10 @@ var init_types = __esm({
497
497
  codebuddy: { skills: ".codebuddy/skills", rules: ".codebuddy/rules", settings: ".codebuddy/settings.json", claudemd: ".codebuddy/CODEBUDDY.md", agents: ".codebuddy/agents", mcp: ".codebuddy/mcp.json", mcpProject: ".codebuddy/mcp.json" },
498
498
  openclaw: { skills: ".openclaw/skills", rules: ".openclaw/rules", claudemd: ".openclaw/workspace/AGENTS.md" },
499
499
  hermes: { skills: ".hermes/skills", claudemd: "AGENTS.md" },
500
+ // DeepSeek Harness: skills synced to ~/.dsh/skills, which its skill-filesystem
501
+ // provider scans as user-dsh root (rank 400). dsh discovers both directory
502
+ // bundles (<name>/SKILL.md) and flat Markdown files there natively.
503
+ dsh: { skills: ".dsh/skills" },
500
504
  workbuddy: { skills: ".workbuddy/skills", rules: ".workbuddy/rules", settings: ".workbuddy/settings.json", claudemd: "AGENTS.md", mcp: ".workbuddy/mcp.json", mcpProject: ".workbuddy/mcp.json" },
501
505
  // OpenCode reads project config from <root>/.opencode/ but user config from
502
506
  // ~/.config/opencode/ — a different prefix, hence userScope. Skills are also
@@ -5770,6 +5774,11 @@ async function detectOpenclawVersion() {
5770
5774
  const match = raw.match(/^([\d.]+)/);
5771
5775
  return match?.[1] ?? "";
5772
5776
  }
5777
+ async function detectDshVersion() {
5778
+ const raw = await execVersion("dsh");
5779
+ const match = raw.match(/v?(\d+(?:\.\d+)*)/);
5780
+ return match?.[1] ?? "";
5781
+ }
5773
5782
  async function getAgentVersion(agentType) {
5774
5783
  if (VERSION_CACHE.has(agentType)) return VERSION_CACHE.get(agentType);
5775
5784
  const detector = DETECTORS[agentType];
@@ -5804,7 +5813,10 @@ var init_agent_version = __esm({
5804
5813
  "codebuddy-ide": detectCodebuddyIdeVersion,
5805
5814
  workbuddy: detectWorkbuddyVersion,
5806
5815
  hermes: detectHermesVersion,
5807
- openclaw: detectOpenclawVersion
5816
+ openclaw: detectOpenclawVersion,
5817
+ // DeepSeek Harness: `dsh --version` prints e.g. "0.1.1" (optionally with a
5818
+ // leading "v" or trailing commit info). Extract leading semver-ish digits.
5819
+ dsh: detectDshVersion
5808
5820
  };
5809
5821
  }
5810
5822
  });
@@ -9367,8 +9379,9 @@ __export(builtin_agents_exports, {
9367
9379
  });
9368
9380
  import fs12 from "fs";
9369
9381
  import path28 from "path";
9382
+ import { fileURLToPath as fileURLToPath3 } from "url";
9370
9383
  function getBuiltinAgentsDir() {
9371
- const distDir = path28.dirname(new URL(import.meta.url).pathname);
9384
+ const distDir = path28.dirname(fileURLToPath3(import.meta.url));
9372
9385
  return path28.join(distDir, "..", "agents");
9373
9386
  }
9374
9387
  async function deployBuiltinAgents(teamConfig, localConfig, options) {
@@ -10920,6 +10933,7 @@ async function push(options) {
10920
10933
  async function pushCore(localConfig, teamConfig, options) {
10921
10934
  const selfMode = localConfig.repo.kind === "self";
10922
10935
  const scopeLabel = localConfig.scope;
10936
+ let pendingTeamConfig = null;
10923
10937
  if (!selfMode) {
10924
10938
  const pullSpin = spinner("Pulling latest changes...").start();
10925
10939
  try {
@@ -10929,8 +10943,19 @@ async function pushCore(localConfig, teamConfig, options) {
10929
10943
  pullSpin.fail("Cannot push: team repo path is not a dedicated git root. Run `teamai init` to re-clone the team repo before pushing.");
10930
10944
  return;
10931
10945
  }
10946
+ const yamlPath = path34.join(repoPath, "teamai.yaml");
10947
+ const workingContent = await readFileSafe(yamlPath);
10948
+ if (workingContent !== null) {
10949
+ const committed = await getFileContentAtRev(repoPath, "HEAD", "teamai.yaml");
10950
+ if (committed === null || committed.toString() !== workingContent) {
10951
+ pendingTeamConfig = workingContent;
10952
+ }
10953
+ }
10932
10954
  await resetToCleanMaster(git, repoPath);
10933
10955
  await pullRepo(repoPath);
10956
+ if (pendingTeamConfig !== null) {
10957
+ await writeFile(yamlPath, pendingTeamConfig);
10958
+ }
10934
10959
  pullSpin.succeed("Up to date");
10935
10960
  } catch (e) {
10936
10961
  pullSpin.warn(`Pull failed: ${e.message}`);
@@ -11037,6 +11062,10 @@ async function pushCore(localConfig, teamConfig, options) {
11037
11062
  allItems.push(matchedItem);
11038
11063
  }
11039
11064
  if (allItems.length === 0) {
11065
+ if (pendingTeamConfig !== null) {
11066
+ await pushTeamConfigOnly(localConfig, teamConfig, options);
11067
+ return;
11068
+ }
11040
11069
  log.info("No new or modified resources to push");
11041
11070
  return;
11042
11071
  }
@@ -11173,7 +11202,8 @@ async function pushCore(localConfig, teamConfig, options) {
11173
11202
  localConfig.repo.localPath,
11174
11203
  sweeperCandidates
11175
11204
  );
11176
- const gitFiles = [.../* @__PURE__ */ new Set([...pushedFiles, ...existingSweepers])];
11205
+ const configFiles = pendingTeamConfig !== null ? ["teamai.yaml"] : [];
11206
+ const gitFiles = [.../* @__PURE__ */ new Set([...pushedFiles, ...existingSweepers, ...configFiles])];
11177
11207
  const branchName = generateBranchName(localConfig.username);
11178
11208
  const commitMsg = `[teamai] Push ${selectedItems.length} resource(s) from ${localConfig.username}`;
11179
11209
  const hasChanges = await pushRepoBranch(
@@ -11228,6 +11258,43 @@ ${selectedItems.map((i) => `- [${i.type}] ${i.name}`).join("\n")}`
11228
11258
  }
11229
11259
  await saveStateForScope(state, localConfig.scope, localConfig.projectRoot);
11230
11260
  }
11261
+ async function pushTeamConfigOnly(localConfig, teamConfig, options) {
11262
+ console.log("");
11263
+ console.log("Found team config change to push:");
11264
+ console.log(" - teamai.yaml");
11265
+ console.log("");
11266
+ if (options.dryRun) {
11267
+ log.info("Dry run \u2014 no changes made");
11268
+ return;
11269
+ }
11270
+ const pushSpin = spinner("Pushing team config...").start();
11271
+ const branchName = generateBranchName(localConfig.username);
11272
+ const commitMsg = `[teamai] Update team config from ${localConfig.username}`;
11273
+ try {
11274
+ const hasChanges = await pushRepoBranch(
11275
+ localConfig.repo.localPath,
11276
+ commitMsg,
11277
+ ["teamai.yaml"],
11278
+ branchName
11279
+ );
11280
+ if (!hasChanges) {
11281
+ pushSpin.succeed("No changes to push (config already up to date)");
11282
+ return;
11283
+ }
11284
+ pushSpin.succeed(`Pushed branch ${branchName}`);
11285
+ await createPrWithFallback(
11286
+ teamConfig,
11287
+ localConfig,
11288
+ branchName,
11289
+ commitMsg,
11290
+ "Updated team config (teamai.yaml)"
11291
+ );
11292
+ await checkoutMaster(localConfig.repo.localPath);
11293
+ } catch (e) {
11294
+ pushSpin.fail(`Push failed: ${e.message}`);
11295
+ return;
11296
+ }
11297
+ }
11231
11298
  var SELF_KNOWLEDGE_SCAN_KEY;
11232
11299
  var init_push = __esm({
11233
11300
  "src/push.ts"() {
@@ -11716,6 +11783,11 @@ var init_known_agents = __esm({
11716
11783
  { id: "easyclaw", displayName: "EasyClaw", category: "lobster", skillsPath: ".easyclaw/skills" },
11717
11784
  { id: "autoclaw", displayName: "AutoClaw", category: "lobster", skillsPath: ".openclaw-autoclaw/skills" },
11718
11785
  { id: "workbuddy", displayName: "WorkBuddy", category: "lobster", skillsPath: ".workbuddy/skills" },
11786
+ // DeepSeek Harness (dsh) — plugin-based agent harness. Its skill-filesystem
11787
+ // provider scans user skill roots: ~/.dsh/skills (rank 400) and ~/.agents/skills
11788
+ // (rank 500). We sync to ~/.dsh/skills so dsh keeps its own copy; the central
11789
+ // `.agents` entry below covers the shared root as well.
11790
+ { id: "dsh", displayName: "DeepSeek Harness", category: "coding", skillsPath: ".dsh/skills" },
11719
11791
  // Central agent skills directory (codex / generic)
11720
11792
  { id: "agents", displayName: "Central (Agent Skills)", category: "central", skillsPath: ".agents/skills" }
11721
11793
  ];
@@ -32492,7 +32564,7 @@ program.name("teamai").description("TeamAI \u2014 The team harness for AI agents
32492
32564
  const opts = thisCommand.opts();
32493
32565
  if (opts.verbose) setVerbose(true);
32494
32566
  });
32495
- program.command("init").description("Initialize teamai (configure Git provider, clone repo, register member)").argument("[repo]", 'Team repo (owner/repo or full URL). Pass "." for single-repo mode (the current git repo is the team repo).').option("--repo <repo>", "Team repo (alias of the positional argument)").option("--http <url>", "Git-free HTTP team repo (read-only consumer; only needs an API key)").option("--self", "Single-repo mode: the current git repo is the team repo (equivalent to `teamai init .`). Knowledge lives on main under .teamai/; reports go to the teamai-reports orphan branch.").option("--token <key>", "API key for HTTP team repo / status reporting (stored 0600, never committed). Also reads TEAMAI_API_TOKEN.").option("--scope <scope>", "Install scope: project (default, <cwd>/.teamai + <cwd>/.claude) or user (~/.teamai + ~/.claude)").option("--inherit-user-scope", "In project scope, also sync safe user-scope resources and search its knowledge").option("--no-inherit-user-scope", "Disable user-scope inheritance for this project").option("--role <id>", "Primary role ID (e.g. hai_dev) for non-interactive setup").option("--agent <name>", "AI tools to set up (e.g. claude, codex, cursor, codebuddy, workbuddy). Repeatable or comma-separated. In single-repo mode, selects which tool dirs to create; omit for an interactive picker. Additive on repeated runs.", (val, acc) => acc.concat(val), []).option("--force", "Overwrite existing config without confirmation").action(async (repoArg, cmdOpts) => {
32567
+ program.command("init").description("Initialize teamai (configure Git provider, clone repo, register member)").argument("[repo]", 'Team repo (owner/repo or full URL). Pass "." for single-repo mode (the current git repo is the team repo).').option("--repo <repo>", "Team repo (alias of the positional argument)").option("--http <url>", "Git-free HTTP team repo (read-only consumer; only needs an API key)").option("--self", "Single-repo mode: the current git repo is the team repo (equivalent to `teamai init .`). Knowledge lives on main under .teamai/; reports go to the teamai-reports orphan branch.").option("--token <key>", "API key for HTTP team repo / status reporting (stored 0600, never committed). Also reads TEAMAI_API_TOKEN.").option("--scope <scope>", "Install scope: project (default, <cwd>/.teamai + <cwd>/.claude) or user (~/.teamai + ~/.claude)").option("--inherit-user-scope", "In project scope, also sync safe user-scope resources and search its knowledge").option("--no-inherit-user-scope", "Disable user-scope inheritance for this project").option("--role <id>", "Primary role ID (e.g. hai_dev) for non-interactive setup").option("--agent <name>", "AI tools to set up (e.g. claude, codex, cursor, codebuddy, workbuddy, dsh). Repeatable or comma-separated. In single-repo mode, selects which tool dirs to create; omit for an interactive picker. Additive on repeated runs.", (val, acc) => acc.concat(val), []).option("--force", "Overwrite existing config without confirmation").action(async (repoArg, cmdOpts) => {
32496
32568
  const globalOpts = program.opts();
32497
32569
  const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
32498
32570
  await init2({ ...globalOpts, ...cmdOpts, repoPositional: repoArg });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teamai-cli",
3
- "version": "0.21.0-beta.0",
3
+ "version": "0.21.0-beta.2",
4
4
  "description": "TeamAI — the team harness for AI agents (skill sync + shared knowledge base, powered by Git)",
5
5
  "type": "module",
6
6
  "bin": {