feat: rename skill subcommand to prompt, add usage/setup
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 <name>` — 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
This commit is contained in:
@@ -720,7 +720,10 @@ defaultModel: default
|
|||||||
|
|
||||||
describe("no legacy apiKeyEnv references", () => {
|
describe("no legacy apiKeyEnv references", () => {
|
||||||
test("config.ts has no references to apiKeyEnv", () => {
|
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");
|
expect(configSource).not.toContain("apiKeyEnv");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+44
-19
@@ -6,16 +6,18 @@ import { describe, expect, test } from "vitest";
|
|||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
import {
|
import {
|
||||||
cmdSkillAdapter,
|
cmdPromptAdapter,
|
||||||
cmdSkillAuthor,
|
cmdPromptAuthor,
|
||||||
cmdSkillDeveloper,
|
cmdPromptDeveloper,
|
||||||
cmdSkillList,
|
cmdPromptList,
|
||||||
cmdSkillUser,
|
cmdPromptSetup,
|
||||||
} from "../commands/skill.js";
|
cmdPromptUsage,
|
||||||
|
cmdPromptUser,
|
||||||
|
} from "../commands/prompt.js";
|
||||||
|
|
||||||
describe("skill commands", () => {
|
describe("prompt commands", () => {
|
||||||
test("skill list returns all skill names", () => {
|
test("prompt list returns all prompt names", () => {
|
||||||
const result = cmdSkillList();
|
const result = cmdPromptList();
|
||||||
expect(result).toBeInstanceOf(Array);
|
expect(result).toBeInstanceOf(Array);
|
||||||
expect(result).toContain("user");
|
expect(result).toContain("user");
|
||||||
expect(result).toContain("author");
|
expect(result).toContain("author");
|
||||||
@@ -26,8 +28,8 @@ describe("skill commands", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill user returns non-empty markdown string", () => {
|
test("prompt user returns non-empty markdown string", () => {
|
||||||
const result = cmdSkillUser();
|
const result = cmdPromptUser();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("uwf");
|
expect(result).toContain("uwf");
|
||||||
expect(result).toContain("thread");
|
expect(result).toContain("thread");
|
||||||
@@ -36,8 +38,8 @@ describe("skill commands", () => {
|
|||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill author returns non-empty markdown string", () => {
|
test("prompt author returns non-empty markdown string", () => {
|
||||||
const result = cmdSkillAuthor();
|
const result = cmdPromptAuthor();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("frontmatter");
|
expect(result).toContain("frontmatter");
|
||||||
expect(result).toContain("graph");
|
expect(result).toContain("graph");
|
||||||
@@ -47,8 +49,8 @@ describe("skill commands", () => {
|
|||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill developer returns non-empty markdown string", () => {
|
test("prompt developer returns non-empty markdown string", () => {
|
||||||
const result = cmdSkillDeveloper();
|
const result = cmdPromptDeveloper();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("Monorepo");
|
expect(result).toContain("Monorepo");
|
||||||
expect(result).toContain("CAS");
|
expect(result).toContain("CAS");
|
||||||
@@ -56,8 +58,8 @@ describe("skill commands", () => {
|
|||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill adapter returns non-empty markdown string", () => {
|
test("prompt adapter returns non-empty markdown string", () => {
|
||||||
const result = cmdSkillAdapter();
|
const result = cmdPromptAdapter();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("createAgent");
|
expect(result).toContain("createAgent");
|
||||||
expect(result).toContain("AgentContext");
|
expect(result).toContain("AgentContext");
|
||||||
@@ -65,13 +67,36 @@ describe("skill commands", () => {
|
|||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill help subcommand is suppressed", () => {
|
test("prompt usage combines all references", () => {
|
||||||
const output = execFileSync("bun", ["src/cli.ts", "skill", "--help"], {
|
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, "..", ".."),
|
cwd: join(__dirname, "..", ".."),
|
||||||
encoding: "utf-8",
|
encoding: "utf-8",
|
||||||
env: { ...process.env, PATH: `/opt/homebrew/bin:${process.env.PATH}` },
|
env: { ...process.env, PATH: `/opt/homebrew/bin:${process.env.PATH}` },
|
||||||
});
|
});
|
||||||
expect(output).not.toMatch(/help\s+\[command\]/i);
|
expect(output).not.toMatch(/help\s+\[command\]/i);
|
||||||
|
expect(output).toContain("usage");
|
||||||
|
expect(output).toContain("setup");
|
||||||
expect(output).toContain("user");
|
expect(output).toContain("user");
|
||||||
expect(output).toContain("author");
|
expect(output).toContain("author");
|
||||||
expect(output).toContain("developer");
|
expect(output).toContain("developer");
|
||||||
@@ -15,15 +15,17 @@ import {
|
|||||||
} from "./commands/cas.js";
|
} from "./commands/cas.js";
|
||||||
import { cmdConfigGet, cmdConfigList, cmdConfigSet } from "./commands/config.js";
|
import { cmdConfigGet, cmdConfigList, cmdConfigSet } from "./commands/config.js";
|
||||||
import { cmdLogClean, cmdLogList, cmdLogShow } from "./commands/log.js";
|
import { cmdLogClean, cmdLogList, cmdLogShow } from "./commands/log.js";
|
||||||
import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js";
|
|
||||||
import {
|
import {
|
||||||
cmdSkillAdapter,
|
cmdPromptAdapter,
|
||||||
cmdSkillAuthor,
|
cmdPromptAuthor,
|
||||||
cmdSkillBootstrap,
|
cmdPromptBootstrap,
|
||||||
cmdSkillDeveloper,
|
cmdPromptDeveloper,
|
||||||
cmdSkillList,
|
cmdPromptList,
|
||||||
cmdSkillUser,
|
cmdPromptSetup,
|
||||||
} from "./commands/skill.js";
|
cmdPromptUsage,
|
||||||
|
cmdPromptUser,
|
||||||
|
} from "./commands/prompt.js";
|
||||||
|
import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js";
|
||||||
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
||||||
import {
|
import {
|
||||||
cmdThreadCancel,
|
cmdThreadCancel,
|
||||||
@@ -492,49 +494,63 @@ For more information, see: uwf help thread list
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
const skill = program.command("skill").description("Built-in skill references for agents");
|
const prompt = program.command("prompt").description("Built-in prompt references for agents");
|
||||||
skill.addHelpCommand(false);
|
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")
|
.command("adapter")
|
||||||
.description("Print the adapter reference (building agent adapters)")
|
.description("Print the adapter reference (building agent adapters)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillAdapter());
|
console.log(cmdPromptAdapter());
|
||||||
});
|
});
|
||||||
|
|
||||||
skill
|
prompt
|
||||||
.command("author")
|
.command("author")
|
||||||
.description("Print the author reference (workflow YAML design guide)")
|
.description("Print the author reference (workflow YAML design guide)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillAuthor());
|
console.log(cmdPromptAuthor());
|
||||||
});
|
});
|
||||||
|
|
||||||
skill
|
prompt
|
||||||
.command("developer")
|
.command("developer")
|
||||||
.description("Print the developer reference (coding conventions + architecture)")
|
.description("Print the developer reference (coding conventions + architecture)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillDeveloper());
|
console.log(cmdPromptDeveloper());
|
||||||
});
|
});
|
||||||
|
|
||||||
skill
|
prompt
|
||||||
.command("user")
|
.command("user")
|
||||||
.description("Print the user reference (CLI guide + typical workflows)")
|
.description("Print the user reference (CLI guide + typical workflows)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillUser());
|
console.log(cmdPromptUser());
|
||||||
});
|
});
|
||||||
|
|
||||||
skill
|
prompt
|
||||||
.command("bootstrap")
|
.command("bootstrap")
|
||||||
.description("Print the bootstrap skill YAML for Hermes agents")
|
.description("Print the bootstrap skill YAML for Hermes agents")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillBootstrap());
|
console.log(cmdPromptBootstrap());
|
||||||
});
|
});
|
||||||
|
|
||||||
skill
|
prompt
|
||||||
.command("list")
|
.command("list")
|
||||||
.description("List all available skill names")
|
.description("List all available prompt names")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdSkillList().join("\n"));
|
console.log(cmdPromptList().join("\n"));
|
||||||
});
|
});
|
||||||
|
|
||||||
program
|
program
|
||||||
|
|||||||
@@ -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<string> {
|
||||||
|
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: <VERSION>
|
||||||
|
author: United Workforce
|
||||||
|
license: MIT
|
||||||
|
metadata:
|
||||||
|
hermes:
|
||||||
|
tags: [workflow, agents, orchestration, cli, yaml]
|
||||||
|
---
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Replace \`<VERSION>\` 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.
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -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<string> {
|
|
||||||
return [...SKILL_NAMES];
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user