From b34b967e73c87fda951b95e441459bd0fa0a686d Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Wed, 21 Oct 2026 18:19:41 +0800 Subject: [PATCH 1/6] feat(telemetry): attribute agent vs human callers via BAILIAN_CALLER_* env --- docs/agents/skill-change.md | 1 + docs/agents/telemetry-change.md | 37 +++-- packages/core/src/telemetry/caller.ts | 59 ++++++++ packages/core/src/telemetry/event.ts | 14 ++ packages/core/src/telemetry/index.ts | 3 + packages/core/src/telemetry/tracker.ts | 4 + packages/core/tests/telemetry-caller.test.ts | 142 ++++++++++++++++++ packages/core/tests/telemetry-tracker.test.ts | 80 +++++++++- packages/runtime/src/middleware.ts | 2 + .../runtime/tests/telemetry-stage.test.ts | 87 +++++++++++ skills/bailian-cli/SKILL.md | 2 +- skills/bailian-finetune/SKILL.md | 2 +- skills/bailian-gen/SKILL.md | 2 +- skills/bailian-managed-agent/SKILL.md | 2 +- skills/bailian-memory/SKILL.md | 2 +- skills/bailian-protocol/SKILL.md | 35 ++++- skills/bailian-protocol/assets/setup.md | 2 + skills/bailian-protocol/assets/versioning.md | 9 +- skills/bailian-sandbox/SKILL.md | 2 +- skills/bailian-web-search/SKILL.md | 2 +- 20 files changed, 463 insertions(+), 26 deletions(-) create mode 100644 packages/core/src/telemetry/caller.ts create mode 100644 packages/core/tests/telemetry-caller.test.ts create mode 100644 packages/runtime/tests/telemetry-stage.test.ts diff --git a/docs/agents/skill-change.md b/docs/agents/skill-change.md index 4136f17ed..225332391 100644 --- a/docs/agents/skill-change.md +++ b/docs/agents/skill-change.md @@ -40,6 +40,7 @@ bailian-gen bailian-finetune bailian-managed-agent bailian-web-search - [ ] **整包装齐**:安装 / 缺 skill 文案主推 `bl skill init`;升级同步用 `bl skill update`(只更新已安装,不装新 skill);业务 skill **不**声明 `companions` - [ ] **协议读取**:CRITICAL / references 可链 `../bailian-protocol/…`;若读不到 → 停止执行 `bl`,提示 `bl skill init` +- [ ] **调用归因**:业务 skill 与协议预检执行 `bl` 时必须带 Agent 归因前缀(见 `bailian-protocol`「Call attribution」);人类终端不要设这些变量 - [ ] **高风险确认**:统一由 `bailian-protocol` 定义;reference / leaf help 以 `risk: high` 明示风险,业务 skill 不得引导 Agent 自动补 `--yes`。遇到 exit code 7 / `requires_confirmation` 时停止执行并请求确认;目标或范围变化后重新确认 - [ ] **正常控制流**:`requires_confirmation` 不是 CLI bug,`assets/issue-reporting.md` 必须将 exit code 7 保持在 EXCLUDE 范围 - [ ] **软 hand-off**:兄弟业务 skill **只写 skill 名**;已安装则 Read,未安装则 `bl … --help` 或提示整包安装;**不要**把 `../bailian-gen/…` 等写成执行前提 diff --git a/docs/agents/telemetry-change.md b/docs/agents/telemetry-change.md index 8dc0e68fb..d8e6ed9f0 100644 --- a/docs/agents/telemetry-change.md +++ b/docs/agents/telemetry-change.md @@ -95,9 +95,18 @@ source-config 只用于百炼 / DashScope API 侧消费,不发送到通用网 - `command`、`timestamp`、`durationMs`、`success` - `cliVersion`、`nodeVersion`、`os` - `authMethod` +- `callerType`(必填:`agent` 或 `human`);`callerType=agent` 时可选 `callerName`、`skillName`、`skillVersion` - 失败时的 `errorMessage`、`exitCode`、`httpStatus`、`requestId` - 安全 allowlist 过滤后的 `params` +调用方归因只认本次进程的 `BAILIAN_CALLER_*`(由 `readCaller` 归一化后写入事件),口径对齐 Ark CLI: + +- `BAILIAN_CALLER_TYPE` 为 `agent` / `ai_agent`(大小写不敏感)→ `callerType=agent` +- 未设置、空白、显式 `human` 或其他值 → `callerType=human`;人类终端不要手动设这些变量 +- `callerName` / `skillName` / `skillVersion` 仅在 `agent` 时发送;`kscli` 通常没有 skill 字段 + +新 CLI 每条进入 middleware 的命令事件都有 `callerType`。旧 CLI 没有该字段。看板只统计带 `callerType` 的事件,不能把字段缺失混进分母。新 CLI + 旧 skill / Agent 漏设变量时,会落进 `human`(与 Ark 相同,靠 skill 强制贴标签收敛)。`BAILIAN_CALLER_*` 是调用方声明,不是 `Identity`,不得用来猜 `bl` / `kscli`。 + 参数默认不上传,只有 `packages/core/src/telemetry/tracker.ts` 的 `PARAM_ALLOWLIST` 中字段会进入事件。不得加入 prompt、凭证、文件路径、URL、账号/租户/工作空间 ID 或其他用户内容。 `page` 仅记录有限数值页码;Webhook 等命令使用的不透明字符串游标不得进入本地日志或远端 AEM,即使字符串内容看起来是数字。 @@ -113,16 +122,16 @@ source-config 只用于百炼 / DashScope API 侧消费,不发送到通用网 AEM 映射: -| AEM 字段 | 内容 | -| ---------- | ------------------------------------------------------------------ | -| event name | 命令路径 | -| `et` | `EXP` | -| `ext` | 除 `command`、`params` 外的结构化事件字段,包含失败时的 `exitCode` | -| `c1` | allowlist 参数 | -| `c2` | `success` / `failure` | -| `c3` | HTTP status | -| `c4` | 错误文案,最多 500 字符 | -| `c5` | request ID | +| AEM 字段 | 内容 | +| ---------- | -------------------------------------------------------------------------------- | +| event name | 命令路径 | +| `et` | `EXP` | +| `ext` | 除 `command`、`params` 外的结构化事件字段,含 `callerType` 与失败时的 `exitCode` | +| `c1` | allowlist 参数 | +| `c2` | `success` / `failure` | +| `c3` | HTTP status | +| `c4` | 错误文案,最多 500 字符 | +| `c5` | request ID | 远端发送是 best-effort,不得阻塞命令或改变退出码。正常退出最多等待 1 秒,SIGINT 最多等待 500 ms。 @@ -140,6 +149,7 @@ AEM 映射: - [ ] 同时核对 `packages/core/src/client/http.ts`、`mcp.ts`、`instrumented-fetch.ts`、`client.ts` 与 `files/upload.ts` - [ ] 产品身份必须来自 `Identity`;不得从命令路径、环境变量或 `process.argv` 猜测 +- [ ] `BAILIAN_CALLER_*` 是调用方声明,不得用来猜产品身份(`bl` / `kscli`) - [ ] `bl` 与 `kscli` 必须分别验证 `binName`、`clientName`、`version` - [ ] OSS、结果文件、npm、二进制和 Skill 下载不得为了业务渠道统计新增 source-config - [ ] 改 URL / host 范围时同时执行 [URL / 渠道变更](url-change.md) 清单 @@ -148,6 +158,7 @@ AEM 映射: - [ ] 更新 `TrackingEvent`、`createTrackingEvent()` 与 `buildRemoteAemOptions()` 的字段映射 - [ ] 本地 JSONL 与远端 AEM 必须基于同一结构化事件,不能维护两套字段口径 +- [ ] 调用方字段经 `readCaller` → `TrackingDeps.caller` → 事件;未设置默认 `human`,仅显式 Agent 声明为 `agent` - [ ] 成功与失败均覆盖;遥测异常必须静默且不改变业务退出码 - [ ] runtime 本地语义错误应记录 `exitCode`;新增字段默认随 AEM `ext` 上报,无需占用新的 `c1`—`c5` - [ ] 检查 `DO_NOT_TRACK=1` 与 `telemetry: false` 两个关闭入口 @@ -157,15 +168,17 @@ AEM 映射: ```sh rg -n "trackingHeaders|x-dashscope-source-config|User-Agent" packages --glob '*.ts' -rg -n "trackCommandExecution|PARAM_ALLOWLIST|buildRemoteAemOptions" packages/core packages/runtime --glob '*.ts' +rg -n "trackCommandExecution|PARAM_ALLOWLIST|buildRemoteAemOptions|readCaller" packages/core packages/runtime --glob '*.ts' vp check -vp test packages/core/tests packages/commands/tests/e2e/auth.e2e.test.ts +vp test packages/core/tests packages/runtime/tests/telemetry-stage.test.ts packages/commands/tests/e2e/auth.e2e.test.ts ``` ## 常见漏点 - ✗ 只看 AEM 命令事件,误以为它能替代网关侧请求渠道统计 - ✗ 把 `authMethod` 当成实际凭证来源;它只是命令声明的鉴权域 +- ✗ 把旧 CLI「没有 `callerType`」和「`callerType=human`」混进同一分母宣称人工占比 +- ✗ 用 `BAILIAN_CALLER_*` 猜测产品身份,或根据 TTY / 安装目录反推调用方 - ✗ 新增 bypass `fetch` 后漏掉应由网关消费的 source-config,或把它发给 OSS / npm / 第三方下载地址 - ✗ 只改 `bl` 入口,导致 `kscli` 的产品名或版本标签错误 - ✗ 把帮助、版本或参数校验失败算进“全部命令”;这些路径当前没有进入 telemetry middleware diff --git a/packages/core/src/telemetry/caller.ts b/packages/core/src/telemetry/caller.ts new file mode 100644 index 000000000..6c1b1df30 --- /dev/null +++ b/packages/core/src/telemetry/caller.ts @@ -0,0 +1,59 @@ +/** Parse BAILIAN_CALLER_* from the process env. Defaults to human. */ + +export type CallerAttribution = + | { callerType: "human" } + | { + callerType: "agent"; + callerName: string; + skillName?: string; + skillVersion?: string; + }; + +const CALLER_TYPE_ENV = "BAILIAN_CALLER_TYPE"; +const CALLER_NAME_ENV = "BAILIAN_CALLER_NAME"; +const SKILL_NAME_ENV = "BAILIAN_SKILL_NAME"; +const SKILL_VERSION_ENV = "BAILIAN_SKILL_VERSION"; + +const NAME_PATTERN = /^[a-z0-9][a-z0-9.-]{0,63}$/; +const SKILL_NAME_PATTERN = /^bailian-[a-z0-9-]{1,64}$/; +const SKILL_VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]{1,20})?$/; + +function readTrimmed(env: NodeJS.ProcessEnv, key: string): string | undefined { + const raw = env[key]; + if (typeof raw !== "string") return undefined; + const trimmed = raw.trim(); + return trimmed.length > 0 ? trimmed : undefined; +} + +/** Normalize host-reported name to a stable id, or `unknown`. */ +function normalizeCallerName(raw: string | undefined): string { + if (!raw) return "unknown"; + const normalized = raw.toLowerCase().replace(/[\s_]+/g, "-"); + return NAME_PATTERN.test(normalized) ? normalized : "unknown"; +} + +/** Env-only attribution; no TTY or install-path heuristics. */ +export function readCaller(env: NodeJS.ProcessEnv): CallerAttribution { + const callerType = readTrimmed(env, CALLER_TYPE_ENV)?.toLowerCase(); + if (callerType !== "agent" && callerType !== "ai_agent") { + return { callerType: "human" }; + } + + const skillNameRaw = readTrimmed(env, SKILL_NAME_ENV)?.toLowerCase(); + const skillName = + skillNameRaw !== undefined && SKILL_NAME_PATTERN.test(skillNameRaw) ? skillNameRaw : undefined; + const skillVersionRaw = readTrimmed(env, SKILL_VERSION_ENV); + const skillVersion = + skillName !== undefined && + skillVersionRaw !== undefined && + SKILL_VERSION_PATTERN.test(skillVersionRaw) + ? skillVersionRaw + : undefined; + + return { + callerType: "agent", + callerName: normalizeCallerName(readTrimmed(env, CALLER_NAME_ENV)), + ...(skillName !== undefined ? { skillName } : {}), + ...(skillVersion !== undefined ? { skillVersion } : {}), + }; +} diff --git a/packages/core/src/telemetry/event.ts b/packages/core/src/telemetry/event.ts index 228bf699f..911ba2b63 100644 --- a/packages/core/src/telemetry/event.ts +++ b/packages/core/src/telemetry/event.ts @@ -1,4 +1,5 @@ import type { AuthRequirement } from "../types/command.ts"; +import type { CallerAttribution } from "./caller.ts"; export interface TrackingEvent { command: string; @@ -14,6 +15,11 @@ export interface TrackingEvent { os: string; authMethod?: AuthRequirement; params?: Record; + /** Always present on new CLI events: `agent` or `human`. */ + callerType: CallerAttribution["callerType"]; + callerName?: string; + skillName?: string; + skillVersion?: string; } export function createTrackingEvent(opts: { @@ -24,6 +30,7 @@ export function createTrackingEvent(opts: { cliVersion: string; authMethod?: AuthRequirement; params?: Record; + caller: CallerAttribution; }): TrackingEvent { const event: TrackingEvent = { command: opts.command, @@ -33,8 +40,15 @@ export function createTrackingEvent(opts: { cliVersion: opts.cliVersion, nodeVersion: process.version, os: process.platform, + callerType: opts.caller.callerType, }; + if (opts.caller.callerType === "agent") { + event.callerName = opts.caller.callerName; + if (opts.caller.skillName !== undefined) event.skillName = opts.caller.skillName; + if (opts.caller.skillVersion !== undefined) event.skillVersion = opts.caller.skillVersion; + } + if (opts.authMethod) { event.authMethod = opts.authMethod; } diff --git a/packages/core/src/telemetry/index.ts b/packages/core/src/telemetry/index.ts index a21f78571..e70ea5fb4 100644 --- a/packages/core/src/telemetry/index.ts +++ b/packages/core/src/telemetry/index.ts @@ -1,4 +1,7 @@ +export type { CallerAttribution } from "./caller.ts"; +export { readCaller } from "./caller.ts"; export type { TrackingEvent } from "./event.ts"; export { createTrackingEvent } from "./event.ts"; export { localSink, remoteSink, flushTelemetry } from "./sink.ts"; export { trackCommandExecution } from "./tracker.ts"; +export type { TrackingDeps } from "./tracker.ts"; diff --git a/packages/core/src/telemetry/tracker.ts b/packages/core/src/telemetry/tracker.ts index a65534835..2f161016e 100644 --- a/packages/core/src/telemetry/tracker.ts +++ b/packages/core/src/telemetry/tracker.ts @@ -1,6 +1,7 @@ import type { Identity, Settings } from "../config/schema.ts"; import { BailianError } from "../errors/base.ts"; import type { AuthRequirement } from "../types/command.ts"; +import type { CallerAttribution } from "./caller.ts"; import { createTrackingEvent } from "./event.ts"; import { localSink, remoteSink } from "./sink.ts"; @@ -89,6 +90,8 @@ export interface TrackingDeps { identity: Identity; settings: Settings; authMethod?: AuthRequirement; + /** From `readCaller(process.env)` in telemetryStage. */ + caller: CallerAttribution; } export async function trackCommandExecution( @@ -133,6 +136,7 @@ export async function trackCommandExecution( cliVersion: deps.identity.version, authMethod: deps.authMethod, params: extractParams(flags), + caller: deps.caller, }); // Fire-and-forget — never block the CLI exit or mask errors diff --git a/packages/core/tests/telemetry-caller.test.ts b/packages/core/tests/telemetry-caller.test.ts new file mode 100644 index 000000000..057a578af --- /dev/null +++ b/packages/core/tests/telemetry-caller.test.ts @@ -0,0 +1,142 @@ +import { expect, test } from "vite-plus/test"; +import { readCaller } from "../src/telemetry/caller.ts"; + +test.each([ + { label: "missing", env: {} }, + { label: "blank", env: { BAILIAN_CALLER_TYPE: " " } }, + { label: "explicit human", env: { BAILIAN_CALLER_TYPE: "human" } }, + { label: "illegal false", env: { BAILIAN_CALLER_TYPE: "false" } }, + { label: "illegal ai-agent", env: { BAILIAN_CALLER_TYPE: "ai-agent" } }, + { label: "illegal zero", env: { BAILIAN_CALLER_TYPE: "0" } }, +])("maps $label to human without agent fields", ({ env }) => { + expect(readCaller(env)).toEqual({ callerType: "human" }); +}); + +test.each([ + { label: "agent", type: "agent" }, + { label: "ai_agent", type: "ai_agent" }, + { label: "Agent", type: "Agent" }, + { label: "AI_AGENT", type: "AI_AGENT" }, + { label: "padded agent", type: " agent " }, +])("accepts $label as agent", ({ type }) => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: type, + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "bailian-cli", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", + }); +}); + +test("normalizes callerName and falls back to unknown", () => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: " Claude Code ", + }), + ).toEqual({ callerType: "agent", callerName: "claude-code" }); + + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "qwen_code", + }), + ).toEqual({ callerType: "agent", callerName: "qwen-code" }); + + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "bad/name!", + }), + ).toEqual({ callerType: "agent", callerName: "unknown" }); + + expect(readCaller({ BAILIAN_CALLER_TYPE: "agent" })).toEqual({ + callerType: "agent", + callerName: "unknown", + }); +}); + +test("drops illegal skillName and only keeps version when skillName is valid", () => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "not-bailian", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ callerType: "agent", callerName: "cursor" }); + + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "bailian-cli", + BAILIAN_SKILL_VERSION: "not-a-version", + }), + ).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + }); + + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "bailian-cli", + BAILIAN_SKILL_VERSION: "2.5.0-beta.1", + }), + ).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0-beta.1", + }); +}); + +test("lowercases skillName before validation", () => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "Bailian-CLI", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", + }); + + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "agent", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "BAILIAN-GEN", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-gen", + skillVersion: "2.5.0", + }); +}); + +test("ignores agent detail fields when callerType is human", () => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: "human", + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "bailian-cli", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ callerType: "human" }); +}); diff --git a/packages/core/tests/telemetry-tracker.test.ts b/packages/core/tests/telemetry-tracker.test.ts index 1870673ae..c623806a6 100644 --- a/packages/core/tests/telemetry-tracker.test.ts +++ b/packages/core/tests/telemetry-tracker.test.ts @@ -2,6 +2,7 @@ import { expect, test, vi } from "vite-plus/test"; import type { Identity, Settings } from "../src/config/schema.ts"; import { BailianError } from "../src/errors/base.ts"; import { ExitCode } from "../src/errors/codes.ts"; +import type { CallerAttribution } from "../src/telemetry/caller.ts"; import { buildRemoteAemOptions, type TrackingEvent } from "../src/telemetry/event.ts"; const sinkMocks = vi.hoisted(() => ({ @@ -20,6 +21,14 @@ const identity: Identity = { npmPackage: "bailian-cli", }; +const humanCaller: CallerAttribution = { callerType: "human" }; +const agentCaller: CallerAttribution = { + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", +}; + test("records BailianError exitCode in local events and AEM ext", async () => { sinkMocks.localSink.mockClear(); sinkMocks.remoteSink.mockClear(); @@ -31,6 +40,7 @@ test("records BailianError exitCode in local events and AEM ext", async () => { identity, settings: { telemetry: true } as Settings, authMethod: "apiKey", + caller: humanCaller, }, ["knowledge", "doc", "delete"], {}, @@ -47,9 +57,13 @@ test("records BailianError exitCode in local events and AEM ext", async () => { success: false, exitCode: 7, errorMessage: "该操作会永久删除文档。", + callerType: "human", }); + expect(event.callerName).toBeUndefined(); + expect(event.skillName).toBeUndefined(); + expect(event.skillVersion).toBeUndefined(); expect(buildRemoteAemOptions(event)).toMatchObject({ - ext: expect.objectContaining({ exitCode: 7 }), + ext: expect.objectContaining({ exitCode: 7, callerType: "human" }), }); }); @@ -67,7 +81,12 @@ test.each([ sinkMocks.remoteSink.mockClear(); await trackCommandExecution( - { identity, settings: { telemetry: true } as Settings, authMethod: "apiKey" }, + { + identity, + settings: { telemetry: true } as Settings, + authMethod: "apiKey", + caller: humanCaller, + }, ["managed-agent", "webhook", "events"], { page, pageSize: 20 }, async () => {}, @@ -82,3 +101,60 @@ test.each([ expect(buildRemoteAemOptions(remoteEvent).c1).toEqual(expectedParams); }, ); + +test("keeps agent attribution on success and in AEM ext", async () => { + sinkMocks.localSink.mockClear(); + sinkMocks.remoteSink.mockClear(); + + await trackCommandExecution( + { + identity, + settings: { telemetry: true } as Settings, + authMethod: "apiKey", + caller: agentCaller, + }, + ["config", "show"], + {}, + async () => {}, + ); + + const event = sinkMocks.localSink.mock.calls[0]![0]; + expect(event).toMatchObject({ + success: true, + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", + }); + expect(event.params).toBeUndefined(); + expect(buildRemoteAemOptions(event)).toMatchObject({ + ext: expect.objectContaining({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", + }), + }); +}); + +test("does not call sinks when telemetry is disabled", async () => { + sinkMocks.localSink.mockClear(); + sinkMocks.remoteSink.mockClear(); + const next = vi.fn(async () => {}); + + await trackCommandExecution( + { + identity, + settings: { telemetry: false } as Settings, + authMethod: "apiKey", + caller: agentCaller, + }, + ["config", "show"], + {}, + next, + ); + + expect(next).toHaveBeenCalledOnce(); + expect(sinkMocks.localSink).not.toHaveBeenCalled(); + expect(sinkMocks.remoteSink).not.toHaveBeenCalled(); +}); diff --git a/packages/runtime/src/middleware.ts b/packages/runtime/src/middleware.ts index b44271b2a..c98e186f5 100644 --- a/packages/runtime/src/middleware.ts +++ b/packages/runtime/src/middleware.ts @@ -19,6 +19,7 @@ import { resolveApiKey, resolveConsole, resolveOpenApi, + readCaller, resolveModelBaseUrlState, selectApiKeyResolutionSources, trackCommandExecution, @@ -176,6 +177,7 @@ export const telemetryStage: Middleware = (ctx, next) => { identity: ctx.identity, settings: ctx.settings, authMethod: ctx.command.auth, + caller: readCaller(process.env), }, ctx.path, ctx.flags, diff --git a/packages/runtime/tests/telemetry-stage.test.ts b/packages/runtime/tests/telemetry-stage.test.ts new file mode 100644 index 000000000..1e3133298 --- /dev/null +++ b/packages/runtime/tests/telemetry-stage.test.ts @@ -0,0 +1,87 @@ +import { afterEach, beforeEach, expect, test, vi } from "vite-plus/test"; +import type { CallerAttribution } from "bailian-cli-core"; + +const trackerMocks = vi.hoisted(() => ({ + trackCommandExecution: vi.fn( + async ( + _deps: unknown, + _path: string[], + _flags: Record, + next: () => Promise, + ) => { + await next(); + }, + ), +})); + +vi.mock("bailian-cli-core", async () => { + const actual = await vi.importActual("bailian-cli-core"); + return { + ...actual, + trackCommandExecution: trackerMocks.trackCommandExecution, + }; +}); + +import { telemetryStage, type RunContext } from "../src/middleware.ts"; + +function makeContext(): RunContext { + return { + identity: { + binName: "bl", + version: "0.0.0-test", + clientName: "bailian-cli-test", + npmPackage: "bailian-cli", + }, + path: ["config", "show"], + command: { auth: "none" }, + settings: { telemetry: true }, + flags: {}, + } as RunContext; +} + +beforeEach(() => { + trackerMocks.trackCommandExecution.mockClear(); +}); + +afterEach(() => { + vi.unstubAllEnvs(); +}); + +test("wires process.env through readCaller into trackCommandExecution", async () => { + vi.stubEnv("BAILIAN_CALLER_TYPE", "agent"); + vi.stubEnv("BAILIAN_CALLER_NAME", "cursor"); + vi.stubEnv("BAILIAN_SKILL_NAME", "bailian-cli"); + vi.stubEnv("BAILIAN_SKILL_VERSION", "2.5.0"); + const next = vi.fn(async () => {}); + + await telemetryStage(makeContext(), next); + + expect(trackerMocks.trackCommandExecution).toHaveBeenCalledOnce(); + const deps = trackerMocks.trackCommandExecution.mock.calls[0]![0] as { + caller: CallerAttribution; + authMethod: string; + }; + expect(deps.caller).toEqual({ + callerType: "agent", + callerName: "cursor", + skillName: "bailian-cli", + skillVersion: "2.5.0", + }); + expect(deps.authMethod).toBe("none"); + expect(next).toHaveBeenCalledOnce(); +}); + +test("defaults to human when caller env is unset", async () => { + vi.stubEnv("BAILIAN_CALLER_TYPE", undefined); + vi.stubEnv("BAILIAN_CALLER_NAME", undefined); + vi.stubEnv("BAILIAN_SKILL_NAME", undefined); + vi.stubEnv("BAILIAN_SKILL_VERSION", undefined); + const next = vi.fn(async () => {}); + + await telemetryStage(makeContext(), next); + + const deps = trackerMocks.trackCommandExecution.mock.calls[0]![0] as { + caller: CallerAttribution; + }; + expect(deps.caller).toEqual({ callerType: "human" }); +}); diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 24a78594a..7d1e36d9b 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -21,7 +21,7 @@ description: >- # Aliyun Model Studio CLI (`bl`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** > **Family hub** — This skill owns Bailian resource commands and the hub `reference/` (apps, knowledge, usage, auth, config, …). > Shared protocol → [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md) (install the full family with `bl skill init`). diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index c00c1a514..1d7b4e30e 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -16,7 +16,7 @@ description: >- # Bailian fine-tuning pipeline (`bl dataset` / `bl finetune` / `bl deploy`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** ## End-to-end workflow (follow in order) diff --git a/skills/bailian-gen/SKILL.md b/skills/bailian-gen/SKILL.md index 102912664..94ccb8aef 100644 --- a/skills/bailian-gen/SKILL.md +++ b/skills/bailian-gen/SKILL.md @@ -20,7 +20,7 @@ description: >- # Bailian media generation & understanding (`bl image` / `bl video` / `bl speech` / `bl omni` / `bl vision`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** ## Consent (short version; full rules in bailian-protocol) diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index 84331217e..b4942d8e7 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -18,7 +18,7 @@ description: >- # Bailian managed agent IaC (`bl managed-agent`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** ## Safety guardrail (the most important rule) diff --git a/skills/bailian-memory/SKILL.md b/skills/bailian-memory/SKILL.md index 5cb67e466..6fbb3282b 100644 --- a/skills/bailian-memory/SKILL.md +++ b/skills/bailian-memory/SKILL.md @@ -19,7 +19,7 @@ description: >- **读取本 Skill、检查本地启用状态与发送云端请求是三个不同步骤。** 前两步不以已经启用为前提;只有云端个人记忆读写需要启用授权。安装 Skill 不代表用户已授权上传。 -执行任何 `bl` 命令前,先读取共享协议 [bailian-protocol](../bailian-protocol/SKILL.md),遵循鉴权、版本预检和高风险确认。协议缺失不妨碍识别记忆意图或解释启用流程;但执行命令前须补齐,提示 `bl skill init`,不能静默退回内置记忆并声称本服务已工作。 +执行任何 `bl` 命令前,先读取共享协议 [bailian-protocol](../bailian-protocol/SKILL.md),遵循鉴权、版本预检、调用归因和高风险确认。协议缺失不妨碍识别记忆意图或解释启用流程;但执行命令前须补齐,提示 `bl skill init`,不能静默退回内置记忆并声称本服务已工作。 ## 入口与范围 diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index dfacbb90d..663f10633 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -21,7 +21,7 @@ description: >- > bl skill init > ``` > -> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。 +> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。Agents wrap with [Call attribution](#call-attribution-mandatory-for-every-agent-bl-command) (`bailian-protocol`). ## Provider selection and consent @@ -72,9 +72,38 @@ After approval, treat Bailian as selected for the current task. Do not ask again - `bailian-protocol`:靠 `bl skill init` 与业务 skill 同装;CRITICAL 可用相对路径 `../bailian-protocol/…`。读不到则停止跑 `bl`,提示整包安装。 - 其它 bailian-\* 业务 skill:只按名字提及,**不要**写死 `../bailian-*/SKILL.md` 当执行前提。 +## Call attribution (mandatory for every Agent `bl` command) + +Examples in this protocol, `assets/`, and business skills show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with the prefix below (declared once here). Humans must not set these variables; unset defaults to human. + +```bash +BAILIAN_CALLER_TYPE=agent \ +BAILIAN_CALLER_NAME= \ +BAILIAN_SKILL_NAME= \ +BAILIAN_SKILL_VERSION= \ +bl +``` + +Pick `` from the task (do not repeat the prefix in every example): + +| Task | `` | +| ------------------------------------------------------------------------ | -------------------------------------- | +| Install, `skill init` / `skill update`, `bl update`, protocol pre-flight | `bailian-protocol` | +| auth, config, text, app, knowledge, usage | `bailian-cli` | +| image / video / speech / vision / omni | `bailian-gen` | +| Other domain commands | The `bailian-*` skill currently in use | + +Conventions: + +- `BAILIAN_CALLER_NAME`: stable host id (`cursor` / `claude-code` / `codex` / `qwen-code`); use `unknown` when unsure. Do not scan install directories. +- `BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md`. +- Prefix each `bl` invocation; do not `export` into the shell session. `bl --version` / `--help` skip telemetry and need no prefix. +- If the host accepts one-shot env without rewriting the command string, set the same four variables there. +- PowerShell: fresh subprocess, or save/restore all four (restore to unset when they were unset). + ## Version & updates (after provider selection, before the first `bl` command) -**MANDATORY:** Before running any `bl` command, complete the **Agent pre-flight checklist** in [`assets/versioning.md`](assets/versioning.md). Do NOT run any `bl` command until the checklist is complete. If versions mismatch, ask the user whether to upgrade — do not proceed silently. +**MANDATORY:** Before running any `bl` command, complete the **Agent pre-flight checklist** in [`assets/versioning.md`](assets/versioning.md). Do NOT run any `bl` command until the checklist is complete. If versions mismatch, ask the user whether to upgrade — do not proceed silently. Pre-flight `bl` commands that enter middleware (for example `bl skill update` / `bl update` / `bl skill init`) must use the same call-attribution prefix above; owning skill for those is `bailian-protocol`. ## Setup & auth @@ -94,7 +123,7 @@ bl text chat --message "Write a poem about spring" # explicit text-model smoke ## Color output When an agent needs plain text without ANSI color codes (for parsing, logs, or -snapshots), run the command with `NO_COLOR=1`: +snapshots), run with `NO_COLOR=1` (and Call attribution when run by an Agent): ```bash NO_COLOR=1 bl config show --output text diff --git a/skills/bailian-protocol/assets/setup.md b/skills/bailian-protocol/assets/setup.md index d61e2c518..7c7cd840a 100644 --- a/skills/bailian-protocol/assets/setup.md +++ b/skills/bailian-protocol/assets/setup.md @@ -7,6 +7,8 @@ Read this only when you need to install `bl`, change credentials/endpoint, or inspect config keys. Day-to-day command routing lives in the business skills (`bailian-cli` / `bailian-gen` / …). +Examples stay bare `bl …`. Agents wrap them with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command): `bailian-protocol` for install / `skill init`, `bailian-cli` for auth / config. + --- ## Install diff --git a/skills/bailian-protocol/assets/versioning.md b/skills/bailian-protocol/assets/versioning.md index 6de95f88c..b598eada0 100644 --- a/skills/bailian-protocol/assets/versioning.md +++ b/skills/bailian-protocol/assets/versioning.md @@ -3,6 +3,8 @@ > Hand-maintained. Lives in `bailian-protocol/assets/` (not auto-generated from command metadata). > Entry point: [SKILL.md → Version & updates](../SKILL.md#version--updates-after-provider-selection-before-the-first-bl-command). +Agents wrap middleware `bl` commands with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command); `` here is always `bailian-protocol`. Examples stay bare. `bl --version` / `--help` need no prefix. + ## Agent pre-flight checklist (MANDATORY) **Do NOT run any `bl` command until you complete this checklist.** Run it **once per session**, before the first `bl` command. Cache the result — do not re-check before every command. @@ -18,7 +20,7 @@ ```bash bl skill update ``` - - If `bailian-protocol` or another needed skill is missing, stop and run `bl skill init`. Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. + - If `bailian-protocol` or another needed skill is missing, stop and run `bl skill init` (same Call attribution, `bailian-protocol`). Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. - Do not trust a stale `reference/` when versions mismatch — flags may be wrong. 4. Check the latest published CLI version: ```bash @@ -27,7 +29,10 @@ 5. If the installed `bl` is **older** than the latest npm version, **STOP** the current task and **ask the user** (report skill version, installed CLI version, and npm latest): > A newer version of bl is available (current: X.Y.Z, latest: A.B.C). Upgrade before continuing? - **Do NOT auto-upgrade silently** — the user decides. - - If the user agrees: run `bl update`, then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) + - If the user agrees: run `bl update` (same Call attribution), then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) + ```bash + bl update + ``` - If the user declines: continue with the current version and note it in the summary. - If `npm view` / `bl update` fails (offline, registry blocked, permission): continue with the current `bl` and tell the user it could not be updated. 6. Only proceed with the user's actual task after the above is resolved. diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index 86cdd80c1..7cf6bfca0 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -15,7 +15,7 @@ description: >- # Bailian Sandbox (`bl sandbox`) -Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. +Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. ## Scope and setup diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 7dc93855c..1622d94a1 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -19,7 +19,7 @@ description: >- # Bailian web search routing (`bailian-web-search`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** > **Scope:** model-aware routing for web search inside Agent-driven `bl` workflows — this skill owns the routing decision only. > Command flags / usage / examples: Read skill `bailian-cli` reference if installed; else `bl search web --help` / `bl text chat --help` — do not guess flags. From 2853389570d3294b06f535b6e0502ac66d79e496 Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Thu, 22 Oct 2026 10:24:52 +0800 Subject: [PATCH 2/6] fix(telemetry): record unrecognized callers as unknown instead of human --- docs/agents/telemetry-change.md | 12 ++++++------ packages/core/src/telemetry/caller.ts | 6 +++--- packages/core/src/telemetry/event.ts | 2 +- packages/core/tests/telemetry-caller.test.ts | 8 ++++---- packages/core/tests/telemetry-tracker.test.ts | 10 +++++----- packages/runtime/tests/telemetry-stage.test.ts | 4 ++-- skills/bailian-protocol/SKILL.md | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/agents/telemetry-change.md b/docs/agents/telemetry-change.md index d8e6ed9f0..dd35b278d 100644 --- a/docs/agents/telemetry-change.md +++ b/docs/agents/telemetry-change.md @@ -95,17 +95,17 @@ source-config 只用于百炼 / DashScope API 侧消费,不发送到通用网 - `command`、`timestamp`、`durationMs`、`success` - `cliVersion`、`nodeVersion`、`os` - `authMethod` -- `callerType`(必填:`agent` 或 `human`);`callerType=agent` 时可选 `callerName`、`skillName`、`skillVersion` +- `callerType`(必填:`agent` 或 `unknown`);`callerType=agent` 时可选 `callerName`、`skillName`、`skillVersion` - 失败时的 `errorMessage`、`exitCode`、`httpStatus`、`requestId` - 安全 allowlist 过滤后的 `params` -调用方归因只认本次进程的 `BAILIAN_CALLER_*`(由 `readCaller` 归一化后写入事件),口径对齐 Ark CLI: +调用方归因只认本次进程的 `BAILIAN_CALLER_*`(由 `readCaller` 归一化后写入事件): - `BAILIAN_CALLER_TYPE` 为 `agent` / `ai_agent`(大小写不敏感)→ `callerType=agent` -- 未设置、空白、显式 `human` 或其他值 → `callerType=human`;人类终端不要手动设这些变量 +- 未设置、空白或其他值 → `callerType=unknown`;不要把该字段当成人工 - `callerName` / `skillName` / `skillVersion` 仅在 `agent` 时发送;`kscli` 通常没有 skill 字段 -新 CLI 每条进入 middleware 的命令事件都有 `callerType`。旧 CLI 没有该字段。看板只统计带 `callerType` 的事件,不能把字段缺失混进分母。新 CLI + 旧 skill / Agent 漏设变量时,会落进 `human`(与 Ark 相同,靠 skill 强制贴标签收敛)。`BAILIAN_CALLER_*` 是调用方声明,不是 `Identity`,不得用来猜 `bl` / `kscli`。 +新 CLI 每条进入 middleware 的命令事件都有 `callerType`。旧 CLI 没有该字段。看板只统计带 `callerType` 的事件,不能把字段缺失混进分母。`unknown` 只表示未识别为 agent,不是人工。新 CLI + 旧 skill / Agent 漏设变量时,会落进 `unknown`。`BAILIAN_CALLER_*` 是调用方声明,不是 `Identity`,不得用来猜 `bl` / `kscli`。 参数默认不上传,只有 `packages/core/src/telemetry/tracker.ts` 的 `PARAM_ALLOWLIST` 中字段会进入事件。不得加入 prompt、凭证、文件路径、URL、账号/租户/工作空间 ID 或其他用户内容。 @@ -158,7 +158,7 @@ AEM 映射: - [ ] 更新 `TrackingEvent`、`createTrackingEvent()` 与 `buildRemoteAemOptions()` 的字段映射 - [ ] 本地 JSONL 与远端 AEM 必须基于同一结构化事件,不能维护两套字段口径 -- [ ] 调用方字段经 `readCaller` → `TrackingDeps.caller` → 事件;未设置默认 `human`,仅显式 Agent 声明为 `agent` +- [ ] 调用方字段经 `readCaller` → `TrackingDeps.caller` → 事件;仅显式 `agent` / `ai_agent` 为 `agent`,其余为 `unknown` - [ ] 成功与失败均覆盖;遥测异常必须静默且不改变业务退出码 - [ ] runtime 本地语义错误应记录 `exitCode`;新增字段默认随 AEM `ext` 上报,无需占用新的 `c1`—`c5` - [ ] 检查 `DO_NOT_TRACK=1` 与 `telemetry: false` 两个关闭入口 @@ -177,7 +177,7 @@ vp test packages/core/tests packages/runtime/tests/telemetry-stage.test.ts packa - ✗ 只看 AEM 命令事件,误以为它能替代网关侧请求渠道统计 - ✗ 把 `authMethod` 当成实际凭证来源;它只是命令声明的鉴权域 -- ✗ 把旧 CLI「没有 `callerType`」和「`callerType=human`」混进同一分母宣称人工占比 +- ✗ 把旧 CLI「没有 `callerType`」或「`callerType=unknown`」当成人工占比 - ✗ 用 `BAILIAN_CALLER_*` 猜测产品身份,或根据 TTY / 安装目录反推调用方 - ✗ 新增 bypass `fetch` 后漏掉应由网关消费的 source-config,或把它发给 OSS / npm / 第三方下载地址 - ✗ 只改 `bl` 入口,导致 `kscli` 的产品名或版本标签错误 diff --git a/packages/core/src/telemetry/caller.ts b/packages/core/src/telemetry/caller.ts index 6c1b1df30..8fbde3f66 100644 --- a/packages/core/src/telemetry/caller.ts +++ b/packages/core/src/telemetry/caller.ts @@ -1,7 +1,7 @@ -/** Parse BAILIAN_CALLER_* from the process env. Defaults to human. */ +/** Parse BAILIAN_CALLER_*. Only an explicit agent is `agent`; everything else is `unknown`. */ export type CallerAttribution = - | { callerType: "human" } + | { callerType: "unknown" } | { callerType: "agent"; callerName: string; @@ -36,7 +36,7 @@ function normalizeCallerName(raw: string | undefined): string { export function readCaller(env: NodeJS.ProcessEnv): CallerAttribution { const callerType = readTrimmed(env, CALLER_TYPE_ENV)?.toLowerCase(); if (callerType !== "agent" && callerType !== "ai_agent") { - return { callerType: "human" }; + return { callerType: "unknown" }; } const skillNameRaw = readTrimmed(env, SKILL_NAME_ENV)?.toLowerCase(); diff --git a/packages/core/src/telemetry/event.ts b/packages/core/src/telemetry/event.ts index 911ba2b63..bc31e60dd 100644 --- a/packages/core/src/telemetry/event.ts +++ b/packages/core/src/telemetry/event.ts @@ -15,7 +15,7 @@ export interface TrackingEvent { os: string; authMethod?: AuthRequirement; params?: Record; - /** Always present on new CLI events: `agent` or `human`. */ + /** Always present on new CLI events: `agent` or `unknown`. */ callerType: CallerAttribution["callerType"]; callerName?: string; skillName?: string; diff --git a/packages/core/tests/telemetry-caller.test.ts b/packages/core/tests/telemetry-caller.test.ts index 057a578af..e949e6305 100644 --- a/packages/core/tests/telemetry-caller.test.ts +++ b/packages/core/tests/telemetry-caller.test.ts @@ -8,8 +8,8 @@ test.each([ { label: "illegal false", env: { BAILIAN_CALLER_TYPE: "false" } }, { label: "illegal ai-agent", env: { BAILIAN_CALLER_TYPE: "ai-agent" } }, { label: "illegal zero", env: { BAILIAN_CALLER_TYPE: "0" } }, -])("maps $label to human without agent fields", ({ env }) => { - expect(readCaller(env)).toEqual({ callerType: "human" }); +])("maps $label to unknown without agent fields", ({ env }) => { + expect(readCaller(env)).toEqual({ callerType: "unknown" }); }); test.each([ @@ -130,7 +130,7 @@ test("lowercases skillName before validation", () => { }); }); -test("ignores agent detail fields when callerType is human", () => { +test("ignores agent detail fields when callerType is not agent", () => { expect( readCaller({ BAILIAN_CALLER_TYPE: "human", @@ -138,5 +138,5 @@ test("ignores agent detail fields when callerType is human", () => { BAILIAN_SKILL_NAME: "bailian-cli", BAILIAN_SKILL_VERSION: "2.5.0", }), - ).toEqual({ callerType: "human" }); + ).toEqual({ callerType: "unknown" }); }); diff --git a/packages/core/tests/telemetry-tracker.test.ts b/packages/core/tests/telemetry-tracker.test.ts index c623806a6..f36da576d 100644 --- a/packages/core/tests/telemetry-tracker.test.ts +++ b/packages/core/tests/telemetry-tracker.test.ts @@ -21,7 +21,7 @@ const identity: Identity = { npmPackage: "bailian-cli", }; -const humanCaller: CallerAttribution = { callerType: "human" }; +const unknownCaller: CallerAttribution = { callerType: "unknown" }; const agentCaller: CallerAttribution = { callerType: "agent", callerName: "cursor", @@ -40,7 +40,7 @@ test("records BailianError exitCode in local events and AEM ext", async () => { identity, settings: { telemetry: true } as Settings, authMethod: "apiKey", - caller: humanCaller, + caller: unknownCaller, }, ["knowledge", "doc", "delete"], {}, @@ -57,13 +57,13 @@ test("records BailianError exitCode in local events and AEM ext", async () => { success: false, exitCode: 7, errorMessage: "该操作会永久删除文档。", - callerType: "human", + callerType: "unknown", }); expect(event.callerName).toBeUndefined(); expect(event.skillName).toBeUndefined(); expect(event.skillVersion).toBeUndefined(); expect(buildRemoteAemOptions(event)).toMatchObject({ - ext: expect.objectContaining({ exitCode: 7, callerType: "human" }), + ext: expect.objectContaining({ exitCode: 7, callerType: "unknown" }), }); }); @@ -85,7 +85,7 @@ test.each([ identity, settings: { telemetry: true } as Settings, authMethod: "apiKey", - caller: humanCaller, + caller: unknownCaller, }, ["managed-agent", "webhook", "events"], { page, pageSize: 20 }, diff --git a/packages/runtime/tests/telemetry-stage.test.ts b/packages/runtime/tests/telemetry-stage.test.ts index 1e3133298..c575441eb 100644 --- a/packages/runtime/tests/telemetry-stage.test.ts +++ b/packages/runtime/tests/telemetry-stage.test.ts @@ -71,7 +71,7 @@ test("wires process.env through readCaller into trackCommandExecution", async () expect(next).toHaveBeenCalledOnce(); }); -test("defaults to human when caller env is unset", async () => { +test("defaults to unknown when caller env is unset", async () => { vi.stubEnv("BAILIAN_CALLER_TYPE", undefined); vi.stubEnv("BAILIAN_CALLER_NAME", undefined); vi.stubEnv("BAILIAN_SKILL_NAME", undefined); @@ -83,5 +83,5 @@ test("defaults to human when caller env is unset", async () => { const deps = trackerMocks.trackCommandExecution.mock.calls[0]![0] as { caller: CallerAttribution; }; - expect(deps.caller).toEqual({ callerType: "human" }); + expect(deps.caller).toEqual({ callerType: "unknown" }); }); diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 663f10633..74b408887 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -74,7 +74,7 @@ After approval, treat Bailian as selected for the current task. Do not ask again ## Call attribution (mandatory for every Agent `bl` command) -Examples in this protocol, `assets/`, and business skills show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with the prefix below (declared once here). Humans must not set these variables; unset defaults to human. +Examples in this protocol, `assets/`, and business skills show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with the prefix below (declared once here). Humans must not set these variables. Anything other than an explicit agent is recorded as `unknown`. ```bash BAILIAN_CALLER_TYPE=agent \ From 01037e1e87074ad868cd75e282a632a5ef47d450 Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Fri, 23 Oct 2026 13:49:10 +0800 Subject: [PATCH 3/6] docs(skills): fix memory list example, host name, and skill ownership prefix --- skills/bailian-cli/SKILL.md | 21 +++++- skills/bailian-finetune/SKILL.md | 19 +++++- skills/bailian-gen/SKILL.md | 27 ++++++-- skills/bailian-managed-agent/SKILL.md | 16 ++++- skills/bailian-memory/SKILL.md | 8 +++ skills/bailian-protocol/SKILL.md | 52 +++++++++------ skills/bailian-protocol/assets/setup.md | 66 +++++++++++-------- skills/bailian-protocol/assets/versioning.md | 22 ++++--- skills/bailian-sandbox/SKILL.md | 10 ++- .../assets/instance-connections.md | 4 +- skills/bailian-web-search/SKILL.md | 26 ++++++-- 11 files changed, 201 insertions(+), 70 deletions(-) diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 7d1e36d9b..0450619cc 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -23,6 +23,14 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Write a poem about spring" +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. + > **Family hub** — This skill owns Bailian resource commands and the hub `reference/` (apps, knowledge, usage, auth, config, …). > Shared protocol → [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md) (install the full family with `bl skill init`). > Soft hand-offs by skill name (Read if installed; else `bl … --help` / prompt `bl skill init`): `bailian-gen` (media) · `bailian-finetune` (training) · `bailian-managed-agent` (agents.yaml IaC) · `bailian-sandbox` (Sandbox lifecycle) · `bailian-web-search` (web search routing). @@ -93,12 +101,21 @@ Use this table only after the decision table in [`bailian-protocol`](../bailian- | Bailian Sandbox instance / template lifecycle | → skill `bailian-sandbox` | Fallback: `bl sandbox --help` | | Web search (model-aware routing) | → skill `bailian-web-search` | Token Plan vs MCP path + fallback; fallback: `bl search web --help` | -Flags, usage, and examples: see hub [`reference/`](reference/index.md) or `bl --help` — do not guess flags. Domain command details live in the owning skill's `reference/`. +Flags, usage, and examples: see hub [`reference/`](reference/index.md) or `bl --help` — do not guess flags. Domain command details live in the owning skill's `reference/`. Examples in `reference/` are human documentation; an Agent runs them with the Agent bash prefix above. --- ## Quick examples +**Agent shell** — copy this shape; replace `codex` with this host's id. Do not drop the variables. Reuse the four-variable shape on later commands; set `BAILIAN_SKILL_NAME` to the owning skill for that command. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Write a poem about spring in Chinese" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl usage stats +``` + +Human documentation only. Do not paste this fence into an Agent shell; prefix each `bl` line. + ```bash bl text chat --message "Write a poem about spring in Chinese" bl decision --workspace-id --state "Is this requesting a refund?" --questions '{"refund":{"type":"noul"}}' @@ -116,6 +133,8 @@ More examples per command: see `reference/.md` (e.g. [`reference/text.md` ### Find and call an app +Run each `bl` with the Agent bash prefix. The lines below are the arguments only. + 1. `bl app list --name --output json` 2. Pick `code` (app ID); handle `user_prompt_params` via `--biz-params '{"key":"value"}'` 3. `bl app call --app-id --prompt "..."` diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index 1d7b4e30e..45ba4c07d 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -16,7 +16,15 @@ description: >- # Bailian fine-tuning pipeline (`bl dataset` / `bl finetune` / `bl deploy`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** + +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-finetune BAILIAN_SKILL_VERSION=2.5.0 bl dataset validate --file train.jsonl +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. Example: after deploy, `bl text chat` uses `BAILIAN_SKILL_NAME=bailian-cli`, not `bailian-finetune`. The numbered workflow below is arguments only. ## End-to-end workflow (follow in order) @@ -67,6 +75,15 @@ Flags, usage, and examples: see [`reference/`](reference/index.md) or `bl - # Bailian media generation & understanding (`bl image` / `bl video` / `bl speech` / `bl omni` / `bl vision`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** + +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat in space" --out-dir ./out/ +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. ## Consent (short version; full rules in bailian-protocol) @@ -54,22 +62,24 @@ Flags, usage, and examples: see [`reference/`](reference/index.md) or `bl `: ```bash -bl config set --config media --key watermark --value false +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --config media --key watermark --value false ``` ## Local files (mandatory) Any command that accepts a **file URL** also accepts a **local path**; the CLI uploads to DashScope temporary storage (`oss://`, 48h) automatically. If the user gives a local file, pass the path directly — never ask them to upload or host a URL first. +Human documentation. Agent shell: prefix each `bl` line with the Agent bash block above. Do not paste this fence as-is. + ```bash bl image edit --image ./photo.png --prompt "Add sunset" bl video edit --video ./clip.mp4 --prompt "Anime style" @@ -80,6 +90,15 @@ bl speech recognize --url ./meeting.wav ## Quick examples +**Agent shell** — copy this shape; replace `codex` with this host's id. Do not drop the variables. Reuse the four-variable shape on later commands; set `BAILIAN_SKILL_NAME` to the owning skill for that command. If `bl` is inside `$(...)`, put the four variables inside the substitution. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat in space" --out-dir ./out/ +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl video generate --prompt "Sunset on the beach" --download sunset.mp4 +``` + +Human documentation only. Do not paste this fence into an Agent shell. + ```bash bl image generate --prompt "A cat in space" --out-dir ./out/ bl video generate --prompt "Sunset on the beach" --download sunset.mp4 diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index b4942d8e7..e98a0210d 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -18,7 +18,15 @@ description: >- # Bailian managed agent IaC (`bl managed-agent`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** + +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human fences below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-managed-agent BAILIAN_SKILL_VERSION=2.5.0 bl managed-agent plan +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. ## Safety guardrail (the most important rule) @@ -103,6 +111,8 @@ for explicit confirmation before re-running with `--yes`. `vault credential create --secret-env ` 中的参数是变量名,不是 Secret 明文。Secret 可来自 Shell export、CI Secret 注入或可选的 `.env`;CLI 会从当前目录向上自动加载最近的 `.env`,用户不必创建该文件。 +Human documentation. Agent shell: prefix the `bl` line with the Agent bash variables above. Do not paste this fence as-is. Do not `export` the `BAILIAN_*` variables; `export` below is only for the credential value. + ```bash export PROD_API_TOKEN="..." bl managed-agent vault credential create \ @@ -191,6 +201,8 @@ Managed Agents 的子线程通过 Event 中的 `session_thread_id` 暴露;公 - Deployment currently supports File Resources only. An effective Memory mount, including one inherited from the Agent, is rejected. / Deployment 本期仅支持 File,不能继承或直接挂载记忆库。 - Preview memory writes with `--dry-run`, then obtain confirmation before adding `--yes`. Version redaction permanently removes that version's content. / 版本擦除不可撤销,必须先预览并确认。 +Human documentation. Agent shell: prefix each `bl` line with the Agent bash variables above. Do not paste this fence as-is. + ```bash bl managed-agent memory-store create --name Notes --dry-run bl managed-agent memory-store memories list --workspace-id ws-example --store-id memstore-example --view full @@ -208,6 +220,8 @@ Command fields and pagination are authoritative in `reference/managed-agent.md` - `webhook events` uses `--limit` (1–100) and the opaque `--page` cursor; pass `next_page` back unchanged. / 事件分页游标保持原样传回,不转换成数字页码。 - Successful `create` and `reset-secret` responses can contain `signing_secret`. Store that response securely for signature verification; do not paste it into logs, issue reports, or source files. Verbose diagnostics and errors must not expose secrets. / 创建或重置密钥的成功响应可能包含签名密钥;请安全保存,不写入日志或代码。 +Human documentation. Agent shell: prefix each `bl` line with the Agent bash variables above. Do not paste this fence as-is. + ```bash bl managed-agent webhook list --workspace-id ws-example --output json bl managed-agent webhook create \ diff --git a/skills/bailian-memory/SKILL.md b/skills/bailian-memory/SKILL.md index 6fbb3282b..7f0a443d0 100644 --- a/skills/bailian-memory/SKILL.md +++ b/skills/bailian-memory/SKILL.md @@ -21,6 +21,14 @@ description: >- 执行任何 `bl` 命令前,先读取共享协议 [bailian-protocol](../bailian-protocol/SKILL.md),遵循鉴权、版本预检、调用归因和高风险确认。协议缺失不妨碍识别记忆意图或解释启用流程;但执行命令前须补齐,提示 `bl skill init`,不能静默退回内置记忆并声称本服务已工作。 +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from `reference/memory.md`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). Examples in `reference/` are human documentation. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-memory BAILIAN_SKILL_VERSION=2.5.0 bl memory list --user-id --workspace-id --page-size 1 --output json +``` + +Fill `` and `` from `~/.bailian/personal-memory/config.json` (`user_id`, `workspace_id`). Do not invent a temporary user id. Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. Command names in the tables below are arguments only. + ## 入口与范围 - 个人记忆:遇到上述触发意图,先读取用户级 `~/.bailian/personal-memory/config.json`;不能在读取前以“用户尚未启用”为由跳过本 Skill。同一会话状态已知可复用,启用/暂停后刷新。状态定义与旧配置迁移见 [初始化](references/setup.md#状态与旧配置)。 diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 74b408887..05096e6c6 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -15,13 +15,17 @@ description: >- 本 skill 是 `bailian-*` 家族的统一执行协议。所有业务 skill 在跑 `bl` 前都应先读本文件。 -> **Install(supported):** 整包装齐,含本 skill 与全部业务 skill: -> -> ```bash -> bl skill init -> ``` +**Agent shell:** never paste a bare `bl` into bash. Put the four `BAILIAN_*` variables on that same command ([Call attribution](#call-attribution-mandatory-for-every-agent-bl-command)). `--help` and `--version` are the only exceptions. Humans must not set these variables. + +> **Install(supported):** 整包装齐,含本 skill 与全部业务 skill。Human terminal: `bl skill init`. > -> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。Agents wrap with [Call attribution](#call-attribution-mandatory-for-every-agent-bl-command) (`bailian-protocol`). +> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。Do not paste that human line into an Agent shell. + +**Agent shell** for that install (`BAILIAN_SKILL_VERSION` is this file's `metadata.version`; sample uses `codex` — replace with this host's id): + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init +``` ## Provider selection and consent @@ -74,17 +78,23 @@ After approval, treat Bailian as selected for the current task. Do not ask again ## Call attribution (mandatory for every Agent `bl` command) -Examples in this protocol, `assets/`, and business skills show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with the prefix below (declared once here). Humans must not set these variables. Anything other than an explicit agent is recorded as `unknown`. +**Never run a bare `bl` from an Agent shell.** Codex CLI, Qwen CLI, and other bash hosts copy a fenced command as-is, so the variables must be on the same line as `bl`. Do not `export` them into the shell session. Humans must not set them. Anything other than an explicit agent is recorded as `unknown`. + +`--help` and `--version` skip telemetry and need no prefix. Every other `bl` does, including `bl skill init`, `bl skill update`, and `bl update`. + +Fenced `bl` blocks in this file, `assets/`, business skills, and generated `reference/` are **human documentation** unless the fence is labeled **Agent shell**. Copy the arguments, then add the prefix. Do not paste a human fence into bash. + +Single-line form (keep the variables on the same command): ```bash -BAILIAN_CALLER_TYPE=agent \ -BAILIAN_CALLER_NAME= \ -BAILIAN_SKILL_NAME= \ -BAILIAN_SKILL_VERSION= \ -bl +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME= BAILIAN_SKILL_NAME= BAILIAN_SKILL_VERSION= bl ``` -Pick `` from the task (do not repeat the prefix in every example): +`` is this Agent host's stable id. Examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`. Use the actual host name (lowercase; spaces/underscores become hyphens). Use `unknown` only when you cannot tell which host you are. Do not borrow another product's name. Do not scan install directories. Do not leave angle brackets or a `|` list in the command. + +If the host shell tool accepts a one-shot env map without rewriting the command string, set the same four variables there. A bare `bl` with neither the prefix nor that env map is not valid for an Agent. + +Owning skill for the task (each business skill also shows one filled-in line). Reuse the four-variable shape on every later `bl`, but change `BAILIAN_SKILL_NAME` when the command belongs to a different skill; keep `BAILIAN_CALLER_NAME` as this host: | Task | `` | | ------------------------------------------------------------------------ | -------------------------------------- | @@ -95,10 +105,8 @@ Pick `` from the task (do not repeat the prefix in every example): Conventions: -- `BAILIAN_CALLER_NAME`: stable host id (`cursor` / `claude-code` / `codex` / `qwen-code`); use `unknown` when unsure. Do not scan install directories. -- `BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md`. -- Prefix each `bl` invocation; do not `export` into the shell session. `bl --version` / `--help` skip telemetry and need no prefix. -- If the host accepts one-shot env without rewriting the command string, set the same four variables there. +- `BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md` frontmatter. The family currently shares one version; if the frontmatter differs from `2.5.0` in an example, use the frontmatter. +- If `bl` sits inside a command substitution, put the four variables inside it: `VAR=$(BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl ...)`. - PowerShell: fresh subprocess, or save/restore all four (restore to unset when they were unset). ## Version & updates (after provider selection, before the first `bl` command) @@ -114,6 +122,8 @@ Install, API key / console login, endpoint override, and config keys: **API Key login:** Token Plan and other subscription plans cannot use `--console`. For them, or when the user already has an ordinary API Key, run `bl auth login --api-key `. +Human documentation. Agent shell: prefix each `bl` line (`bailian-cli` for auth and text). Do not paste this fence as-is. + ```bash bl auth status # check current auth bl auth login --console --console-site international # example: international console @@ -123,16 +133,18 @@ bl text chat --message "Write a poem about spring" # explicit text-model smoke ## Color output When an agent needs plain text without ANSI color codes (for parsing, logs, or -snapshots), run with `NO_COLOR=1` (and Call attribution when run by an Agent): +snapshots), run with `NO_COLOR=1` on the same command as Call attribution. `config` is owned by `bailian-cli`. Sample uses `codex`; replace with this host's id. ```bash -NO_COLOR=1 bl config show --output text +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 NO_COLOR=1 bl config show --output text ``` ## Local files (mandatory) Any command that accepts a **file URL** also accepts a **local path**. The CLI uploads to DashScope temporary storage (`oss://`, 48h) automatically. +Human documentation. Agent shell: prefix each `bl` line with `bailian-gen`. Do not paste this fence as-is. + ```bash bl image edit --image ./photo.png --prompt "Add sunset" bl video edit --video ./clip.mp4 --prompt "Anime style" @@ -153,6 +165,8 @@ When the selected workflow uses `bl text chat` or `bl omni`, the CLI injects **n - If the user explicitly names a target language (e.g. "翻译成英文"), follow that instead. - Your own narration around the tool call is also in the user's language. +Human documentation. Agent shell: prefix each `bl` line with `bailian-cli`. Do not paste this fence as-is. + ```bash bl text chat --system "Reply in Chinese." --message "Explain what a vector database is." bl text chat --system "Answer in English." --message "Explain what a vector database is." diff --git a/skills/bailian-protocol/assets/setup.md b/skills/bailian-protocol/assets/setup.md index 7c7cd840a..8e6333875 100644 --- a/skills/bailian-protocol/assets/setup.md +++ b/skills/bailian-protocol/assets/setup.md @@ -7,7 +7,14 @@ Read this only when you need to install `bl`, change credentials/endpoint, or inspect config keys. Day-to-day command routing lives in the business skills (`bailian-cli` / `bailian-gen` / …). -Examples stay bare `bl …`. Agents wrap them with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command): `bailian-protocol` for install / `skill init`, `bailian-cli` for auth / config. +An Agent must not paste a bare `bl` into bash. Fences below include Call attribution with sample `BAILIAN_CALLER_NAME=codex`; replace with this host's stable id (examples: `qwen-code`, `qoder`, `claude-code`, `cursor`). Humans omit the four `BAILIAN_*` variables. `bailian-protocol` owns install / `skill init`; `bailian-cli` owns auth / config; image / video smoke commands use `bailian-gen`. Reuse the four-variable shape on every `bl`, and set `BAILIAN_SKILL_NAME` to the owning skill for that command. `BAILIAN_SKILL_VERSION` is `metadata.version` in `bailian-protocol/SKILL.md`. Do not `export` the variables. + +**Agent shell:** + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth status +``` --- @@ -20,7 +27,8 @@ Examples stay bare `bl …`. Agents wrap them with [Call attribution](../SKILL.m ```bash # node -v ≥ 18.17.0; global install via npm only (do not use pnpm/yarn) npm install -g bailian-cli -bl skill init +# Agent shell: sample uses codex — replace with this host's id +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init ``` ### 2. Fallback: binary (no Node) @@ -29,7 +37,7 @@ When there is no usable Node/npm, or Node is too old for the npm path: ```bash curl -fsSL https://bailian.aliyun.com/cli/install.sh | bash -# The script runs bl skill init after installing the CLI; if that fails, run it manually +# The script runs bl skill init after installing the CLI. If that child process is bare, rerun the prefixed bl skill init from the Agent shell block above. ``` Windows PowerShell: `irm https://bailian.aliyun.com/cli/install.ps1 | iex` @@ -42,10 +50,11 @@ Unix `install.sh` prefers the `.tar.gz` asset and does not require `unzip`. Wind - **Advanced / subset** (include protocol when needed): ```bash -# bl skill add --name bailian-protocol,bailian-gen -# bl skill add --name bailian-protocol,bailian-finetune -# bl skill add --name bailian-protocol,bailian-managed-agent -# bl skill add --name bailian-protocol,bailian-cli +# Agent shell: uncomment one line. Sample uses codex — replace with this host's id. +# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-gen +# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-finetune +# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-managed-agent +# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-cli ``` Verify: `bl --version` (prints `bl X.Y.Z`). @@ -63,10 +72,11 @@ For the exact command-to-auth mapping, read the owning skill's `reference/index. | OpenAPI AK/SK | `bl auth login --open-api --access-key-id --access-key-secret ` or Alibaba env vars | Token Plan management commands (`token-plan`) | ```bash -bl auth status # check current auth -bl auth logout # clear credentials and the model Base URL -bl auth logout --console # clear console token only -bl auth logout --open-api # clear OpenAPI AK/SK only +# Agent shell. Sample uses codex — replace with this host's id +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth status +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout --console +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout --open-api ``` - Get a DashScope API key: https://bailian.console.aliyun.com/cn-beijing/?spm=a2ty07.github&tab=app#/api-key @@ -81,16 +91,16 @@ Get or copy the Token Plan API key from the [subscription overview](https://bail Token Plan and other subscription plans cannot use `--console`; log in directly with the subscription API Key: ```bash -bl auth login --api-key sk-sp-xxx -bl text chat --message "Hello" -bl image generate --prompt "A cat" -bl video generate --prompt "A horse running through a field" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --api-key sk-sp-xxx +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Hello" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl video generate --prompt "A horse running through a field" ``` Ordinary API Keys use the same command: ```bash -bl auth login --api-key +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --api-key ``` ### API Key capability fallback @@ -112,7 +122,7 @@ appends missing preset capabilities without removing existing entries, so log in the persisted preset. ```bash -bl config set --config company-plan --key api-key-capabilities \ +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --config company-plan --key api-key-capabilities \ --value text.chat,image.generate,video.generate ``` @@ -122,8 +132,8 @@ Successful login automatically activates the explicitly selected Profile. Use `b inspect it, and switch back when needed: ```bash -bl config list -bl config use --name default +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config list +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name default ``` API Key login selects and activates the matching built-in Profile only after the credential is saved. Failed login and `--dry-run` do not switch Profiles. Use @@ -181,11 +191,11 @@ Use `bl auth login --console` for the China site. Add `--console-site internatio 5. **Still unclear** — ask the user which console they use; do not assume domestic. ```bash -# Domestic -bl auth login --console +# Domestic. Sample uses codex — replace with this host's id +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --console # International -bl auth login --console --console-site international +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --console --console-site international ``` After a successful console login, the callback may persist `console_site` in `~/.bailian/config.json`. You can also set it manually: @@ -214,12 +224,12 @@ Default: `https://dashscope.aliyuncs.com` (China). Override with any of: - **Env:** `DASHSCOPE_API_KEY`, `DASHSCOPE_BASE_URL`, `DASHSCOPE_OUTPUT`, `ALIBABA_CLOUD_ACCESS_KEY_ID`, `ALIBABA_CLOUD_ACCESS_KEY_SECRET`, `BAILIAN_WORKSPACE_ID` ```bash -bl config show -bl config list -bl config use --name -bl config use --name default -bl config set --key default-text-model --value qwen3.8-max -bl config set --key output_dir --value ~/bailian-output +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config list +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name default +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --key default-text-model --value qwen3.8-max +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --key output_dir --value ~/bailian-output ``` Valid config keys: run `bl config set --help`, or if `bailian-cli` is installed read its `reference/config.md`. diff --git a/skills/bailian-protocol/assets/versioning.md b/skills/bailian-protocol/assets/versioning.md index b598eada0..eed8e8f91 100644 --- a/skills/bailian-protocol/assets/versioning.md +++ b/skills/bailian-protocol/assets/versioning.md @@ -3,24 +3,27 @@ > Hand-maintained. Lives in `bailian-protocol/assets/` (not auto-generated from command metadata). > Entry point: [SKILL.md → Version & updates](../SKILL.md#version--updates-after-provider-selection-before-the-first-bl-command). -Agents wrap middleware `bl` commands with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command); `` here is always `bailian-protocol`. Examples stay bare. `bl --version` / `--help` need no prefix. +Pre-flight `bl` commands that enter middleware use [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command). `` here is always `bailian-protocol`. `BAILIAN_SKILL_VERSION` is `metadata.version` in `bailian-protocol/SKILL.md` (currently `2.5.0`). Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. Do not `export` the variables. `bl --version` / `--help` need no prefix. Do not paste a bare `bl skill update`, `bl skill init`, or `bl update` into bash. ## Agent pre-flight checklist (MANDATORY) **Do NOT run any `bl` command until you complete this checklist.** Run it **once per session**, before the first `bl` command. Cache the result — do not re-check before every command. 1. Read `metadata.version` from the installed `bailian-protocol/SKILL.md` frontmatter (all `bailian-*` skills share the same version). -2. Check the installed CLI version: +2. Check the installed CLI version (`--version` skips telemetry; no prefix): ```bash bl --version ``` If this fails, see [Missing `bl`](#missing-bl) below. 3. Compare the two versions (ignore the `bl` prefix; compare only `X.Y.Z`): - - If `metadata.version` ≠ `bl --version`, refresh already-installed skills before doing anything else: + - If `metadata.version` ≠ `bl --version`, refresh already-installed skills before doing anything else. Replace `codex` with this host's id. ```bash - bl skill update + BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill update + ``` + - If `bailian-protocol` or another needed skill is missing, stop and run the same four-variable shape with `bl skill init` (`BAILIAN_SKILL_NAME=bailian-protocol`). Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. + ```bash + BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init ``` - - If `bailian-protocol` or another needed skill is missing, stop and run `bl skill init` (same Call attribution, `bailian-protocol`). Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. - Do not trust a stale `reference/` when versions mismatch — flags may be wrong. 4. Check the latest published CLI version: ```bash @@ -29,9 +32,9 @@ Agents wrap middleware `bl` commands with [Call attribution](../SKILL.md#call-at 5. If the installed `bl` is **older** than the latest npm version, **STOP** the current task and **ask the user** (report skill version, installed CLI version, and npm latest): > A newer version of bl is available (current: X.Y.Z, latest: A.B.C). Upgrade before continuing? - **Do NOT auto-upgrade silently** — the user decides. - - If the user agrees: run `bl update` (same Call attribution), then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) + - If the user agrees: run `bl update` with the same four-variable shape (`BAILIAN_SKILL_NAME=bailian-protocol`), then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) Replace `codex` with this host's id. ```bash - bl update + BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl update ``` - If the user declines: continue with the current version and note it in the summary. - If `npm view` / `bl update` fails (offline, registry blocked, permission): continue with the current `bl` and tell the user it could not be updated. @@ -46,9 +49,10 @@ If `bl --version` fails, install the CLI and skills (same order as [setup.md → ```bash # Recommended — Node.js ≥ 18.17.0; npm only (do not use pnpm/yarn) npm install -g bailian-cli -bl skill init +# Agent shell: sample uses codex — replace with this host's id +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init -# Fallback — no usable Node/npm: +# Fallback — no usable Node/npm (the script runs bl skill init; if that child is bare, run the prefixed line above yourself): # curl -fsSL https://bailian.aliyun.com/cli/install.sh | bash ``` diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index 7cf6bfca0..51217645c 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -15,7 +15,15 @@ description: >- # Bailian Sandbox (`bl sandbox`) -Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. +Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. Examples in `reference/` are human documentation; prefix them before running. + +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). `bl auth` / `bl config` use `BAILIAN_SKILL_NAME=bailian-cli`; `bl sandbox` uses `bailian-sandbox`. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION=2.5.0 bl sandbox list +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. ## Scope and setup diff --git a/skills/bailian-sandbox/assets/instance-connections.md b/skills/bailian-sandbox/assets/instance-connections.md index 2497cf516..20afe7cfe 100644 --- a/skills/bailian-sandbox/assets/instance-connections.md +++ b/skills/bailian-sandbox/assets/instance-connections.md @@ -15,12 +15,12 @@ The browser paths below belong to the official browser image, not to every Sandb Reuse the requested instance. Create one only when creation is part of the user's request. Follow the shared protocol before running `bl`; use the generated command reference for lifecycle flags. -Capture the credential-bearing result in a private temporary directory: +Capture the credential-bearing result in a private temporary directory. Agent shell: prefix the `bl` line. Sample uses `codex`; replace with this host's id. Do not `export` the `BAILIAN_*` variables. ```bash umask 077 sandbox_connection_dir="$(mktemp -d)" -bl sandbox get --sandbox-id --show-credentials --output json > "$sandbox_connection_dir/connection.json" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION=2.5.0 bl sandbox get --sandbox-id --show-credentials --output json > "$sandbox_connection_dir/connection.json" ``` Check the command exit code before reading the file. `create` and `connect` can also return connection fields with `--show-credentials`, but neither command opens a terminal or browser. Without that flag, tokens are `[REDACTED]` and cannot authenticate a runtime request. diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 1622d94a1..00d1947b9 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -21,6 +21,15 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). `bl config` and `bl text chat` are owned by `bailian-cli`; `bl search web` is owned by this skill. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" +``` + +Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command. Keep `BAILIAN_CALLER_NAME` as this host. + > **Scope:** model-aware routing for web search inside Agent-driven `bl` workflows — this skill owns the routing decision only. > Command flags / usage / examples: Read skill `bailian-cli` reference if installed; else `bl search web --help` / `bl text chat --help` — do not guess flags. > @@ -32,10 +41,10 @@ Token Plan keys do not authorize Bailian MCP search — never route them to `bl ### Step 1 — Identify the active model identity -Run (no auth needed): +Run with the Agent bash shape (`BAILIAN_SKILL_NAME=bailian-cli` for this command; replace `codex` with this host's id). No auth needed: ```bash -bl config show --output json +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json ``` Treat the connection as **Token Plan** when **either** condition holds — this mirrors the CLI's own endpoint detection (`usesTokenPlanEndpoint`), so routing stays consistent with command behavior: @@ -58,7 +67,7 @@ Do not rely on the profile name alone: users can create additional Token Plan pr ### Model-native path (Token Plan preferred / fallback target) ```bash -bl text chat --api responses --tool '{"type":"web_search"}' --message "搜索近期的阿里云新闻" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --api responses --tool '{"type":"web_search"}' --message "搜索近期的阿里云新闻" ``` - The Responses API enables native web search via the tool definition `{"type":"web_search"}`. @@ -69,7 +78,7 @@ bl text chat --api responses --tool '{"type":"web_search"}' --message "搜索近 ### MCP path (default) ```bash -bl search web --query "阿里云百炼最新功能" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" ``` - Requires the WebSearch MCP to be activated for the current key; on the not-activated error the CLI appends an activation hint with the marketplace URL — relay it to the user. @@ -93,6 +102,15 @@ Fallback discipline: ## Quick examples +**Agent shell** — replace `codex` with this host's id. Do not drop the variables. Set `BAILIAN_SKILL_NAME` to the owning skill for that command. + +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" +``` + +Human documentation only. Do not paste this fence into an Agent shell. `bl config` / `bl text chat` use `BAILIAN_SKILL_NAME=bailian-cli`; `bl search web` uses `bailian-web-search`. + ```bash # Step 1: identify the active model identity bl config show --output json From 505dece8a13237c2554b0487d2f15f5973297895 Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Fri, 23 Oct 2026 14:22:24 +0800 Subject: [PATCH 4/6] docs(skills): slim call attribution to dual templates + one sample per skill Keep bash/PowerShell templates in bailian-protocol; each business skill shows one filled sample and restores bare bl elsewhere. --- docs/agents/skill-change.md | 2 +- skills/bailian-cli/SKILL.md | 17 +---- skills/bailian-finetune/SKILL.md | 15 +--- skills/bailian-gen/SKILL.md | 23 ++---- skills/bailian-managed-agent/SKILL.md | 12 +-- skills/bailian-memory/SKILL.md | 4 +- skills/bailian-protocol/SKILL.md | 74 +++++++++++-------- skills/bailian-protocol/assets/setup.md | 65 +++++++--------- skills/bailian-protocol/assets/versioning.md | 22 +++--- skills/bailian-sandbox/SKILL.md | 6 +- .../assets/instance-connections.md | 4 +- skills/bailian-web-search/SKILL.md | 22 ++---- 12 files changed, 101 insertions(+), 165 deletions(-) diff --git a/docs/agents/skill-change.md b/docs/agents/skill-change.md index 225332391..2adee7e30 100644 --- a/docs/agents/skill-change.md +++ b/docs/agents/skill-change.md @@ -40,7 +40,7 @@ bailian-gen bailian-finetune bailian-managed-agent bailian-web-search - [ ] **整包装齐**:安装 / 缺 skill 文案主推 `bl skill init`;升级同步用 `bl skill update`(只更新已安装,不装新 skill);业务 skill **不**声明 `companions` - [ ] **协议读取**:CRITICAL / references 可链 `../bailian-protocol/…`;若读不到 → 停止执行 `bl`,提示 `bl skill init` -- [ ] **调用归因**:业务 skill 与协议预检执行 `bl` 时必须带 Agent 归因前缀(见 `bailian-protocol`「Call attribution」);人类终端不要设这些变量 +- [ ] **调用归因**:协议 `SKILL.md` 放 bash + PowerShell 双模板与协议样例;每个业务 skill **只留一条**填好的样例并链回协议;其余示例 / `assets/` / `reference/` 保持裸 `bl …`。Agent 执行时再套模板;人类终端不要设这些变量 - [ ] **高风险确认**:统一由 `bailian-protocol` 定义;reference / leaf help 以 `risk: high` 明示风险,业务 skill 不得引导 Agent 自动补 `--yes`。遇到 exit code 7 / `requires_confirmation` 时停止执行并请求确认;目标或范围变化后重新确认 - [ ] **正常控制流**:`requires_confirmation` 不是 CLI bug,`assets/issue-reporting.md` 必须将 exit code 7 保持在 EXCLUDE 范围 - [ ] **软 hand-off**:兄弟业务 skill **只写 skill 名**;已安装则 Read,未安装则 `bl … --help` 或提示整包安装;**不要**把 `../bailian-gen/…` 等写成执行前提 diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 0450619cc..d8a7fae58 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -23,14 +23,12 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-cli`; replace `codex` with this host): ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Write a poem about spring" ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. - > **Family hub** — This skill owns Bailian resource commands and the hub `reference/` (apps, knowledge, usage, auth, config, …). > Shared protocol → [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md) (install the full family with `bl skill init`). > Soft hand-offs by skill name (Read if installed; else `bl … --help` / prompt `bl skill init`): `bailian-gen` (media) · `bailian-finetune` (training) · `bailian-managed-agent` (agents.yaml IaC) · `bailian-sandbox` (Sandbox lifecycle) · `bailian-web-search` (web search routing). @@ -101,21 +99,12 @@ Use this table only after the decision table in [`bailian-protocol`](../bailian- | Bailian Sandbox instance / template lifecycle | → skill `bailian-sandbox` | Fallback: `bl sandbox --help` | | Web search (model-aware routing) | → skill `bailian-web-search` | Token Plan vs MCP path + fallback; fallback: `bl search web --help` | -Flags, usage, and examples: see hub [`reference/`](reference/index.md) or `bl --help` — do not guess flags. Domain command details live in the owning skill's `reference/`. Examples in `reference/` are human documentation; an Agent runs them with the Agent bash prefix above. +Flags, usage, and examples: see hub [`reference/`](reference/index.md) or `bl --help` — do not guess flags. Domain command details live in the owning skill's `reference/`. Examples in `reference/` stay bare; wrap with Call attribution when running. --- ## Quick examples -**Agent shell** — copy this shape; replace `codex` with this host's id. Do not drop the variables. Reuse the four-variable shape on later commands; set `BAILIAN_SKILL_NAME` to the owning skill for that command. - -```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Write a poem about spring in Chinese" -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl usage stats -``` - -Human documentation only. Do not paste this fence into an Agent shell; prefix each `bl` line. - ```bash bl text chat --message "Write a poem about spring in Chinese" bl decision --workspace-id --state "Is this requesting a refund?" --questions '{"refund":{"type":"noul"}}' @@ -133,8 +122,6 @@ More examples per command: see `reference/.md` (e.g. [`reference/text.md` ### Find and call an app -Run each `bl` with the Agent bash prefix. The lines below are the arguments only. - 1. `bl app list --name --output json` 2. Pick `code` (app ID); handle `user_prompt_params` via `--biz-params '{"key":"value"}'` 3. `bl app call --app-id --prompt "..."` diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index 45ba4c07d..05b0130e9 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -16,16 +16,14 @@ description: >- # Bailian fine-tuning pipeline (`bl dataset` / `bl finetune` / `bl deploy`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-finetune`; replace `codex` with this host). After deploy, `bl text chat` is owned by `bailian-cli`. ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-finetune BAILIAN_SKILL_VERSION=2.5.0 bl dataset validate --file train.jsonl ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. Example: after deploy, `bl text chat` uses `BAILIAN_SKILL_NAME=bailian-cli`, not `bailian-finetune`. The numbered workflow below is arguments only. - ## End-to-end workflow (follow in order) ``` @@ -75,15 +73,6 @@ Flags, usage, and examples: see [`reference/`](reference/index.md) or `bl - # Bailian media generation & understanding (`bl image` / `bl video` / `bl speech` / `bl omni` / `bl vision`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human examples or `reference/` below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-gen`; replace `codex` with this host): ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat in space" --out-dir ./out/ ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. - ## Consent (short version; full rules in bailian-protocol) - The user named Bailian / DashScope / `bl`, or is continuing an existing `bl` workflow → execute directly. @@ -62,24 +60,22 @@ Flags, usage, and examples: see [`reference/`](reference/index.md) or `bl `: ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --config media --key watermark --value false +bl config set --config media --key watermark --value false ``` ## Local files (mandatory) Any command that accepts a **file URL** also accepts a **local path**; the CLI uploads to DashScope temporary storage (`oss://`, 48h) automatically. If the user gives a local file, pass the path directly — never ask them to upload or host a URL first. -Human documentation. Agent shell: prefix each `bl` line with the Agent bash block above. Do not paste this fence as-is. - ```bash bl image edit --image ./photo.png --prompt "Add sunset" bl video edit --video ./clip.mp4 --prompt "Anime style" @@ -90,15 +86,6 @@ bl speech recognize --url ./meeting.wav ## Quick examples -**Agent shell** — copy this shape; replace `codex` with this host's id. Do not drop the variables. Reuse the four-variable shape on later commands; set `BAILIAN_SKILL_NAME` to the owning skill for that command. If `bl` is inside `$(...)`, put the four variables inside the substitution. - -```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat in space" --out-dir ./out/ -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl video generate --prompt "Sunset on the beach" --download sunset.mp4 -``` - -Human documentation only. Do not paste this fence into an Agent shell. - ```bash bl image generate --prompt "A cat in space" --out-dir ./out/ bl video generate --prompt "Sunset on the beach" --download sunset.mp4 diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index e98a0210d..947f16a52 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -18,16 +18,14 @@ description: >- # Bailian managed agent IaC (`bl managed-agent`) -**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. Examples in `reference/` are human documentation; prefix them before running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** +**CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from the human fences below. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-managed-agent`; replace `codex` with this host): ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-managed-agent BAILIAN_SKILL_VERSION=2.5.0 bl managed-agent plan ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. - ## Safety guardrail (the most important rule) `apply` / `destroy` and single-resource `create --yes` **mutate persistent remote resources**: @@ -111,8 +109,6 @@ for explicit confirmation before re-running with `--yes`. `vault credential create --secret-env ` 中的参数是变量名,不是 Secret 明文。Secret 可来自 Shell export、CI Secret 注入或可选的 `.env`;CLI 会从当前目录向上自动加载最近的 `.env`,用户不必创建该文件。 -Human documentation. Agent shell: prefix the `bl` line with the Agent bash variables above. Do not paste this fence as-is. Do not `export` the `BAILIAN_*` variables; `export` below is only for the credential value. - ```bash export PROD_API_TOKEN="..." bl managed-agent vault credential create \ @@ -201,8 +197,6 @@ Managed Agents 的子线程通过 Event 中的 `session_thread_id` 暴露;公 - Deployment currently supports File Resources only. An effective Memory mount, including one inherited from the Agent, is rejected. / Deployment 本期仅支持 File,不能继承或直接挂载记忆库。 - Preview memory writes with `--dry-run`, then obtain confirmation before adding `--yes`. Version redaction permanently removes that version's content. / 版本擦除不可撤销,必须先预览并确认。 -Human documentation. Agent shell: prefix each `bl` line with the Agent bash variables above. Do not paste this fence as-is. - ```bash bl managed-agent memory-store create --name Notes --dry-run bl managed-agent memory-store memories list --workspace-id ws-example --store-id memstore-example --view full @@ -220,8 +214,6 @@ Command fields and pagination are authoritative in `reference/managed-agent.md` - `webhook events` uses `--limit` (1–100) and the opaque `--page` cursor; pass `next_page` back unchanged. / 事件分页游标保持原样传回,不转换成数字页码。 - Successful `create` and `reset-secret` responses can contain `signing_secret`. Store that response securely for signature verification; do not paste it into logs, issue reports, or source files. Verbose diagnostics and errors must not expose secrets. / 创建或重置密钥的成功响应可能包含签名密钥;请安全保存,不写入日志或代码。 -Human documentation. Agent shell: prefix each `bl` line with the Agent bash variables above. Do not paste this fence as-is. - ```bash bl managed-agent webhook list --workspace-id ws-example --output json bl managed-agent webhook create \ diff --git a/skills/bailian-memory/SKILL.md b/skills/bailian-memory/SKILL.md index 7f0a443d0..27a993c31 100644 --- a/skills/bailian-memory/SKILL.md +++ b/skills/bailian-memory/SKILL.md @@ -21,14 +21,12 @@ description: >- 执行任何 `bl` 命令前,先读取共享协议 [bailian-protocol](../bailian-protocol/SKILL.md),遵循鉴权、版本预检、调用归因和高风险确认。协议缺失不妨碍识别记忆意图或解释启用流程;但执行命令前须补齐,提示 `bl skill init`,不能静默退回内置记忆并声称本服务已工作。 -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`, including commands copied from `reference/memory.md`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). Examples in `reference/` are human documentation. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-memory`; replace `codex` with this host). Fill `` / `` from `~/.bailian/personal-memory/config.json`; do not invent ids. Command names in the tables below are arguments only. ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-memory BAILIAN_SKILL_VERSION=2.5.0 bl memory list --user-id --workspace-id --page-size 1 --output json ``` -Fill `` and `` from `~/.bailian/personal-memory/config.json` (`user_id`, `workspace_id`). Do not invent a temporary user id. Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. Command names in the tables below are arguments only. - ## 入口与范围 - 个人记忆:遇到上述触发意图,先读取用户级 `~/.bailian/personal-memory/config.json`;不能在读取前以“用户尚未启用”为由跳过本 Skill。同一会话状态已知可复用,启用/暂停后刷新。状态定义与旧配置迁移见 [初始化](references/setup.md#状态与旧配置)。 diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 05096e6c6..14b8a62d8 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -15,17 +15,13 @@ description: >- 本 skill 是 `bailian-*` 家族的统一执行协议。所有业务 skill 在跑 `bl` 前都应先读本文件。 -**Agent shell:** never paste a bare `bl` into bash. Put the four `BAILIAN_*` variables on that same command ([Call attribution](#call-attribution-mandatory-for-every-agent-bl-command)). `--help` and `--version` are the only exceptions. Humans must not set these variables. - -> **Install(supported):** 整包装齐,含本 skill 与全部业务 skill。Human terminal: `bl skill init`. +> **Install(supported):** 整包装齐,含本 skill 与全部业务 skill: > -> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。Do not paste that human line into an Agent shell. - -**Agent shell** for that install (`BAILIAN_SKILL_VERSION` is this file's `metadata.version`; sample uses `codex` — replace with this host's id): - -```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init -``` +> ```bash +> bl skill init +> ``` +> +> 子集安装请显式带上 `bailian-protocol`(例如 `bl skill add --name bailian-protocol,bailian-gen`),否则业务 skill 的相对路径 Read 会失败。Agents wrap with [Call attribution](#call-attribution-mandatory-for-every-agent-bl-command). ## Provider selection and consent @@ -78,23 +74,49 @@ After approval, treat Bailian as selected for the current task. Do not ask again ## Call attribution (mandatory for every Agent `bl` command) -**Never run a bare `bl` from an Agent shell.** Codex CLI, Qwen CLI, and other bash hosts copy a fenced command as-is, so the variables must be on the same line as `bl`. Do not `export` them into the shell session. Humans must not set them. Anything other than an explicit agent is recorded as `unknown`. +Examples in this protocol, `assets/`, business skills, and generated `reference/` show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with one of the templates below. Humans must not set these variables. Anything other than an explicit agent is recorded as `unknown`. -`--help` and `--version` skip telemetry and need no prefix. Every other `bl` does, including `bl skill init`, `bl skill update`, and `bl update`. +`--help` and `--version` skip telemetry and need no prefix. Every other `bl` does, including `bl skill init`, `bl skill update`, and `bl update`. Do not `export` the variables into the shell session. If the host accepts a one-shot env map without rewriting the command string, set the same four variables there instead. -Fenced `bl` blocks in this file, `assets/`, business skills, and generated `reference/` are **human documentation** unless the fence is labeled **Agent shell**. Copy the arguments, then add the prefix. Do not paste a human fence into bash. +Pick the template that matches the **current shell**. Windows Codex defaults to PowerShell — do not paste the bash form into PowerShell. Sample host id is `codex`; replace with this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Use `unknown` only when you cannot tell. Do not borrow another product's name. Do not scan install directories. -Single-line form (keep the variables on the same command): +### bash / zsh / Git Bash / WSL ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME= BAILIAN_SKILL_NAME= BAILIAN_SKILL_VERSION= bl ``` -`` is this Agent host's stable id. Examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`. Use the actual host name (lowercase; spaces/underscores become hyphens). Use `unknown` only when you cannot tell which host you are. Do not borrow another product's name. Do not scan install directories. Do not leave angle brackets or a `|` list in the command. +Filled sample for this protocol (`bl skill init`): -If the host shell tool accepts a one-shot env map without rewriting the command string, set the same four variables there. A bare `bl` with neither the prefix nor that env map is not valid for an Agent. +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init +``` + +Inside a command substitution: put the four variables inside `$(...)`. + +With `NO_COLOR` (config is owned by `bailian-cli`): -Owning skill for the task (each business skill also shows one filled-in line). Reuse the four-variable shape on every later `bl`, but change `BAILIAN_SKILL_NAME` when the command belongs to a different skill; keep `BAILIAN_CALLER_NAME` as this host: +```bash +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 NO_COLOR=1 bl config show --output text +``` + +### PowerShell (Windows Codex default) + +```powershell +$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME=''; $env:BAILIAN_SKILL_NAME=''; $env:BAILIAN_SKILL_VERSION=''; bl ; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue +``` + +Filled sample for this protocol: + +```powershell +$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME='codex'; $env:BAILIAN_SKILL_NAME='bailian-protocol'; $env:BAILIAN_SKILL_VERSION='2.5.0'; bl skill init; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue +``` + +Clear the four variables after each command so they do not linger in the Codex session. + +### Owning skill + +Reuse the same four-variable shape on every later `bl`, but change `BAILIAN_SKILL_NAME` when the command belongs to a different skill; keep `BAILIAN_CALLER_NAME` as this host. Each business skill shows one filled-in sample for its own commands. | Task | `` | | ------------------------------------------------------------------------ | -------------------------------------- | @@ -103,15 +125,11 @@ Owning skill for the task (each business skill also shows one filled-in line). R | image / video / speech / vision / omni | `bailian-gen` | | Other domain commands | The `bailian-*` skill currently in use | -Conventions: - -- `BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md` frontmatter. The family currently shares one version; if the frontmatter differs from `2.5.0` in an example, use the frontmatter. -- If `bl` sits inside a command substitution, put the four variables inside it: `VAR=$(BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl ...)`. -- PowerShell: fresh subprocess, or save/restore all four (restore to unset when they were unset). +`BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md` frontmatter. The family currently shares one version; if the frontmatter differs from `2.5.0` in a sample, use the frontmatter. ## Version & updates (after provider selection, before the first `bl` command) -**MANDATORY:** Before running any `bl` command, complete the **Agent pre-flight checklist** in [`assets/versioning.md`](assets/versioning.md). Do NOT run any `bl` command until the checklist is complete. If versions mismatch, ask the user whether to upgrade — do not proceed silently. Pre-flight `bl` commands that enter middleware (for example `bl skill update` / `bl update` / `bl skill init`) must use the same call-attribution prefix above; owning skill for those is `bailian-protocol`. +**MANDATORY:** Before running any `bl` command, complete the **Agent pre-flight checklist** in [`assets/versioning.md`](assets/versioning.md). Do NOT run any `bl` command until the checklist is complete. If versions mismatch, ask the user whether to upgrade — do not proceed silently. Pre-flight `bl` commands that enter middleware (for example `bl skill update` / `bl update` / `bl skill init`) must use Call attribution above; owning skill for those is `bailian-protocol`. ## Setup & auth @@ -122,8 +140,6 @@ Install, API key / console login, endpoint override, and config keys: **API Key login:** Token Plan and other subscription plans cannot use `--console`. For them, or when the user already has an ordinary API Key, run `bl auth login --api-key `. -Human documentation. Agent shell: prefix each `bl` line (`bailian-cli` for auth and text). Do not paste this fence as-is. - ```bash bl auth status # check current auth bl auth login --console --console-site international # example: international console @@ -133,18 +149,16 @@ bl text chat --message "Write a poem about spring" # explicit text-model smoke ## Color output When an agent needs plain text without ANSI color codes (for parsing, logs, or -snapshots), run with `NO_COLOR=1` on the same command as Call attribution. `config` is owned by `bailian-cli`. Sample uses `codex`; replace with this host's id. +snapshots), run with `NO_COLOR=1` and Call attribution (see the bash sample under [Call attribution](#call-attribution-mandatory-for-every-agent-bl-command)): ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 NO_COLOR=1 bl config show --output text +NO_COLOR=1 bl config show --output text ``` ## Local files (mandatory) Any command that accepts a **file URL** also accepts a **local path**. The CLI uploads to DashScope temporary storage (`oss://`, 48h) automatically. -Human documentation. Agent shell: prefix each `bl` line with `bailian-gen`. Do not paste this fence as-is. - ```bash bl image edit --image ./photo.png --prompt "Add sunset" bl video edit --video ./clip.mp4 --prompt "Anime style" @@ -165,8 +179,6 @@ When the selected workflow uses `bl text chat` or `bl omni`, the CLI injects **n - If the user explicitly names a target language (e.g. "翻译成英文"), follow that instead. - Your own narration around the tool call is also in the user's language. -Human documentation. Agent shell: prefix each `bl` line with `bailian-cli`. Do not paste this fence as-is. - ```bash bl text chat --system "Reply in Chinese." --message "Explain what a vector database is." bl text chat --system "Answer in English." --message "Explain what a vector database is." diff --git a/skills/bailian-protocol/assets/setup.md b/skills/bailian-protocol/assets/setup.md index 8e6333875..5efc09a20 100644 --- a/skills/bailian-protocol/assets/setup.md +++ b/skills/bailian-protocol/assets/setup.md @@ -7,14 +7,7 @@ Read this only when you need to install `bl`, change credentials/endpoint, or inspect config keys. Day-to-day command routing lives in the business skills (`bailian-cli` / `bailian-gen` / …). -An Agent must not paste a bare `bl` into bash. Fences below include Call attribution with sample `BAILIAN_CALLER_NAME=codex`; replace with this host's stable id (examples: `qwen-code`, `qoder`, `claude-code`, `cursor`). Humans omit the four `BAILIAN_*` variables. `bailian-protocol` owns install / `skill init`; `bailian-cli` owns auth / config; image / video smoke commands use `bailian-gen`. Reuse the four-variable shape on every `bl`, and set `BAILIAN_SKILL_NAME` to the owning skill for that command. `BAILIAN_SKILL_VERSION` is `metadata.version` in `bailian-protocol/SKILL.md`. Do not `export` the variables. - -**Agent shell:** - -```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth status -``` +Examples stay bare `bl …`. Agents wrap them with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command): `bailian-protocol` for install / `skill init` / `skill update` / `bl update`, `bailian-cli` for auth / config, `bailian-gen` for image / video smoke tests. --- @@ -27,8 +20,7 @@ BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-c ```bash # node -v ≥ 18.17.0; global install via npm only (do not use pnpm/yarn) npm install -g bailian-cli -# Agent shell: sample uses codex — replace with this host's id -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init +bl skill init ``` ### 2. Fallback: binary (no Node) @@ -37,7 +29,7 @@ When there is no usable Node/npm, or Node is too old for the npm path: ```bash curl -fsSL https://bailian.aliyun.com/cli/install.sh | bash -# The script runs bl skill init after installing the CLI. If that child process is bare, rerun the prefixed bl skill init from the Agent shell block above. +# The script runs bl skill init after installing the CLI; if that fails, run it manually ``` Windows PowerShell: `irm https://bailian.aliyun.com/cli/install.ps1 | iex` @@ -50,11 +42,10 @@ Unix `install.sh` prefers the `.tar.gz` asset and does not require `unzip`. Wind - **Advanced / subset** (include protocol when needed): ```bash -# Agent shell: uncomment one line. Sample uses codex — replace with this host's id. -# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-gen -# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-finetune -# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-managed-agent -# BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill add --name bailian-protocol,bailian-cli +# bl skill add --name bailian-protocol,bailian-gen +# bl skill add --name bailian-protocol,bailian-finetune +# bl skill add --name bailian-protocol,bailian-managed-agent +# bl skill add --name bailian-protocol,bailian-cli ``` Verify: `bl --version` (prints `bl X.Y.Z`). @@ -72,11 +63,10 @@ For the exact command-to-auth mapping, read the owning skill's `reference/index. | OpenAPI AK/SK | `bl auth login --open-api --access-key-id --access-key-secret ` or Alibaba env vars | Token Plan management commands (`token-plan`) | ```bash -# Agent shell. Sample uses codex — replace with this host's id -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth status -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout --console -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth logout --open-api +bl auth status +bl auth logout +bl auth logout --console +bl auth logout --open-api ``` - Get a DashScope API key: https://bailian.console.aliyun.com/cn-beijing/?spm=a2ty07.github&tab=app#/api-key @@ -91,16 +81,16 @@ Get or copy the Token Plan API key from the [subscription overview](https://bail Token Plan and other subscription plans cannot use `--console`; log in directly with the subscription API Key: ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --api-key sk-sp-xxx -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Hello" -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat" -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl video generate --prompt "A horse running through a field" +bl auth login --api-key sk-sp-xxx +bl text chat --message "Hello" +bl image generate --prompt "A cat" +bl video generate --prompt "A horse running through a field" ``` Ordinary API Keys use the same command: ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --api-key +bl auth login --api-key ``` ### API Key capability fallback @@ -122,7 +112,7 @@ appends missing preset capabilities without removing existing entries, so log in the persisted preset. ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --config company-plan --key api-key-capabilities \ +bl config set --config company-plan --key api-key-capabilities \ --value text.chat,image.generate,video.generate ``` @@ -132,8 +122,8 @@ Successful login automatically activates the explicitly selected Profile. Use `b inspect it, and switch back when needed: ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config list -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name default +bl config list +bl config use --name default ``` API Key login selects and activates the matching built-in Profile only after the credential is saved. Failed login and `--dry-run` do not switch Profiles. Use @@ -191,11 +181,10 @@ Use `bl auth login --console` for the China site. Add `--console-site internatio 5. **Still unclear** — ask the user which console they use; do not assume domestic. ```bash -# Domestic. Sample uses codex — replace with this host's id -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --console +bl auth login --console # International -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl auth login --console --console-site international +bl auth login --console --console-site international ``` After a successful console login, the callback may persist `console_site` in `~/.bailian/config.json`. You can also set it manually: @@ -224,12 +213,12 @@ Default: `https://dashscope.aliyuncs.com` (China). Override with any of: - **Env:** `DASHSCOPE_API_KEY`, `DASHSCOPE_BASE_URL`, `DASHSCOPE_OUTPUT`, `ALIBABA_CLOUD_ACCESS_KEY_ID`, `ALIBABA_CLOUD_ACCESS_KEY_SECRET`, `BAILIAN_WORKSPACE_ID` ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config list -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config use --name default -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --key default-text-model --value qwen3.8-max -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config set --key output_dir --value ~/bailian-output +bl config show +bl config list +bl config use --name +bl config use --name default +bl config set --key default-text-model --value qwen3.8-max +bl config set --key output_dir --value ~/bailian-output ``` Valid config keys: run `bl config set --help`, or if `bailian-cli` is installed read its `reference/config.md`. diff --git a/skills/bailian-protocol/assets/versioning.md b/skills/bailian-protocol/assets/versioning.md index eed8e8f91..b598eada0 100644 --- a/skills/bailian-protocol/assets/versioning.md +++ b/skills/bailian-protocol/assets/versioning.md @@ -3,27 +3,24 @@ > Hand-maintained. Lives in `bailian-protocol/assets/` (not auto-generated from command metadata). > Entry point: [SKILL.md → Version & updates](../SKILL.md#version--updates-after-provider-selection-before-the-first-bl-command). -Pre-flight `bl` commands that enter middleware use [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command). `` here is always `bailian-protocol`. `BAILIAN_SKILL_VERSION` is `metadata.version` in `bailian-protocol/SKILL.md` (currently `2.5.0`). Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. Do not `export` the variables. `bl --version` / `--help` need no prefix. Do not paste a bare `bl skill update`, `bl skill init`, or `bl update` into bash. +Agents wrap middleware `bl` commands with [Call attribution](../SKILL.md#call-attribution-mandatory-for-every-agent-bl-command); `` here is always `bailian-protocol`. Examples stay bare. `bl --version` / `--help` need no prefix. ## Agent pre-flight checklist (MANDATORY) **Do NOT run any `bl` command until you complete this checklist.** Run it **once per session**, before the first `bl` command. Cache the result — do not re-check before every command. 1. Read `metadata.version` from the installed `bailian-protocol/SKILL.md` frontmatter (all `bailian-*` skills share the same version). -2. Check the installed CLI version (`--version` skips telemetry; no prefix): +2. Check the installed CLI version: ```bash bl --version ``` If this fails, see [Missing `bl`](#missing-bl) below. 3. Compare the two versions (ignore the `bl` prefix; compare only `X.Y.Z`): - - If `metadata.version` ≠ `bl --version`, refresh already-installed skills before doing anything else. Replace `codex` with this host's id. + - If `metadata.version` ≠ `bl --version`, refresh already-installed skills before doing anything else: ```bash - BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill update - ``` - - If `bailian-protocol` or another needed skill is missing, stop and run the same four-variable shape with `bl skill init` (`BAILIAN_SKILL_NAME=bailian-protocol`). Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. - ```bash - BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init + bl skill update ``` + - If `bailian-protocol` or another needed skill is missing, stop and run `bl skill init` (same Call attribution, `bailian-protocol`). Do not use `bl skill init` only to refresh versions — it installs every `bailian-*` skill. - Do not trust a stale `reference/` when versions mismatch — flags may be wrong. 4. Check the latest published CLI version: ```bash @@ -32,9 +29,9 @@ Pre-flight `bl` commands that enter middleware use [Call attribution](../SKILL.m 5. If the installed `bl` is **older** than the latest npm version, **STOP** the current task and **ask the user** (report skill version, installed CLI version, and npm latest): > A newer version of bl is available (current: X.Y.Z, latest: A.B.C). Upgrade before continuing? - **Do NOT auto-upgrade silently** — the user decides. - - If the user agrees: run `bl update` with the same four-variable shape (`BAILIAN_SKILL_NAME=bailian-protocol`), then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) Replace `codex` with this host's id. + - If the user agrees: run `bl update` (same Call attribution), then continue. (`bl update` uses the detected install channel and, on success, also runs `bl skill update` to refresh already-installed skills; it does not install new skills. First-time install still uses `bl skill init`.) ```bash - BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl update + bl update ``` - If the user declines: continue with the current version and note it in the summary. - If `npm view` / `bl update` fails (offline, registry blocked, permission): continue with the current `bl` and tell the user it could not be updated. @@ -49,10 +46,9 @@ If `bl --version` fails, install the CLI and skills (same order as [setup.md → ```bash # Recommended — Node.js ≥ 18.17.0; npm only (do not use pnpm/yarn) npm install -g bailian-cli -# Agent shell: sample uses codex — replace with this host's id -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-protocol BAILIAN_SKILL_VERSION=2.5.0 bl skill init +bl skill init -# Fallback — no usable Node/npm (the script runs bl skill init; if that child is bare, run the prefixed line above yourself): +# Fallback — no usable Node/npm: # curl -fsSL https://bailian.aliyun.com/cli/install.sh | bash ``` diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index 51217645c..0d190531f 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -15,16 +15,14 @@ description: >- # Bailian Sandbox (`bl sandbox`) -Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. Examples in `reference/` are human documentation; prefix them before running. +Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. Examples in `reference/` stay bare; wrap with Call attribution when running. -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). `bl auth` / `bl config` use `BAILIAN_SKILL_NAME=bailian-cli`; `bl sandbox` uses `bailian-sandbox`. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-sandbox`; replace `codex` with this host). `bl auth` / `bl config` are owned by `bailian-cli`. ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION=2.5.0 bl sandbox list ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command (see `bailian-protocol` Call attribution). Keep `BAILIAN_CALLER_NAME` as this host. - ## Scope and setup - Manage Sandbox instances and templates through Bailian's E2B-compatible REST control plane. No E2B SDK or E2B API key is required; authentication uses the Bailian API Key as an Authorization Bearer token. diff --git a/skills/bailian-sandbox/assets/instance-connections.md b/skills/bailian-sandbox/assets/instance-connections.md index 20afe7cfe..081850c54 100644 --- a/skills/bailian-sandbox/assets/instance-connections.md +++ b/skills/bailian-sandbox/assets/instance-connections.md @@ -15,12 +15,12 @@ The browser paths below belong to the official browser image, not to every Sandb Reuse the requested instance. Create one only when creation is part of the user's request. Follow the shared protocol before running `bl`; use the generated command reference for lifecycle flags. -Capture the credential-bearing result in a private temporary directory. Agent shell: prefix the `bl` line. Sample uses `codex`; replace with this host's id. Do not `export` the `BAILIAN_*` variables. +Capture the credential-bearing result in a private temporary directory. Agents wrap the `bl` line with Call attribution (`bailian-sandbox`). ```bash umask 077 sandbox_connection_dir="$(mktemp -d)" -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION=2.5.0 bl sandbox get --sandbox-id --show-credentials --output json > "$sandbox_connection_dir/connection.json" +bl sandbox get --sandbox-id --show-credentials --output json > "$sandbox_connection_dir/connection.json" ``` Check the command exit code before reading the file. `create` and `connect` can also return connection fields with `--show-credentials`, but neither command opens a terminal or browser. Without that flag, tokens are `[REDACTED]` and cannot authenticate a runtime request. diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 00d1947b9..44bf72e25 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -21,15 +21,12 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Agent bash (mandatory):** Never run a bare `bl` in the shell. Prefix every invocation except `--help` and `--version`. Do not `export` these variables. Set `BAILIAN_CALLER_NAME` to this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Sample lines use `codex`; replace with your host. `BAILIAN_SKILL_VERSION` is this file's `metadata.version` (`2.5.0`). `bl config` and `bl text chat` are owned by `bailian-cli`; `bl search web` is owned by this skill. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-web-search`; replace `codex` with this host). `bl config` / `bl text chat` are owned by `bailian-cli`. ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" ``` -Replace `codex` in the sample with this host's id. Reuse the same four-variable shape on every later `bl`, but set `BAILIAN_SKILL_NAME` to the owning skill for that command. Keep `BAILIAN_CALLER_NAME` as this host. - > **Scope:** model-aware routing for web search inside Agent-driven `bl` workflows — this skill owns the routing decision only. > Command flags / usage / examples: Read skill `bailian-cli` reference if installed; else `bl search web --help` / `bl text chat --help` — do not guess flags. > @@ -41,10 +38,10 @@ Token Plan keys do not authorize Bailian MCP search — never route them to `bl ### Step 1 — Identify the active model identity -Run with the Agent bash shape (`BAILIAN_SKILL_NAME=bailian-cli` for this command; replace `codex` with this host's id). No auth needed: +Wrap with Call attribution (`BAILIAN_SKILL_NAME=bailian-cli`). No auth needed: ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json +bl config show --output json ``` Treat the connection as **Token Plan** when **either** condition holds — this mirrors the CLI's own endpoint detection (`usesTokenPlanEndpoint`), so routing stays consistent with command behavior: @@ -67,7 +64,7 @@ Do not rely on the profile name alone: users can create additional Token Plan pr ### Model-native path (Token Plan preferred / fallback target) ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --api responses --tool '{"type":"web_search"}' --message "搜索近期的阿里云新闻" +bl text chat --api responses --tool '{"type":"web_search"}' --message "搜索近期的阿里云新闻" ``` - The Responses API enables native web search via the tool definition `{"type":"web_search"}`. @@ -78,7 +75,7 @@ BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-c ### MCP path (default) ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" +bl search web --query "阿里云百炼最新功能" ``` - Requires the WebSearch MCP to be activated for the current key; on the not-activated error the CLI appends an activation hint with the marketplace URL — relay it to the user. @@ -102,15 +99,6 @@ Fallback discipline: ## Quick examples -**Agent shell** — replace `codex` with this host's id. Do not drop the variables. Set `BAILIAN_SKILL_NAME` to the owning skill for that command. - -```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl config show --output json -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" -``` - -Human documentation only. Do not paste this fence into an Agent shell. `bl config` / `bl text chat` use `BAILIAN_SKILL_NAME=bailian-cli`; `bl search web` uses `bailian-web-search`. - ```bash # Step 1: identify the active model identity bl config show --output json From 2e3cf2c9a31f9f08636f5afe58bd98d8fa581fc1 Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Fri, 23 Oct 2026 14:41:36 +0800 Subject: [PATCH 5/6] test(cli): ignore markdown anchors when checking sandbox skill links --- packages/cli/tests/skill-sandbox-reference.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/cli/tests/skill-sandbox-reference.test.ts b/packages/cli/tests/skill-sandbox-reference.test.ts index 41d181ae9..e61b0c06c 100644 --- a/packages/cli/tests/skill-sandbox-reference.test.ts +++ b/packages/cli/tests/skill-sandbox-reference.test.ts @@ -23,7 +23,8 @@ test("Sandbox is a valid standalone skill aligned with the CLI version", () => { expect(frontmatter.metadata.version).toBe(cliPackage.version); for (const link of skillMarkdown.matchAll(/\]\(([^)]+)\)/g)) { - expect(existsSync(join(sandboxSkillDirectory, link[1]))).toBe(true); + const target = link[1].split("#")[0]; + expect(existsSync(join(sandboxSkillDirectory, target)), target).toBe(true); } }); From 646f4eab728e1518c24a5f99a48f5f1fd8703aca Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Fri, 23 Oct 2026 15:29:10 +0800 Subject: [PATCH 6/6] fix(skills): preserve PowerShell bl exit code after env cleanup --- skills/bailian-protocol/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 14b8a62d8..4f9ae7277 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -103,16 +103,16 @@ BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-c ### PowerShell (Windows Codex default) ```powershell -$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME=''; $env:BAILIAN_SKILL_NAME=''; $env:BAILIAN_SKILL_VERSION=''; bl ; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue +$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME=''; $env:BAILIAN_SKILL_NAME=''; $env:BAILIAN_SKILL_VERSION=''; bl ; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } ``` Filled sample for this protocol: ```powershell -$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME='codex'; $env:BAILIAN_SKILL_NAME='bailian-protocol'; $env:BAILIAN_SKILL_VERSION='2.5.0'; bl skill init; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue +$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME='codex'; $env:BAILIAN_SKILL_NAME='bailian-protocol'; $env:BAILIAN_SKILL_VERSION='2.5.0'; bl skill init; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } ``` -Clear the four variables after each command so they do not linger in the Codex session. +Clear the four variables after each command so they do not linger in the Codex session. Save `$LASTEXITCODE` before `Remove-Item` and `exit` only on nonzero — a trailing successful cleanup must not mask `bl` failures (e.g. exit 7 `requires_confirmation`). ### Owning skill