Saul Moro 488c3074cf fix(learnings): publish what an older import --from-mr left in the checkout (#823) (#838)
* fix(learnings): publish what an older import --from-mr left in the checkout (#823)

Item 7. import --from-mr in 0.25.0 to 0.26.0-beta.3 wrote
learnings/<date>-<title>.md, with source_mr in its frontmatter, into the
learnings checkout and never committed it. Nothing published it. In single-repo mode it also kept
`git worktree remove` from removing the checkout an older teamai left in
.teamai/, so every pull and contribute stopped on CheckoutRefusedError.
publishQueuedLearnings now takes the sync lock first, and under it, before
listing the queue, queues every untracked file of exactly that shape
(directly under learnings/, date name, source_mr), in the active namespace
and with contribute's name, then deletes the original. It finds the one
checkout this repo registers for the branch (git worktree list), so the
shared checkout and the old .teamai/learnings-wt are both covered and
another repository's never is. A file the branch or the queue already has,
by source_mr or by content, is deleted instead, and the warning names what
has it. A dry run touches nothing.

Item 21. The branch side of that duplicate check was the checkout's own
tracked files. In single-repo mode the checkout is often the old
.teamai/learnings-wt, which nothing syncs any more, so a teammate's later
import of the same MR was missed and the remnant went out as a duplicate.
When there are remnants, the check now also fetches origin/teamai-learnings
(best effort) and reads what origin has that the checkout's commit lacks.

Item 20. pull --dry-run published the queue: publishQueuedLearnings
honoured dryRun only for the remnants. It now stops after listing the queue,
and pull prints "[dry-run] Would publish N queued learning(s)" instead of
publishing or warning.

Maintenance sweep. publishLearningsMaintenance staged all of learnings/,
so a confidence write-back or a prune swept any uncommitted file into its
commit. confidence write-back, prune and promote now return the files they
wrote or removed, and only those are staged (a removed file git never
tracked is left out, since naming it would fail the add). That exposed a
second bug:
simple-git lists a staged rename under `renamed`, not `staged`, so a
`prune --archive` with nothing else to stage counted as nothing to commit
and was never published. commitAndPushAt now counts renames.

#814 follow-ups. drainCheckoutQueue is gone: the preAction migration moves a
checkout's queue before contribute and import --from-mr. Retire-only now
says "Retired <legacy> to <backup>: this project's data already lives in
<partition>"; a linked worktree lands there too, so "Finished an
interrupted migration" was wrong for it. config.yaml.*.tmp, the temp an
interrupted config save leaves (#831), is ignored in the single-repo and
project-scope .gitignore, and the single-repo self-heal adds it.

Item 15. After a failed refresh, readableReportsWorktree called ensure
without the reports lock, so it could create the checkout while a writer
that had just taken the lock created it too. It now refreshes once more
under the lock and throws the cause if that fails as well.

Item 17. init replaced the team clone before saving the new config, so an
init that stopped in between (an unknown --role, a busy queue lock) left
the old team's config.yaml beside the new team's clone. Just before it
clones another owner's repo, init now settles the old install as the final
save would (queue set aside, indexes dropped) and moves its config.yaml to
config.yaml.previous. A failed init then leaves no config, and commands ask
for teamai init.

* fix(learnings): address review — literal pathspecs, carry settings after a failed clone

Maintenance now stages exactly the files it names: commitAndPushAt and the
removed-file ls-files lookup pass --literal-pathspecs, so a learning named
with [ or * no longer stages the stray files it matches as a pattern.

init reads the config it set aside when the rerun finds none, so an init
whose replacement clone failed no longer drops enabledAgents,
disabledAgents, toolRoots and inheritUserScope on the next run.

* fix(learnings): address review — HTTP maintenance, agent lists on a plain rerun

An HTTP install's learnings dir is no git checkout, so the removed-file
ls-files lookup threw after a prune had already deleted the file. It now
returns the same non-fatal failed publish commitAndPush gives.

init without --agent keeps the carried enabledAgents and disabledAgents,
so a rerun after a failed replacement clone no longer reactivates tools
uninstall --agent excluded.

* fix(learnings): address review — retry maintenance a busy lock or failed push kept local, keep remnants while origin is unreachable

* fix(learnings): address review — queue remnants when origin has no learnings branch, never let one bad maintenance record or remnant block the rest

* fix(learnings): address review — dedup remnants against origin's tree, keep a maintenance record a read failed on

* fix(learnings): address review — commit only the published paths, not the whole index (#823)

* fix(learnings): address review — keep a staged file across the push-retry rebase (#823)

The path-limited commit leaves a file someone else staged in the checkout,
and git refuses to rebase with anything staged, so a non-fast-forward push
failed every retry. Snapshot it with git stash create around the rebase, as
syncWorktree does, and re-apply it with --index so it stays staged.

* fix(learnings): address review — read the queue for remnant dedup under the queue lock and ownership check; move a stale config aside when init reuses a clone (#823)

* ci: re-run checks (flaky dry-run-load-path test, unrelated to this PR)

* fix(learnings): address review — keep staged files staged when the snapshot restore conflicts; never publish a hand edit as a recorded maintenance run (#823)

* fix(learnings): address review — resolve snapshot conflicts from the snapshot without a reset, keep a conflicting staged file unstaged, no hand-edit warning for a merged maintenance commit (#823)

* fix(learnings): address review — point the unpublished-edit warning at git status (#823)
2026-09-28 10:43:32 +08:00
2026-03-03 14:38:43 +08:00
2026-03-03 14:38:43 +08:00

teamai-cli

TeamAI — Make Every Team AI Native

Tencent%2Fteamai-cli | Trendshift

English | 中文 | 日本語 | 한국어 | ไทย

CI npm version npm downloads License: MIT

The shared foundation for how your team works, learns, and improves with AI.

TeamAI turns individual AI capabilities into shared team capabilities — across agents, machines, and team members.

Why TeamAI

Eight everyday scenarios, before and after TeamAI

Quick Start

Send this one line to your AI tool:

Install the teamai skill: https://github.com/Tencent/teamai-cli/tree/main/skills/teamai , load the teamai skill, then set up TeamAI for my team from scratch.

Once TeamAI is set up, just talk to the /teamai skill in your AI tool:

Set up a team from scratch

/teamai Help me set up TeamAI for my team from scratch

Join a team

/teamai Help me join my team's TeamAI, repo URL is https://github.com/your-org/your-repo

Share with the team

Skills, rules, MCP servers, and other agent resources can all be shared:

/teamai Share my xxx skill with the team

Open the dashboard

/teamai Open the TeamAI dashboard

Once a teammate is set up, they just open their agent and already have the team's full set of AI assets.

Command-line install

Install

npm install -g teamai-cli

Team admin / solo user

Create a shared-experience repo on your git host (GitHub, GitLab, GitCode, CNB, TGit, or a private Git service), grant write access to team members, then run teamai init https://github.com/your-org/your-repo.

No team repo yet? Start from a template pre-loaded with production-ready skills, rules, and review agents. Browse the teamai-hub org, click Fork, then teamai init against your new repo.

Team members

# Choose one, depending on where you want resources installed

# Project-scope init (default, resources installed under the project directory)
cd /path/to/my-project
teamai init https://github.com/your-org/your-repo

# Or, user-scope init (resources installed under ~/)
teamai init https://github.com/your-org/your-repo --scope user

Once initialized, every AI session automatically pulls the latest skills / rules and other Harness updates published by admins — no manual sync needed.

Product Overview

Three layers of capability, built on Git:

  • Team Execution — make every agent work the team's way: skills, rules, docs, env, agents, hooks, MCP, models.
  • Team Context (beta) — make every agent understand the team: learnings, codebase graph, teamwiki.
  • Team Improvement (beta) — make every execution improve the team: usage, sessions, dashboard.
Agent Team Execution Team Context (beta) Team Improvement (beta)
skillsrulesdocsenvagentshooksmcpmodels learningscodebaseteamwiki usagesessionsdashboard
Claude Code✓✓✓✓✓✓✓✓✓✓✓✓✓✓
Codex✓✓✓✓✓✓✓✓✓✓✓✓✓✓
Cursor✓✓✓✓✓✓✓—✓✓✓✓✓✓
GitHub Copilot CLI✓✓✓✓✓✓✓—✓✓✓✓✓✓
CodeBuddy✓✓✓✓✓✓✓✓✓✓✓✓✓✓
WorkBuddy✓✓✓✓—✓✓✓✓✓✓✓✓✓
OpenCode✓✓✓✓✓✓✓✓✓✓✓———
Pi Coding Agent✓✓✓——✓————————
OpenClaw✓✓✓✓————✓✓✓———
Hermes✓—✓✓————✓✓✓———
DeepSeek Harness✓—✓—————✓✓✓———
Qoder✓✓✓✓✓✓✓—✓✓✓✓✓✓
Qoder CN✓✓✓✓✓✓✓—✓✓✓✓✓✓
Kiro✓✓✓✓✓✓✓—✓✓✓✓✓✓
ZCode✓—✓—✓✓✓—✓✓✓✓✓✓
Oh My Pi✓✓✓✓✓✓✓—✓✓✓———

Learn More

Contributors

Thanks to everyone who has contributed to TeamAI!

Contributors

Made with contrib.rocks.

Contributing

Join the conversation, or open an issue or PR. See CONTRIBUTING.md for how to contribute.

License

MIT

S
Description
GitHub Trending: Tencent/teamai-cli
Readme MIT
25 MiB
Languages
TypeScript 99.7%
Python 0.2%
JavaScript 0.1%