From 61ee22f64762fa753b174ee4154609be51ba7408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=9C=88?= Date: Tue, 2 Jun 2026 13:41:46 +0800 Subject: [PATCH] feat: rename skill subcommand to prompt, add usage/setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename `uwf skill` → `uwf prompt` to align with ocas CLI convention. Changes: - `uwf prompt usage` — combined output of all references (for skill installation) - `uwf prompt setup` — agent-facing setup instructions - `uwf prompt list` — list available prompt names - `uwf prompt ` — individual reference (user/author/developer/adapter/bootstrap) - Removed: commands/skill.ts, __tests__/skill.test.ts - Added: commands/prompt.ts, __tests__/prompt.test.ts Ref #598 --- .../cli-workflow/src/__tests__/config.test.ts | 5 +- .../{skill.test.ts => prompt.test.ts} | 63 +++++++---- packages/cli-workflow/src/cli.ts | 62 +++++++---- packages/cli-workflow/src/commands/prompt.ts | 101 ++++++++++++++++++ packages/cli-workflow/src/commands/skill.ts | 13 --- 5 files changed, 188 insertions(+), 56 deletions(-) rename packages/cli-workflow/src/__tests__/{skill.test.ts => prompt.test.ts} (53%) create mode 100644 packages/cli-workflow/src/commands/prompt.ts delete mode 100644 packages/cli-workflow/src/commands/skill.ts diff --git a/packages/cli-workflow/src/__tests__/config.test.ts b/packages/cli-workflow/src/__tests__/config.test.ts index c8cb0c9..6303aeb 100644 --- a/packages/cli-workflow/src/__tests__/config.test.ts +++ b/packages/cli-workflow/src/__tests__/config.test.ts @@ -720,7 +720,10 @@ defaultModel: default describe("no legacy apiKeyEnv references", () => { test("config.ts has no references to apiKeyEnv", () => { - const configSource = readFileSync(join(__dirname, "..", "..", "src", "commands", "config.ts"), "utf8"); + const configSource = readFileSync( + join(__dirname, "..", "..", "src", "commands", "config.ts"), + "utf8", + ); expect(configSource).not.toContain("apiKeyEnv"); }); diff --git a/packages/cli-workflow/src/__tests__/skill.test.ts b/packages/cli-workflow/src/__tests__/prompt.test.ts similarity index 53% rename from packages/cli-workflow/src/__tests__/skill.test.ts rename to packages/cli-workflow/src/__tests__/prompt.test.ts index 1472e60..b2b908e 100644 --- a/packages/cli-workflow/src/__tests__/skill.test.ts +++ b/packages/cli-workflow/src/__tests__/prompt.test.ts @@ -6,16 +6,18 @@ import { describe, expect, test } from "vitest"; const __dirname = dirname(fileURLToPath(import.meta.url)); import { - cmdSkillAdapter, - cmdSkillAuthor, - cmdSkillDeveloper, - cmdSkillList, - cmdSkillUser, -} from "../commands/skill.js"; + cmdPromptAdapter, + cmdPromptAuthor, + cmdPromptDeveloper, + cmdPromptList, + cmdPromptSetup, + cmdPromptUsage, + cmdPromptUser, +} from "../commands/prompt.js"; -describe("skill commands", () => { - test("skill list returns all skill names", () => { - const result = cmdSkillList(); +describe("prompt commands", () => { + test("prompt list returns all prompt names", () => { + const result = cmdPromptList(); expect(result).toBeInstanceOf(Array); expect(result).toContain("user"); expect(result).toContain("author"); @@ -26,8 +28,8 @@ describe("skill commands", () => { } }); - test("skill user returns non-empty markdown string", () => { - const result = cmdSkillUser(); + test("prompt user returns non-empty markdown string", () => { + const result = cmdPromptUser(); expect(typeof result).toBe("string"); expect(result).toContain("uwf"); expect(result).toContain("thread"); @@ -36,8 +38,8 @@ describe("skill commands", () => { expect(result.length).toBeGreaterThan(500); }); - test("skill author returns non-empty markdown string", () => { - const result = cmdSkillAuthor(); + test("prompt author returns non-empty markdown string", () => { + const result = cmdPromptAuthor(); expect(typeof result).toBe("string"); expect(result).toContain("frontmatter"); expect(result).toContain("graph"); @@ -47,8 +49,8 @@ describe("skill commands", () => { expect(result.length).toBeGreaterThan(500); }); - test("skill developer returns non-empty markdown string", () => { - const result = cmdSkillDeveloper(); + test("prompt developer returns non-empty markdown string", () => { + const result = cmdPromptDeveloper(); expect(typeof result).toBe("string"); expect(result).toContain("Monorepo"); expect(result).toContain("CAS"); @@ -56,8 +58,8 @@ describe("skill commands", () => { expect(result.length).toBeGreaterThan(500); }); - test("skill adapter returns non-empty markdown string", () => { - const result = cmdSkillAdapter(); + test("prompt adapter returns non-empty markdown string", () => { + const result = cmdPromptAdapter(); expect(typeof result).toBe("string"); expect(result).toContain("createAgent"); expect(result).toContain("AgentContext"); @@ -65,13 +67,36 @@ describe("skill commands", () => { expect(result.length).toBeGreaterThan(500); }); - test("skill help subcommand is suppressed", () => { - const output = execFileSync("bun", ["src/cli.ts", "skill", "--help"], { + test("prompt usage combines all references", () => { + const result = cmdPromptUsage(); + expect(typeof result).toBe("string"); + expect(result).toContain("User Reference"); + expect(result).toContain("Author Reference"); + expect(result).toContain("Developer Reference"); + expect(result).toContain("Adapter Reference"); + expect(result).toContain("---"); + expect(result.length).toBeGreaterThan(2000); + }); + + test("prompt setup returns setup instructions", () => { + const result = cmdPromptSetup(); + expect(typeof result).toBe("string"); + expect(result).toContain("uwf Skill Setup"); + expect(result).toContain("uwf prompt usage"); + expect(result).toContain("uwf prompt setup"); + expect(result).toContain("SKILL.md"); + expect(result).toContain("version"); + }); + + test("prompt help subcommand is suppressed", () => { + const output = execFileSync("bun", ["src/cli.ts", "prompt", "--help"], { cwd: join(__dirname, "..", ".."), encoding: "utf-8", env: { ...process.env, PATH: `/opt/homebrew/bin:${process.env.PATH}` }, }); expect(output).not.toMatch(/help\s+\[command\]/i); + expect(output).toContain("usage"); + expect(output).toContain("setup"); expect(output).toContain("user"); expect(output).toContain("author"); expect(output).toContain("developer"); diff --git a/packages/cli-workflow/src/cli.ts b/packages/cli-workflow/src/cli.ts index 81e1ff0..44954f3 100755 --- a/packages/cli-workflow/src/cli.ts +++ b/packages/cli-workflow/src/cli.ts @@ -15,15 +15,17 @@ import { } from "./commands/cas.js"; import { cmdConfigGet, cmdConfigList, cmdConfigSet } from "./commands/config.js"; import { cmdLogClean, cmdLogList, cmdLogShow } from "./commands/log.js"; -import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js"; import { - cmdSkillAdapter, - cmdSkillAuthor, - cmdSkillBootstrap, - cmdSkillDeveloper, - cmdSkillList, - cmdSkillUser, -} from "./commands/skill.js"; + cmdPromptAdapter, + cmdPromptAuthor, + cmdPromptBootstrap, + cmdPromptDeveloper, + cmdPromptList, + cmdPromptSetup, + cmdPromptUsage, + cmdPromptUser, +} from "./commands/prompt.js"; +import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js"; import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js"; import { cmdThreadCancel, @@ -492,49 +494,63 @@ For more information, see: uwf help thread list process.exit(1); }); -const skill = program.command("skill").description("Built-in skill references for agents"); -skill.addHelpCommand(false); +const prompt = program.command("prompt").description("Built-in prompt references for agents"); +prompt.addHelpCommand(false); -skill +prompt + .command("usage") + .description("Print the complete skill content (all references combined)") + .action(() => { + console.log(cmdPromptUsage()); + }); + +prompt + .command("setup") + .description("Print setup instructions for installing the uwf skill") + .action(() => { + console.log(cmdPromptSetup()); + }); + +prompt .command("adapter") .description("Print the adapter reference (building agent adapters)") .action(() => { - console.log(cmdSkillAdapter()); + console.log(cmdPromptAdapter()); }); -skill +prompt .command("author") .description("Print the author reference (workflow YAML design guide)") .action(() => { - console.log(cmdSkillAuthor()); + console.log(cmdPromptAuthor()); }); -skill +prompt .command("developer") .description("Print the developer reference (coding conventions + architecture)") .action(() => { - console.log(cmdSkillDeveloper()); + console.log(cmdPromptDeveloper()); }); -skill +prompt .command("user") .description("Print the user reference (CLI guide + typical workflows)") .action(() => { - console.log(cmdSkillUser()); + console.log(cmdPromptUser()); }); -skill +prompt .command("bootstrap") .description("Print the bootstrap skill YAML for Hermes agents") .action(() => { - console.log(cmdSkillBootstrap()); + console.log(cmdPromptBootstrap()); }); -skill +prompt .command("list") - .description("List all available skill names") + .description("List all available prompt names") .action(() => { - console.log(cmdSkillList().join("\n")); + console.log(cmdPromptList().join("\n")); }); program diff --git a/packages/cli-workflow/src/commands/prompt.ts b/packages/cli-workflow/src/commands/prompt.ts new file mode 100644 index 0000000..355120f --- /dev/null +++ b/packages/cli-workflow/src/commands/prompt.ts @@ -0,0 +1,101 @@ +import { + generateAdapterReference, + generateAuthorReference, + generateBootstrapReference, + generateDeveloperReference, + generateUserReference, +} from "@uncaged/workflow-util"; + +export { + generateAdapterReference as cmdPromptAdapter, + generateAuthorReference as cmdPromptAuthor, + generateBootstrapReference as cmdPromptBootstrap, + generateDeveloperReference as cmdPromptDeveloper, + generateUserReference as cmdPromptUser, +}; + +const PROMPT_ENTRIES: ReadonlyArray<{ name: string; generate: () => string }> = [ + { name: "user", generate: generateUserReference }, + { name: "author", generate: generateAuthorReference }, + { name: "developer", generate: generateDeveloperReference }, + { name: "adapter", generate: generateAdapterReference }, + { name: "bootstrap", generate: generateBootstrapReference }, +]; + +export function cmdPromptList(): ReadonlyArray { + return PROMPT_ENTRIES.map((e) => e.name); +} + +export function cmdPromptUsage(): string { + return PROMPT_ENTRIES.map((e) => e.generate()).join("\n\n---\n\n"); +} + +export function cmdPromptSetup(): string { + return `# uwf Skill Setup + +You are being asked to install or update the uwf (United Workforce) skill +so that you know how to use the \`uwf\` CLI for workflow orchestration. + +## Steps + +1. **Check if uwf CLI is installed:** + \`\`\`bash + uwf --help + \`\`\` + If not installed: \`bun add -g @uncaged/cli-workflow\` + +2. **Clean up old versions of the skill** (if any exist): + - Look for any existing uwf/workflow skill files in your skill directories + (e.g. \`~/.hermes/skills/uwf/SKILL.md\` or similar paths). + - If a skill exists, read its \`version\` from the YAML frontmatter. + - If the version matches the current CLI version (\`uwf --version\`), you're done — no update needed. + - If the version is older, **delete the old skill file** before proceeding. + +3. **Get the usage skill content:** + \`\`\`bash + uwf prompt usage + \`\`\` + +4. **Create a SKILL.md file** in your skill directory (e.g. \`~/.hermes/skills/uwf/SKILL.md\`). + The output of \`uwf prompt usage\` is the skill body WITHOUT frontmatter. + You must prepend the following YAML frontmatter: + + \`\`\`yaml + --- + name: uwf + description: "Use when orchestrating multi-agent workflows with uwf (United Workforce). Covers CLI usage, workflow YAML authoring, moderator logic, and agent development." + version: + author: United Workforce + license: MIT + metadata: + hermes: + tags: [workflow, agents, orchestration, cli, yaml] + --- + \`\`\` + + Replace \`\` with the installed CLI version (from \`uwf --version\`). + +5. **Verify** the skill is loadable by your agent framework. + +## Individual prompts + +You can also get individual reference sections: + +\`\`\`bash +uwf prompt list # list available prompt names +uwf prompt user # user reference (CLI guide + typical workflows) +uwf prompt author # author reference (workflow YAML design guide) +uwf prompt developer # developer reference (coding conventions + architecture) +uwf prompt adapter # adapter reference (building agent adapters) +uwf prompt bootstrap # bootstrap skill YAML for Hermes agents +\`\`\` + +## Notes + +- The skill content is bundled with the CLI and versioned with it — always use + \`uwf prompt usage\` to get the content matching your installed version. +- Do NOT hand-edit the skill body. If the CLI is updated, re-run \`uwf prompt setup\` + and follow the steps again. +- When upgrading, always delete the old skill first to avoid stale instructions. +`; +} diff --git a/packages/cli-workflow/src/commands/skill.ts b/packages/cli-workflow/src/commands/skill.ts deleted file mode 100644 index 1388ce0..0000000 --- a/packages/cli-workflow/src/commands/skill.ts +++ /dev/null @@ -1,13 +0,0 @@ -export { - generateAdapterReference as cmdSkillAdapter, - generateAuthorReference as cmdSkillAuthor, - generateBootstrapReference as cmdSkillBootstrap, - generateDeveloperReference as cmdSkillDeveloper, - generateUserReference as cmdSkillUser, -} from "@uncaged/workflow-util"; - -const SKILL_NAMES = ["user", "author", "developer", "adapter", "bootstrap"] as const; - -export function cmdSkillList(): ReadonlyArray { - return [...SKILL_NAMES]; -}