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
4 changes: 4 additions & 0 deletions README-ZH_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ QoderWork、DeepSeek TUI。
内置 skill 会随 `oo` 每次发布同步更新。具体的 skill 安装位置和手动管理方式见
[命令参考](./docs/commands.zh-CN.md)。

当请求与内置 skill 匹配时,Agent 可能会自行使用它。若希望必须由你点名后才触发,
运行 `oo skills auto-trigger off --all`(也可只指定其中几个)。skill 仍然安装
着、仍可调用——在 Claude Code 中用 `/oo`,在 Codex 中用 `$oo`。

## 隐私

`oo` 默认记录受隐私约束的 telemetry,事件不包含自由文本输入、路径、用户名、
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ Bundled skills are kept in sync with each `oo` release. See the
[command reference](./docs/commands.md) for the exact skill targets and how to
manage them manually.

Agents may use a bundled skill on their own when a request matches it. To make
them wait until you ask by name, run `oo skills auto-trigger off --all` (or name
individual skills). The skills stay installed and invocable — `/oo` in Claude
Code, `$oo` in Codex.

## Privacy

`oo` records privacy-constrained telemetry by default. Events do not include
Expand Down
1 change: 1 addition & 0 deletions contrib/skills/shared/oo-create-skill/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: oo-create-skill
description: Create, adopt, review, or update local AI agent skills, including ordinary knowledge or workflow skills and skills powered by oo connectors or hosted capabilities. Use when the user asks to create or improve a skill, turn existing files or scripts into a skill, check a skill against modern authoring practices, or build a reusable skill that calls oo at runtime.
disable-model-invocation: <!-- agentic:var disableModelInvocation -->
<!-- agentic:if agent=claude|hermes -->
allowed-tools: [Bash(oo *)]
<!-- agentic:endif -->
Expand Down
5 changes: 5 additions & 0 deletions contrib/skills/shared/oo-create-skill/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Managed by oo. Change this through `oo skills auto-trigger`, not by hand.
# `allow_implicit_invocation: false` stops Codex from loading this skill from a
# user prompt; explicit `$oo-create-skill` invocation keeps working.
policy:
allow_implicit_invocation: <!-- agentic:var allowImplicitInvocation -->
1 change: 1 addition & 0 deletions contrib/skills/shared/oo-find-skills/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: oo-find-skills
description: Find, compare, and install published OOMOL/oo skills. Use when the user asks to find, search for, discover, recommend, compare, choose, or install an existing skill for a task; asks whether there is a skill that can do something; or explicitly mentions the OOMOL/oo skill catalog. Do not use for creating or editing local skills, generic skill design, or non-OOMOL skill catalogs.
disable-model-invocation: <!-- agentic:var disableModelInvocation -->
<!-- agentic:if agent=claude|hermes -->
allowed-tools: [Bash(oo *)]
<!-- agentic:endif -->
Expand Down
5 changes: 5 additions & 0 deletions contrib/skills/shared/oo-find-skills/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Managed by oo. Change this through `oo skills auto-trigger`, not by hand.
# `allow_implicit_invocation: false` stops Codex from loading this skill from a
# user prompt; explicit `$oo-find-skills` invocation keeps working.
policy:
allow_implicit_invocation: <!-- agentic:var allowImplicitInvocation -->
1 change: 1 addition & 0 deletions contrib/skills/shared/oo-publish-skill/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: oo-publish-skill
description: Publish, release, upload, or submit an existing AI agent skill directory with SKILL.md to the OOMOL registry by running oo skills publish, or generate a share prompt for a published skill by running oo skills share, including temporary shares for private packages. Use when the user asks to publish a skill, share a published skill, make a skill available in the OOMOL skill catalog, release a registry skill package, resolve publish visibility, version, package-name, or overwrite prompts, or publish from a local, registry-installed, or path-based skill source. Do not use for finding, installing, creating, or editing skills unless the final goal is publication or sharing.
disable-model-invocation: <!-- agentic:var disableModelInvocation -->
<!-- agentic:if agent=claude|hermes -->
allowed-tools: [Bash(oo *)]
<!-- agentic:endif -->
Expand Down
5 changes: 5 additions & 0 deletions contrib/skills/shared/oo-publish-skill/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Managed by oo. Change this through `oo skills auto-trigger`, not by hand.
# `allow_implicit_invocation: false` stops Codex from loading this skill from a
# user prompt; explicit `$oo-publish-skill` invocation keeps working.
policy:
allow_implicit_invocation: <!-- agentic:var allowImplicitInvocation -->
1 change: 1 addition & 0 deletions contrib/skills/shared/oo/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: oo
description: Use OO for connected accounts, APIs, and hosted AI tasks; the first-choice router for tasks whose outcome lives outside this workspace, including connected third-party accounts (email, calendar, drive, chat, notes, issue tracker, code host, CRM, storage, etc.), an external API, or a managed AI pipeline (OCR, translation, transcription, TTS, text-to-image, subtitles, long-document understanding). Use when local code needs OOMOL LLM client configuration such as an OpenAI-compatible base URL, API key, or model name. Otherwise use only when the user wants an existing hosted capability or connector workflow, not a local implementation. Concrete capabilities are discovered at runtime, so no package, block, connector, or action names are assumed in advance. Match intent across languages. Skip other pure local coding, shell glue, repo edits, and text-only answers an LLM can complete without hosted capability execution.
disable-model-invocation: <!-- agentic:var disableModelInvocation -->
<!-- agentic:if agent=claude|hermes -->
allowed-tools: [Bash(oo *)]
<!-- agentic:endif -->
Expand Down
5 changes: 5 additions & 0 deletions contrib/skills/shared/oo/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Managed by oo. Change this through `oo skills auto-trigger`, not by hand.
# `allow_implicit_invocation: false` stops Codex from loading this skill from a
# user prompt; explicit `$oo` invocation keeps working.
policy:
allow_implicit_invocation: <!-- agentic:var allowImplicitInvocation -->
105 changes: 105 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1934,6 +1934,111 @@ Common rules:
- The JSON payload never includes `apiKey`, raw HTTP request/response bodies,
stack traces, or unredacted endpoint secrets.

### `oo skills auto-trigger`

Control whether agents may load a bundled skill without being asked to. This is
a command group with three subcommands, and it applies only to the four bundled
skills (`oo`, `oo-find-skills`, `oo-create-skill`, `oo-publish-skill`). Registry
and local skills are unaffected.

Turning auto-trigger off leaves the skill installed and still invocable by name
— `/oo` in Claude Code and Claude-compatible agents, `$oo` in Codex. What
changes is that the agent no longer offers to use it on its own.

- Scope: the setting is per skill, not per agent. One run applies it to every
supported agent host, using whichever mechanism that agent understands.
- Persistence: the choice is stored in the CLI settings file under
`[skills.auto_trigger]` and survives across sessions.
- Application: the setting is an input to skill publication, not a runtime
switch. `off`/`on` republish the bundled skills immediately. Startup
synchronization does not detect a hand-edited `[skills.auto_trigger]`; apply
one with `oo skills repair --skill oo --skill oo-find-skills --skill
oo-create-skill --skill oo-publish-skill` (`--skill` is required).
- `--all` is a standing policy, not a snapshot: bundled skills added by later
releases are covered by it without a further command. While it is in force, a
per-skill `off`/`on` still updates the stored list but changes nothing an
agent can see, and the text output says so.
- Consequence: with auto-trigger off, an agent that hides a skill's description
from its own context can no longer act on it unprompted. The bundled `oo`
skill's end-of-session suggestions are one such behavior and stop happening
until auto-trigger is turned back on.

#### `oo skills auto-trigger off [skillName...]`

Make bundled skills manual-only.

- Arguments: `[skillName...]` bundled skill names to make manual-only; they are
added to a persisted list, de-duplicated and sorted.
- Options: `--all` makes every bundled skill manual-only, now and in future
releases, and clears the per-skill list because it supersedes it.
`--json` / `--format json` / `--show-schema-version` control output.
- Validation: pass skill names **or** `--all`, not both and not neither; either
misuse exits `2`. A name that is not a bundled skill exits `2` and lists the
accepted names.
- Safety: a same-name skill directory that `oo` does not manage is left
untouched and reported as skipped. This differs from `oo skills install`,
which fails the run on such a directory: changing a preference must still
reach the other agents.
- Exit code: `1` when the setting was saved but one or more skill targets could
not be republished; the message names them and gives the `oo skills repair`
command to finish applying it.

#### `oo skills auto-trigger on [skillName...]`

Let agents load bundled skills on their own again.

- Arguments: `[skillName...]` bundled skill names to remove from the list.
- Options: `--all` restores the shipped default for every bundled skill,
clearing both the standing policy and the per-skill list, so nothing is left
silently manual-only. Output options match `off`.
- Validation: as `off`, except that `on` also accepts a name the stored
`disabled` list already holds even when it is not a bundled skill in this
release. Removing an entry is the command's job, and a bundled skill dropped
by a later release would otherwise be unclearable except with `--all`.
- Safety and exit codes match `off`.

#### `oo skills auto-trigger status`

Show the configured auto-trigger policy for every bundled skill.

- Options: `--json` / `--format json` / `--show-schema-version`.
- Text output: a headline stating the overall state, then one line per bundled
skill reading `auto`, `manual`, or `manual (all)`.
- Scope: this reports the stored setting, not what is currently published. The
two agree unless the settings file was edited by hand without republishing —
see Application above.

#### JSON output

`status` emits the state; `off` and `on` emit the same state plus what they
published.

```json
{
"disabled": ["oo-create-skill"],
"disabledAll": false,
"skills": [
{ "autoTrigger": true, "name": "oo", "reason": "default" },
{ "autoTrigger": true, "name": "oo-find-skills", "reason": "default" },
{ "autoTrigger": false, "name": "oo-create-skill", "reason": "skill" },
{ "autoTrigger": true, "name": "oo-publish-skill", "reason": "default" }
],
"publications": [
{ "agent": "universal", "skill": "oo", "status": "published" },
{ "agent": "claude", "skill": "oo", "status": "skipped" }
]
}
```

- `disabled` echoes the persisted per-skill list verbatim, including a name that
no longer matches a bundled skill in this release. Such an entry has no
effect; clear it with `on <name>`, which accepts a name the list already
holds.
- `reason` is `default` (auto-trigger on), `skill` (this skill was named), or
`all` (the standing policy covers it). `all` outranks `skill`.
- `publications` is present on `off` and `on` only. `status` is one of
`published`, `skipped` (target not managed by `oo`), or `failed`.

### `oo skills recommend`

End-of-session skill suggestions for the bundled `oo` skill, plus controls to
Expand Down
91 changes: 91 additions & 0 deletions docs/commands.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,97 @@ CLI 默认记录受隐私约束的命令使用 telemetry。事件不包含 free-
- JSON 输出永远不会包含 `apiKey`、原始 HTTP 请求 / 响应体、stack trace 或未
脱敏的 endpoint secret。

### `oo skills auto-trigger`

控制 agent 能否在用户未点名的情况下自行加载内置 skill。这是一个命令组,包含三个
子命令,仅作用于四个内置 skill(`oo`、`oo-find-skills`、`oo-create-skill`、
`oo-publish-skill`),registry skill 与本地 skill 不受影响。

关闭自动触发后,skill 仍然安装着、仍可按名调用——在 Claude Code 及兼容 agent 中
使用 `/oo`,在 Codex 中使用 `$oo`。改变的只是 agent 不再主动使用它。

- 维度:设置按 skill 生效,不按 agent。一次执行即应用到所有受支持的 agent 宿主,
各自使用该 agent 能识别的机制。
- 持久化:选择存储在 CLI 设置文件的 `[skills.auto_trigger]` 下,跨会话保留。
- 生效时机:该设置是 skill 发布时的输入,不是运行时开关。`off`/`on` 会立即重新
发布内置 skill。启动同步不会检测手工修改的 `[skills.auto_trigger]`;手改后请用
`oo skills repair --skill oo --skill oo-find-skills --skill oo-create-skill
--skill oo-publish-skill` 应用(`--skill` 是必填项)。
- `--all` 是常驻策略而非快照:后续版本新增的内置 skill 也会被它覆盖,无需再次
执行命令。该策略生效期间,针对单个 skill 的 `off`/`on` 仍会更新持久化列表,但
对 agent 而言没有任何变化,文本输出会明确提示这一点。
- 连带影响:自动触发关闭后,会把 skill 描述从自身上下文中移除的 agent 将无法再
主动使用它。内置 `oo` skill 的收尾阶段推荐即属于此类行为,在重新开启自动触发
之前不会再发生。

#### `oo skills auto-trigger off [skillName...]`

把内置 skill 改为仅手动触发。

- 参数:`[skillName...]` 要改为仅手动触发的内置 skill 名称;会写入持久化列表,
去重并排序。
- 选项:`--all` 把所有内置 skill 改为仅手动触发(含后续版本新增的),并清空
per-skill 列表,因为它已被覆盖。`--json` / `--format json` /
`--show-schema-version` 控制输出。
- 校验:传入 skill 名称**或** `--all`,不能同时传、也不能都不传,两种误用均以
`2` 退出。不属于内置 skill 的名称以 `2` 退出并列出可用名称。
- 安全性:非 `oo` 管理的同名 skill 目录不会被覆盖,会在输出中报告为已跳过。这与
`oo skills install` 不同——后者遇到此类目录会让整次运行失败;而修改偏好设置必须
仍然能对其他 agent 生效。
- 退出码:设置已保存但有 skill 目标未能重新发布时退出 `1`,消息会点名这些目标,
并给出用于完成应用的 `oo skills repair` 命令。

#### `oo skills auto-trigger on [skillName...]`

重新允许 agent 自行加载内置 skill。

- 参数:`[skillName...]` 要从列表中移除的内置 skill 名称。
- 选项:`--all` 把所有内置 skill 恢复为出厂默认,同时清除常驻策略和 per-skill
列表,不会遗留任何仍处于仅手动状态的 skill。输出选项与 `off` 相同。
- 校验:与 `off` 相同,但 `on` 额外接受已存在于 `disabled` 列表中的名称,即使它
在当前版本中已不是内置 skill。移除条目本就是该命令的职责;否则后续版本删除的
内置 skill 将只能用 `--all` 清除。
- 安全性与退出码同 `off`。

#### `oo skills auto-trigger status`

显示每个内置 skill 已配置的自动触发策略。

- 选项:`--json` / `--format json` / `--show-schema-version`。
- 文本输出:先输出一行整体状态,再为每个内置 skill 输出一行,取值为 `自动`、
`手动` 或 `手动(全部关闭)`。
- 范围:显示的是已保存的设置,而非当前已发布到磁盘的内容。除非手改了设置文件却
没有重新发布,两者一致——参见上文「生效时机」。

#### JSON 输出

`status` 输出状态;`off` 与 `on` 输出同样的状态,外加本次发布的结果。

```json
{
"disabled": ["oo-create-skill"],
"disabledAll": false,
"skills": [
{ "autoTrigger": true, "name": "oo", "reason": "default" },
{ "autoTrigger": true, "name": "oo-find-skills", "reason": "default" },
{ "autoTrigger": false, "name": "oo-create-skill", "reason": "skill" },
{ "autoTrigger": true, "name": "oo-publish-skill", "reason": "default" }
],
"publications": [
{ "agent": "universal", "skill": "oo", "status": "published" },
{ "agent": "claude", "skill": "oo", "status": "skipped" }
]
}
```

- `disabled` 原样回显持久化的 per-skill 列表,包括在当前版本中已不对应任何内置
skill 的名称。此类条目不产生任何效果;用 `on <name>` 即可清除——`on` 接受列表
中已存在的名称。
- `reason` 取值为 `default`(自动触发开启)、`skill`(该 skill 被单独指定)或
`all`(被常驻策略覆盖)。`all` 优先于 `skill`。
- `publications` 仅出现在 `off` 与 `on` 中。`status` 取值为 `published`、
`skipped`(目标不由 `oo` 管理)或 `failed`。

### `oo skills recommend`

为内置 `oo` skill 提供收尾阶段的 skill 推荐,并提供静音控制。内置 `oo` skill 会
Expand Down
14 changes: 13 additions & 1 deletion src/application/commands/skills/auto-sync.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { CliExecutionContext } from "../../contracts/cli.ts";
import type { SkillAutoTriggerPolicy } from "./auto-trigger-policy.ts";
import type { BundledSkillName } from "./embedded-assets.ts";
import type {
ManagedSkillHost,
Expand All @@ -7,6 +8,7 @@ import type {
import type { RegistrySkillMetadata } from "./skill-metadata.ts";

import { join } from "node:path";
import { readSkillAutoTriggerPolicy } from "./auto-trigger-policy.ts";
import {
publishBundledSkillInstallation,
} from "./bundled-skill-filesystem.ts";
Expand Down Expand Up @@ -69,14 +71,22 @@ export async function synchronizeManagedSkillsForAvailableHosts(
}
}

// The policy is read here rather than by the caller so that a settings file
// this run cannot parse fails only the bundled half. Registry synchronization
// does not depend on the policy, and awaiting the read while the caller builds
// its `Promise.all` array would stop it from ever being started.
async function synchronizeBundledSkills(
hosts: readonly ManagedSkillHost[],
context: SkillSyncContext,
): Promise<void> {
const autoTriggerPolicy = await readSkillAutoTriggerPolicy(
context.settingsStore,
);

await Promise.all(
hosts.flatMap(host =>
availableBundledSkillNames.map(skillName =>
synchronizeBundledSkill(host, skillName, context),
synchronizeBundledSkill(host, skillName, context, autoTriggerPolicy),
),
),
);
Expand All @@ -86,6 +96,7 @@ async function synchronizeBundledSkill(
host: ManagedSkillHost,
skillName: BundledSkillName,
context: SkillSyncContext,
autoTriggerPolicy: SkillAutoTriggerPolicy,
): Promise<void> {
const settingsFilePath = context.settingsStore.getFilePath();
const installation = resolveManagedSkillHostInstallation(host, skillName);
Expand Down Expand Up @@ -162,6 +173,7 @@ async function synchronizeBundledSkill(

const installedSkillDirectoryPath = await publishManagedBundledSkill({
agentName: host.agentName,
autoTriggerPolicy,
homeDirectory: host.homeDirectory,
settingsFilePath,
skillName,
Expand Down
Loading