Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions docs/designs/skill-serving.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,28 @@ path (measured here from a 77-character one).
blocks instead (`blockedBy: "config"`), since recall and the source are then
unknown and the workflow would fail at `teamai contribute` — a project config
too, which detection alone would skip in favour of the user config
(`findUnreadableProjectConfig`). The Stop-hook share reminder is gated the same
way (`contributeHintAllowed`, `src/hook-handlers.ts`), because it points at this
command, with one difference: with no config at all it stays silent. The hook
fires in every project on the machine, and a directory without teamai has no
team to share with (#748). The gate lives in one place:
`resolveServableSkill` (`src/skill-content.ts`) is the only way to obtain a
packaged skill outside that module, and it returns `blocked` instead of the
skill, so a command cannot print a directory it never received.
(`findUnreadableProjectConfig`), including one that is not `scope: project`. The refusal then says what failed (for a file
that does not parse, which file and where; for one that fails validation,
which field and why), since nothing else reports it. The
Stop-hook share reminder asks the same gate (`contributeHintAllowed`, called
by the hook dispatcher and by the legacy `teamai contribute-check`), because it
points at this command, with one difference: with no config at all it stays
silent. The hook fires in every project on the machine, and a directory without
teamai has no team to share with (#748). The gate lives in one place: `shareGate`
(`src/skill-content.ts`) decides it, and `resolveServableSkill` is the only
way to obtain a packaged skill outside that module; it returns `blocked`
instead of the skill, so a command cannot print a directory it never received.
- **`skill path` takes a name, always,** and a blocked name gets the same
refusal as `skill get`. The gate routes the agent away from a workflow that
cannot finish; it is not access control, since the files ship in the package.
- **A member's own skill outranks a packaged name.** `locateSkill` searches the
team repo, then the installed agents, then the package. `codebase`, `default`,
`learning` and `share` are ordinary names: a directory a member created under
one of them is the skill they are asking about, and the recall gate does not
apply to it. The two legacy directory names are the exception, by design:
apply to it. A config that cannot be loaded does apply: which team repo and
agents are meant is then unknown (`detectTeam`), so `skill show` searches
neither, refuses `share`, and answers any other name from the package alone,
saying what failed. The two legacy directory names are the exception, by design:
`team-wiki-codebase` and `teamai-share-learnings` classify as `[builtin]` and
are skipped by the push scan by name alone (`isCliOwnedSkillName`), because a
tree with that name is one a pre-stub release wrote until the first pull has
Expand All @@ -121,6 +127,8 @@ path (measured here from a 77-character one).
- **`skill list` needs no team.** The human-readable listing prints the packaged
catalog even before `teamai init`, with a hint for the team half, so a fresh
machine can discover what the installed CLI serves the way `skill get` lets it.
With a config that cannot be loaded it prints the catalog too, but no team
listing, says what failed on stderr, and exits 1.


## Drift guards
Expand All @@ -132,8 +140,9 @@ Two tests, both in the unit suite:
`npx vitest run commands-reference -u`.
- `skill-commands-exist.test.ts` resolves every `teamai …` string written
anywhere under `skill-data/` against that same table, and fails on an unknown
command or flag. It carries a case proving it catches `teamai extract graph`,
the command the wiki skill advertised for four releases.
command, subcommand or flag. It carries cases proving it catches
`teamai extract graph`, the command the wiki skill advertised for four
releases, and a misspelled subcommand inside a group (`teamai skill gett`).

A third, in `skill-content.test.ts`, asserts through `npm pack` that both
`skills/` and `skill-data/` are in the published tarball. Without it, a missing
Expand Down Expand Up @@ -237,7 +246,8 @@ and can be dropped on the same schedule.
`/teamai-share-learnings` was never a deployed slash command in its own right —
it existed because the directory was installed. The Stop-hook nudge now names
`/teamai share what this session taught me`, an invocation the core skill routes
to `share` (bare `/teamai` prints the menu and stops), and carries
to `share` (so does a bare `/teamai` typed right after the reminder; otherwise
bare `/teamai` prints the menu and stops), and carries
`teamai skill get share` literally, so an agent can act on it even without
inferring the intent. It is withheld while recall is off, because that command
refuses then.
inferring the intent. It is withheld wherever that command refuses (recall off,
a read-only HTTP source, a config that cannot be loaded).
2 changes: 1 addition & 1 deletion docs/product-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Task: Fix duplicate project-level Hook injection
Consider running `/teamai share what this session taught me` to summarize what you learned and share it with your team (or run `teamai skill get share`).
```

The hint names the non-zero friction signals that triggered it and, when available, includes a redacted, single-line summary of the first task. The `share` workflow (`teamai skill get share`) summarizes the session and pushes a learning document directly to the team repo. Each session is prompted at most once. Teams can switch the hint off with `sharing.contributeHint.enabled: false` in `teamai.yaml` (members: `contributeHintEnabled` in local config) while keeping the rest of the Stop hook. The hint also needs recall to be on (it is off by default), because the workflow it points at is served only then, and it never appears in a directory where teamai is not set up.
The hint names the non-zero friction signals that triggered it and, when available, includes a redacted, single-line summary of the first task. The `share` workflow (`teamai skill get share`) summarizes the session and pushes a learning document directly to the team repo. Each session is prompted at most once. Teams can switch the hint off with `sharing.contributeHint.enabled: false` in `teamai.yaml` (members: `contributeHintEnabled` in local config) while keeping the rest of the Stop hook. The hint also needs recall to be on (it is off by default), because the workflow it points at is served only then. For the same reason it never appears on a read-only HTTP source or while a teamai config exists but cannot be loaded, and it never appears in a directory where teamai is not set up.

### Team Knowledge Recall

Expand Down
2 changes: 1 addition & 1 deletion docs/product-overview.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Task: Fix duplicate project-level Hook injection
Consider running `/teamai share what this session taught me` to summarize what you learned and share it with your team (or run `teamai skill get share`).
```

提示会列出实际触发它的非零摩擦信号;如果能取得首个任务摘要,还会在脱敏、单行化后附上任务上下文。`share` 工作流(`teamai skill get share`)自动总结 session 经验并推送到团队仓库。每个 session 最多提示一次。团队可在 `teamai.yaml` 设置 `sharing.contributeHint.enabled: false` 关闭该提示(成员可用本地配置 `contributeHintEnabled` 覆盖),Stop hook 的其余功能不受影响。该提示还需要开启 recall(默认关闭),因为它指向的工作流只在 recall 开启时提供;在未配置 teamai 的目录中也不会出现。
提示会列出实际触发它的非零摩擦信号;如果能取得首个任务摘要,还会在脱敏、单行化后附上任务上下文。`share` 工作流(`teamai skill get share`)自动总结 session 经验并推送到团队仓库。每个 session 最多提示一次。团队可在 `teamai.yaml` 设置 `sharing.contributeHint.enabled: false` 关闭该提示(成员可用本地配置 `contributeHintEnabled` 覆盖),Stop hook 的其余功能不受影响。该提示还需要开启 recall(默认关闭),因为它指向的工作流只在 recall 开启时提供。同理,只读 HTTP 源上,或 teamai 配置文件存在但无法加载时,该提示从不出现;在未配置 teamai 的目录中也不会出现。

### 团队知识检索

Expand Down
6 changes: 4 additions & 2 deletions docs/usage-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,9 @@ yours and stays. A directory that also holds a file of your own is kept, with on
packaged files removed, and named in the pull output. `share` is served only while recall is
on (off by default; `sharing.recall.enabled: true` in `teamai.yaml` for the team, or
`teamai recall enable` for one machine): until then `teamai skill get share` refuses and says so.
It also refuses on a read-only HTTP source, where `teamai contribute` cannot write. The legacy names still
It also refuses on a read-only HTTP source, where `teamai contribute` cannot write, and when a
teamai config exists but cannot be loaded (the refusal says what failed: for a file that does not parse, which file and where; for one that fails validation, which field and why),
since recall and the source are then unknown. The legacy names still
resolve: `teamai skill get team-wiki-codebase` serves `wiki`.

---
Expand Down Expand Up @@ -973,7 +975,7 @@ Teams that route knowledge sharing through their own review flow (for example, a

Only the nudge is affected: friction scoring, `teamai contribute --file`, and `/teamai` keep working when invoked manually.

The reminder is also withheld while recall is off (the default until `sharing.recall.enabled: true` in `teamai.yaml`, or `teamai recall enable` on one machine): it points at the `share` workflow, and `teamai skill get share` refuses until recall is on. It never appears on a read-only HTTP source, where `share` refuses too, nor in a directory where teamai is not set up.
The reminder is also withheld while recall is off (the default until `sharing.recall.enabled: true` in `teamai.yaml`, or `teamai recall enable` on one machine): it points at the `share` workflow, and `teamai skill get share` refuses until recall is on. It never appears on a read-only HTTP source, or while a teamai config exists but cannot be loaded, where `share` refuses too, nor in a directory where teamai is not set up, although `teamai skill get share` still serves there.

### Searching knowledge

Expand Down
5 changes: 3 additions & 2 deletions docs/usage-guide.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ teamai skill path wiki # 打印打包目录,用于运行 skill
只删除其中的打包文件,保留该目录和你的文件,并在 pull 输出中点名。`share` 只在开启 recall 后才会提供(默认关闭;
团队在 `teamai.yaml` 设置 `sharing.recall.enabled: true`,或单台机器运行 `teamai recall enable`):在此之前,
`teamai skill get share` 会拒绝并说明原因。
只读 HTTP 源上它同样会拒绝,因为 `teamai contribute` 无法写入。旧名字仍然可用:
只读 HTTP 源上它同样会拒绝,因为 `teamai contribute` 无法写入;teamai 配置文件存在但无法加载时也会拒绝
(提示会说明失败原因;若是文件无法解析,还会指出是哪个文件、哪一行;若是校验失败,还会指出是哪个字段、为何不合法),因为此时无法确定 recall 与来源。旧名字仍然可用:
`teamai skill get team-wiki-codebase` 等价于 `wiki`。

---
Expand Down Expand Up @@ -934,7 +935,7 @@ teamai contribute --file /tmp/session.md --scope project

只影响提醒本身:摩擦评分、`teamai contribute --file` 和手动调用 `/teamai` 不受影响。

未开启 recall 时(默认关闭;团队在 `teamai.yaml` 设置 `sharing.recall.enabled: true`,或单台机器运行 `teamai recall enable`)也不会显示这条提醒:提醒指向 `share` 工作流,而 recall 关闭时 `teamai skill get share` 会拒绝执行。只读 HTTP 源上这条提醒也从不出现,因为 `share` 同样会拒绝;在未配置 teamai 的目录中也不会出现。
未开启 recall 时(默认关闭;团队在 `teamai.yaml` 设置 `sharing.recall.enabled: true`,或单台机器运行 `teamai recall enable`)也不会显示这条提醒:提醒指向 `share` 工作流,而 recall 关闭时 `teamai skill get share` 会拒绝执行。只读 HTTP 源上,或 teamai 配置文件存在但无法加载时,这条提醒也从不出现,因为 `share` 同样会拒绝;在未配置 teamai 的目录中也不会出现,尽管 `teamai skill get share` 在那里仍会提供。

### 搜索知识

Expand Down
9 changes: 7 additions & 2 deletions skill-data/core/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ do not skip, reorder, or invent commands.

Look at what the user typed after `/teamai`.

**If they gave NO scenario** (bare `/teamai`, or only greetings/no task):
**If they gave NO scenario right after a TeamAI friction reminder** (the
`[teamai]` line that suggests `/teamai share what this session taught me`),
that reminder is the scenario: load `teamai skill get share` and follow it.

**If they gave NO scenario otherwise** (bare `/teamai`, or only greetings/no task):
print the menu below **exactly**, then **STOP and wait**. Take no other action —
do not run any command, do not load another skill yet.

Expand Down Expand Up @@ -62,7 +66,8 @@ Sharing a session's learnings needs no menu choice: TeamAI prompts on its own at
the end of a session that produced something worth sharing, and that prompt means
`teamai skill get share`. (Only when recall is on; it is off by default. The team turns it on with
`sharing.recall.enabled: true` in `teamai.yaml`, a member with `teamai recall enable`;
while it is off, `teamai skill get share` says so.)
while it is off, or while the teamai config cannot be loaded, `teamai skill get share`
says so and why.)

## Global rules

Expand Down
2 changes: 1 addition & 1 deletion skill-data/core/references/contribute-member.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ team"*, in whatever language they work in — then you run the publish for them.
## Which kind of contribution?

- **A learning** (a lesson, a gotcha, how you solved something) → this is
**automatic** once recall is on (off by default): TeamAI prompts at the end of a session worth sharing and the
**automatic** once recall is on (off by default) and the teamai config loads: TeamAI prompts at the end of a session worth sharing and the
dedicated `share` workflow (`teamai skill get share`) takes over (it summarizes the
session and runs `teamai contribute`). The user does not come through this flow
for it. (Step A below is only a manual fallback for while recall is off.)
Expand Down
3 changes: 2 additions & 1 deletion skill-data/setup/references/join-member.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ Summarize the outcome **in the user's own language** (global rule 1). Cover:
summarize and contribute it. They do **not** invoke `/teamai` for this. (This
prompt only appears when recall is on — it is off by default; the admin turns it
on in `teamai.yaml` (`sharing.recall.enabled`), a member with `teamai recall enable` — and the admin has not switched the
reminder off in `teamai.yaml`.)
reminder off in `teamai.yaml`. It also stays silent while their teamai config
cannot be loaded; `teamai skill get share` then names the file and the error.)
3. **They can also contribute a skill — just ask in plain language.** A member does
not need to be an admin to publish a skill. They tell TeamAI something like
*"share this xxx skill with my team"*, in their own language, and you
Expand Down
6 changes: 4 additions & 2 deletions skill-data/setup/references/manage-admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,16 @@ the team (`sharing.recall.enabled: true` in `teamai.yaml`, then `teamai push`; i
off by default, and `teamai recall enable` turns it on for one machine only): at the end of a session
worth sharing, TeamAI prompts the member and the dedicated
`share` workflow (`teamai skill get share`) summarizes the session and runs
`teamai contribute`. Nobody has to invoke it by hand.
`teamai contribute`. Nobody has to invoke it by hand. (A member whose teamai config
cannot be loaded gets no prompt; `teamai skill get share` names the file and the error.)
(Publishing a **reusable skill** someone authored is a different task — any member
can do it, see `"$(teamai skill path core)/references/contribute-member.md"`.)

### Turn the sharing prompt on or off (admin)

The auto-share prompt is **on by default once recall is on**, and only shows in directories set up
with teamai. To disable it team-wide, set this in
with teamai (never on a read-only HTTP source, or while a member's teamai config cannot be loaded).
To disable it team-wide, set this in
`teamai.yaml` and `teamai push`:

```yaml
Expand Down
3 changes: 2 additions & 1 deletion skill-data/setup/references/setup-admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ day-to-day work — they can keep letting the AI run things for them:
its own at the end of a session worth sharing, and the `share` workflow
(`teamai skill get share`) takes over. (Only once recall is on — off by default;
turn it on team-wide with `sharing.recall.enabled: true` in `teamai.yaml`, then
`teamai push`.)
`teamai push`. Never on a read-only HTTP source, or while a member's teamai
config cannot be loaded.)

Mention the underlying commands (`teamai push`, `teamai roles`, …) only as a note
for users who *do* want them — the primary path is re-invoking `/teamai`.
Expand Down
Loading
Loading