Merge pull request 'refactor(prompt): rename subcommands and add frontmatter output' (#67) from feat/prompt-refactor-66 into main
CI / check (push) Successful in 5m15s
CI / check (push) Successful in 5m15s
refactor(prompt): rename subcommands and add frontmatter output (#67)
This commit was merged in pull request #67.
This commit is contained in:
@@ -266,7 +266,7 @@ node scripts/publish-all.mjs --dry-run # preview without publishing
|
|||||||
|
|
||||||
- `workspace:^` dependencies resolve to `^x.y.z` on publish
|
- `workspace:^` dependencies resolve to `^x.y.z` on publish
|
||||||
- Publish order defined in `scripts/publish-all.mjs` (dependency order)
|
- Publish order defined in `scripts/publish-all.mjs` (dependency order)
|
||||||
- Changesets config: `.changeset/config.json` (fixed mode, public access)
|
- Changesets config: `.changeset/config.json` (independent versioning, public access)
|
||||||
|
|
||||||
### End-to-end: Author → Register → Run
|
### End-to-end: Author → Register → Run
|
||||||
|
|
||||||
|
|||||||
@@ -6,86 +6,109 @@ import { describe, expect, test } from "vitest";
|
|||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
import {
|
import {
|
||||||
cmdPromptAdapter,
|
cmdPromptAdapterDeveloping,
|
||||||
cmdPromptAuthor,
|
cmdPromptBootstrap,
|
||||||
cmdPromptDeveloper,
|
|
||||||
cmdPromptList,
|
cmdPromptList,
|
||||||
cmdPromptSetup,
|
cmdPromptSetup,
|
||||||
cmdPromptUsage,
|
cmdPromptUsage,
|
||||||
cmdPromptUser,
|
cmdPromptUsageReference,
|
||||||
|
cmdPromptWorkflowAuthoring,
|
||||||
} from "../commands/prompt.js";
|
} from "../commands/prompt.js";
|
||||||
|
|
||||||
describe("prompt commands", () => {
|
describe("prompt commands", () => {
|
||||||
test("prompt list returns all prompt names", () => {
|
test("prompt list returns new prompt names", () => {
|
||||||
const result = cmdPromptList();
|
const result = cmdPromptList();
|
||||||
expect(result).toBeInstanceOf(Array);
|
expect(result).toBeInstanceOf(Array);
|
||||||
expect(result).toContain("user");
|
expect(result).toContain("usage");
|
||||||
expect(result).toContain("author");
|
expect(result).toContain("workflow-authoring");
|
||||||
expect(result).toContain("developer");
|
expect(result).toContain("adapter-developing");
|
||||||
expect(result).toContain("adapter");
|
expect(result).toContain("bootstrap");
|
||||||
|
expect(result).not.toContain("user");
|
||||||
|
expect(result).not.toContain("author");
|
||||||
|
expect(result).not.toContain("developer");
|
||||||
|
expect(result).not.toContain("adapter");
|
||||||
for (const name of result) {
|
for (const name of result) {
|
||||||
expect(name).toMatch(/^\S+$/);
|
expect(name).toMatch(/^\S+$/);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt user returns non-empty markdown string", () => {
|
test("prompt usage-reference returns non-empty markdown string with frontmatter", () => {
|
||||||
const result = cmdPromptUser();
|
const result = cmdPromptUsageReference();
|
||||||
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");
|
||||||
expect(result).toContain("workflow");
|
expect(result).toContain("workflow");
|
||||||
expect(result).toContain("Quick Start");
|
expect(result).toContain("Quick Start");
|
||||||
|
expect(result).toContain("---");
|
||||||
|
expect(result).toContain("name:");
|
||||||
|
expect(result).toContain("version:");
|
||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt author returns non-empty markdown string", () => {
|
test("prompt workflow-authoring returns non-empty markdown string with frontmatter", () => {
|
||||||
const result = cmdPromptAuthor();
|
const result = cmdPromptWorkflowAuthoring();
|
||||||
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");
|
||||||
expect(result).toContain("$START");
|
expect(result).toContain("$START");
|
||||||
expect(result).toContain("$END");
|
expect(result).toContain("$END");
|
||||||
expect(result).toContain("$status");
|
expect(result).toContain("$status");
|
||||||
|
expect(result).toContain("---");
|
||||||
|
expect(result).toContain("name:");
|
||||||
|
expect(result).toContain("version:");
|
||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt developer returns non-empty markdown string", () => {
|
test("prompt adapter-developing returns non-empty markdown string with frontmatter", () => {
|
||||||
const result = cmdPromptDeveloper();
|
const result = cmdPromptAdapterDeveloping();
|
||||||
expect(typeof result).toBe("string");
|
|
||||||
expect(result).toContain("Monorepo");
|
|
||||||
expect(result).toContain("CAS");
|
|
||||||
expect(result).toContain("Biome");
|
|
||||||
expect(result.length).toBeGreaterThan(500);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("prompt adapter returns non-empty markdown string", () => {
|
|
||||||
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");
|
||||||
expect(result).toContain("frontmatter");
|
expect(result).toContain("frontmatter");
|
||||||
|
expect(result).toContain("---");
|
||||||
|
expect(result).toContain("name:");
|
||||||
|
expect(result).toContain("version:");
|
||||||
expect(result.length).toBeGreaterThan(500);
|
expect(result.length).toBeGreaterThan(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt usage combines all references", () => {
|
test("prompt bootstrap returns non-empty skill with frontmatter", () => {
|
||||||
|
const result = cmdPromptBootstrap();
|
||||||
|
expect(typeof result).toBe("string");
|
||||||
|
expect(result).toContain("uwf");
|
||||||
|
expect(result).toContain("---");
|
||||||
|
expect(result.length).toBeGreaterThan(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("prompt usage combines remaining references (no developer)", () => {
|
||||||
const result = cmdPromptUsage();
|
const result = cmdPromptUsage();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("User Reference");
|
expect(result).toContain("Usage Reference");
|
||||||
expect(result).toContain("Author Reference");
|
expect(result).toContain("Workflow Authoring Reference");
|
||||||
expect(result).toContain("Developer Reference");
|
expect(result).toContain("Adapter Developing Reference");
|
||||||
expect(result).toContain("Adapter Reference");
|
expect(result).not.toContain("Developer Reference");
|
||||||
expect(result).toContain("---");
|
expect(result).toContain("---");
|
||||||
expect(result.length).toBeGreaterThan(2000);
|
expect(result.length).toBeGreaterThan(2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt setup returns setup instructions", () => {
|
test("prompt setup returns simplified setup instructions", () => {
|
||||||
const result = cmdPromptSetup();
|
const result = cmdPromptSetup();
|
||||||
expect(typeof result).toBe("string");
|
expect(typeof result).toBe("string");
|
||||||
expect(result).toContain("uwf Skill Setup");
|
expect(result).toContain("uwf Skill Setup");
|
||||||
expect(result).toContain("uwf prompt usage");
|
expect(result).toContain("uwf prompt bootstrap");
|
||||||
expect(result).toContain("uwf prompt setup");
|
|
||||||
expect(result).toContain("SKILL.md");
|
expect(result).toContain("SKILL.md");
|
||||||
expect(result).toContain("version");
|
expect(result).toContain("version");
|
||||||
|
expect(result).not.toMatch(/\bbun (install|run|test|changeset|version|release)\b/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("prompt setup references new subcommand names", () => {
|
||||||
|
const result = cmdPromptSetup();
|
||||||
|
expect(result).toContain("uwf prompt usage");
|
||||||
|
expect(result).toContain("uwf prompt workflow-authoring");
|
||||||
|
expect(result).toContain("uwf prompt adapter-developing");
|
||||||
|
expect(result).not.toContain("uwf prompt user");
|
||||||
|
expect(result).not.toContain("uwf prompt author");
|
||||||
|
expect(result).not.toContain("uwf prompt developer");
|
||||||
|
expect(result).not.toMatch(/uwf prompt adapter\b(?!-developing)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prompt help subcommand is suppressed", { timeout: 30_000 }, () => {
|
test("prompt help subcommand is suppressed", { timeout: 30_000 }, () => {
|
||||||
@@ -97,10 +120,10 @@ describe("prompt commands", () => {
|
|||||||
expect(output).not.toMatch(/help\s+\[command\]/i);
|
expect(output).not.toMatch(/help\s+\[command\]/i);
|
||||||
expect(output).toContain("usage");
|
expect(output).toContain("usage");
|
||||||
expect(output).toContain("setup");
|
expect(output).toContain("setup");
|
||||||
expect(output).toContain("user");
|
expect(output).toContain("workflow-authoring");
|
||||||
expect(output).toContain("author");
|
expect(output).toContain("adapter-developing");
|
||||||
expect(output).toContain("developer");
|
expect(output).toContain("bootstrap");
|
||||||
expect(output).toContain("adapter");
|
|
||||||
expect(output).toContain("list");
|
expect(output).toContain("list");
|
||||||
|
expect(output).not.toContain("developer");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-20
@@ -5,14 +5,13 @@ import { Command } from "commander";
|
|||||||
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 {
|
import {
|
||||||
cmdPromptAdapter,
|
cmdPromptAdapterDeveloping,
|
||||||
cmdPromptAuthor,
|
|
||||||
cmdPromptBootstrap,
|
cmdPromptBootstrap,
|
||||||
cmdPromptDeveloper,
|
|
||||||
cmdPromptList,
|
cmdPromptList,
|
||||||
cmdPromptSetup,
|
cmdPromptSetup,
|
||||||
cmdPromptUsage,
|
cmdPromptUsage,
|
||||||
cmdPromptUser,
|
cmdPromptUsageReference,
|
||||||
|
cmdPromptWorkflowAuthoring,
|
||||||
} from "./commands/prompt.js";
|
} from "./commands/prompt.js";
|
||||||
import { cmdSetup, cmdSetupInteractive } from "./commands/setup.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";
|
||||||
@@ -523,31 +522,24 @@ prompt
|
|||||||
});
|
});
|
||||||
|
|
||||||
prompt
|
prompt
|
||||||
.command("adapter")
|
.command("usage-reference")
|
||||||
.description("Print the adapter reference (building agent adapters)")
|
.description("Print the usage reference (CLI guide + typical workflows)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdPromptAdapter());
|
console.log(cmdPromptUsageReference());
|
||||||
});
|
});
|
||||||
|
|
||||||
prompt
|
prompt
|
||||||
.command("author")
|
.command("workflow-authoring")
|
||||||
.description("Print the author reference (workflow YAML design guide)")
|
.description("Print the workflow authoring reference (YAML design guide)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdPromptAuthor());
|
console.log(cmdPromptWorkflowAuthoring());
|
||||||
});
|
});
|
||||||
|
|
||||||
prompt
|
prompt
|
||||||
.command("developer")
|
.command("adapter-developing")
|
||||||
.description("Print the developer reference (coding conventions + architecture)")
|
.description("Print the adapter developing reference (building agent adapters)")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
console.log(cmdPromptDeveloper());
|
console.log(cmdPromptAdapterDeveloping());
|
||||||
});
|
|
||||||
|
|
||||||
prompt
|
|
||||||
.command("user")
|
|
||||||
.description("Print the user reference (CLI guide + typical workflows)")
|
|
||||||
.action(() => {
|
|
||||||
console.log(cmdPromptUser());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
prompt
|
prompt
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
generateAdapterReference,
|
generateAdapterDevelopingReference,
|
||||||
generateAuthorReference,
|
|
||||||
generateBootstrapReference,
|
generateBootstrapReference,
|
||||||
generateDeveloperReference,
|
generateUsageReference,
|
||||||
generateUserReference,
|
generateWorkflowAuthoringReference,
|
||||||
} from "@united-workforce/util";
|
} from "@united-workforce/util";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
generateAdapterReference as cmdPromptAdapter,
|
generateAdapterDevelopingReference as cmdPromptAdapterDeveloping,
|
||||||
generateAuthorReference as cmdPromptAuthor,
|
|
||||||
generateBootstrapReference as cmdPromptBootstrap,
|
generateBootstrapReference as cmdPromptBootstrap,
|
||||||
generateDeveloperReference as cmdPromptDeveloper,
|
generateUsageReference as cmdPromptUsageReference,
|
||||||
generateUserReference as cmdPromptUser,
|
generateWorkflowAuthoringReference as cmdPromptWorkflowAuthoring,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PROMPT_ENTRIES: ReadonlyArray<{ name: string; generate: () => string }> = [
|
const PROMPT_ENTRIES: ReadonlyArray<{ name: string; generate: () => string }> = [
|
||||||
{ name: "user", generate: generateUserReference },
|
{ name: "usage", generate: generateUsageReference },
|
||||||
{ name: "author", generate: generateAuthorReference },
|
{ name: "workflow-authoring", generate: generateWorkflowAuthoringReference },
|
||||||
{ name: "developer", generate: generateDeveloperReference },
|
{ name: "adapter-developing", generate: generateAdapterDevelopingReference },
|
||||||
{ name: "adapter", generate: generateAdapterReference },
|
|
||||||
{ name: "bootstrap", generate: generateBootstrapReference },
|
{ name: "bootstrap", generate: generateBootstrapReference },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -27,7 +24,9 @@ export function cmdPromptList(): ReadonlyArray<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function cmdPromptUsage(): string {
|
export function cmdPromptUsage(): string {
|
||||||
return PROMPT_ENTRIES.map((e) => e.generate()).join("\n\n---\n\n");
|
return PROMPT_ENTRIES.filter((e) => e.name !== "bootstrap")
|
||||||
|
.map((e) => e.generate())
|
||||||
|
.join("\n\n---\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cmdPromptSetup(): string {
|
export function cmdPromptSetup(): string {
|
||||||
@@ -42,7 +41,7 @@ so that you know how to use the \`uwf\` CLI for workflow orchestration.
|
|||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
uwf --help
|
uwf --help
|
||||||
\`\`\`
|
\`\`\`
|
||||||
If not installed: \`bun add -g @united-workforce/cli\`
|
If not installed: \`npm install -g @united-workforce/cli\`
|
||||||
|
|
||||||
2. **Clean up old versions of the skill** (if any exist):
|
2. **Clean up old versions of the skill** (if any exist):
|
||||||
- Look for any existing uwf/workflow skill files in your skill directories
|
- Look for any existing uwf/workflow skill files in your skill directories
|
||||||
@@ -51,43 +50,24 @@ so that you know how to use the \`uwf\` CLI for workflow orchestration.
|
|||||||
- If the version matches the current CLI version (\`uwf --version\`), you're done — no update needed.
|
- 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.
|
- If the version is older, **delete the old skill file** before proceeding.
|
||||||
|
|
||||||
3. **Get the usage skill content:**
|
3. **Install the bootstrap skill:**
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
uwf prompt usage
|
uwf prompt bootstrap > ~/.hermes/skills/uwf/SKILL.md
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
The bootstrap prompt already includes complete YAML frontmatter — no editing needed.
|
||||||
|
|
||||||
4. **Create a SKILL.md file** in your skill directory (e.g. \`~/.hermes/skills/uwf/SKILL.md\`).
|
4. **Verify** the skill is loadable by your agent framework.
|
||||||
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
|
## Individual prompts
|
||||||
|
|
||||||
You can also get individual reference sections:
|
Each prompt outputs a complete SKILL.md with frontmatter — pipe directly to a file:
|
||||||
|
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
uwf prompt list # list available prompt names
|
uwf prompt list # list available prompt names
|
||||||
uwf prompt user # user reference (CLI guide + typical workflows)
|
uwf prompt usage > ~/.hermes/skills/uwf-usage/SKILL.md # CLI usage guide
|
||||||
uwf prompt author # author reference (workflow YAML design guide)
|
uwf prompt workflow-authoring > ~/.hermes/skills/uwf-workflow-authoring/SKILL.md
|
||||||
uwf prompt developer # developer reference (coding conventions + architecture)
|
uwf prompt adapter-developing > ~/.hermes/skills/uwf-adapter-developing/SKILL.md
|
||||||
uwf prompt adapter # adapter reference (building agent adapters)
|
uwf prompt bootstrap > ~/.hermes/skills/uwf/SKILL.md # bootstrap skill
|
||||||
uwf prompt bootstrap # bootstrap skill YAML for Hermes agents
|
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|||||||
+11
-2
@@ -1,5 +1,14 @@
|
|||||||
export function generateAdapterReference(): string {
|
import { VERSION } from "./version.js";
|
||||||
return `# Adapter Reference
|
|
||||||
|
export function generateAdapterDevelopingReference(): string {
|
||||||
|
return `---
|
||||||
|
name: uwf-adapter-developing
|
||||||
|
description: "Guide for building a new agent adapter (CLI binary) for the workflow engine."
|
||||||
|
version: ${VERSION}
|
||||||
|
tags: [uwf, adapter, agent, development]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Adapter Developing Reference
|
||||||
|
|
||||||
Guide for building a new agent adapter (CLI binary) for the workflow engine.
|
Guide for building a new agent adapter (CLI binary) for the workflow engine.
|
||||||
|
|
||||||
@@ -18,8 +18,9 @@ YAML 状态机工作流引擎。当用户提到「workflow」「工作流」时
|
|||||||
运行以下命令获取完整用法:
|
运行以下命令获取完整用法:
|
||||||
|
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
uwf skill user # 用户使用手册(CLI 命令、thread 生命周期)
|
uwf prompt usage # 完整用法文档(所有引用合并)
|
||||||
uwf skill author # workflow 编写指南(role 定义、graph 路由、schema)
|
uwf prompt workflow-authoring # workflow 编写指南(role 定义、graph 路由、schema)
|
||||||
|
uwf prompt adapter-developing # adapter 开发指南(构建新的 agent adapter)
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
## 快速参考
|
## 快速参考
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
export function generateDeveloperReference(): string {
|
|
||||||
return `# Developer Reference
|
|
||||||
|
|
||||||
Guide for contributing to the workflow engine codebase.
|
|
||||||
|
|
||||||
## Monorepo Structure
|
|
||||||
|
|
||||||
\`\`\`
|
|
||||||
packages/
|
|
||||||
protocol/ # Shared types (WorkflowPayload, StepNodePayload, etc.)
|
|
||||||
util/ # Base32, ULID, logger, frontmatter parsing, skill references
|
|
||||||
util-agent/ # createAgent factory, context builder, extract pipeline
|
|
||||||
agent-hermes/ # uwf-hermes CLI (spawns Hermes chat sessions)
|
|
||||||
agent-builtin/ # uwf-builtin CLI (direct LLM calls via OpenAI API)
|
|
||||||
cli/ # uwf CLI (moderator, thread/step/cas/config commands)
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
Dependency layers (each only imports from packages above it):
|
|
||||||
\`\`\`
|
|
||||||
protocol → util → util-agent → agent-hermes / agent-builtin / cli
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
External CAS: \`@ocas/core\` (store API, hashing, schema validation) + \`@ocas/fs\` (filesystem backend).
|
|
||||||
|
|
||||||
## Coding Conventions
|
|
||||||
|
|
||||||
### Functional-first
|
|
||||||
|
|
||||||
| Rule | Description |
|
|
||||||
|------|-------------|
|
|
||||||
| \`type\` over \`interface\` | All type definitions use \`type\` |
|
|
||||||
| \`function\` over \`class\` | Pure functions + closures, no class |
|
|
||||||
| No \`this\` | Functions must not depend on \`this\` context |
|
|
||||||
| No inheritance | No \`extends\`, \`implements\`, \`abstract\` |
|
|
||||||
| No optional properties | Use \`T \\| null\` instead of \`?:\` |
|
|
||||||
| Immutability first | Use \`Readonly<T>\`, \`as const\`, avoid mutation |
|
|
||||||
|
|
||||||
Classes allowed only when required by third-party libraries or for Error subclasses.
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
- \`Result<T, E>\` type for expected failures (\`ok\`/\`err\` constructors from \`@united-workforce/util\`)
|
|
||||||
- \`throw\` only for unrecoverable bugs
|
|
||||||
- No try-catch for flow control
|
|
||||||
|
|
||||||
### Async
|
|
||||||
|
|
||||||
Always \`async/await\`, never \`.then()\` chains.
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
|
|
||||||
\`console.*\` is banned (Biome \`noConsole\` rule). Use the structured logger:
|
|
||||||
|
|
||||||
\`\`\`typescript
|
|
||||||
import { createLogger } from "@united-workforce/util";
|
|
||||||
const log = createLogger();
|
|
||||||
log("4KNMR2PX", "Loading workflow..."); // 8-char Crockford Base32 tag
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
Each call site gets a unique hand-written tag. \`grep "4KNMR2PX"\` in logs → instant code location.
|
|
||||||
|
|
||||||
CLI package (\`@united-workforce/cli\`) may use \`console.log\` for user-facing output with a biome-ignore comment.
|
|
||||||
|
|
||||||
### No Dynamic Import
|
|
||||||
|
|
||||||
No \`await import()\` in production code. Always static top-level \`import\`. Test files are exempt.
|
|
||||||
|
|
||||||
### Naming
|
|
||||||
|
|
||||||
- Workflow names: verb-first kebab-case (\`solve-issue\`, \`review-code\`)
|
|
||||||
- IDs: Crockford Base32 — CAS hash (XXH64, 13-char), Thread ID (ULID, 26-char)
|
|
||||||
|
|
||||||
## Development Workflow
|
|
||||||
|
|
||||||
\`\`\`bash
|
|
||||||
bun install # install all workspace deps
|
|
||||||
bun run build # tsc --build (all packages)
|
|
||||||
bun run check # tsc + biome check + lint-log-tags
|
|
||||||
bun run format # biome format --write
|
|
||||||
bun test # run all tests
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
Before committing: \`bun run check\` + \`bun test\` must both pass.
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
- \`cli\`: vitest
|
|
||||||
- Other packages: \`bun test\`
|
|
||||||
- Test files live in \`__tests__/\` directories
|
|
||||||
|
|
||||||
### Publishing
|
|
||||||
|
|
||||||
Fixed-mode versioning — all \`@united-workforce/*\` packages share the same version number.
|
|
||||||
|
|
||||||
\`\`\`bash
|
|
||||||
bun changeset # describe the change
|
|
||||||
bun version # bump versions + changelogs
|
|
||||||
bun release # build + test + publish to npmjs
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
## Key Modules
|
|
||||||
|
|
||||||
### Moderator (\`cli/src/moderator/\`)
|
|
||||||
|
|
||||||
Status-based graph evaluator. Reads \`graph[lastRole][output.$status]\` to determine the next role. Zero LLM cost.
|
|
||||||
|
|
||||||
### Extract Pipeline (\`util-agent/src/\`)
|
|
||||||
|
|
||||||
1. Agent produces frontmatter markdown
|
|
||||||
2. \`parseFrontmatterMarkdown()\` extracts YAML frontmatter
|
|
||||||
3. \`tryFrontmatterFastPath()\` validates against role's output schema
|
|
||||||
4. If fast path fails, retries up to 2 times via agent continue
|
|
||||||
5. Validated output stored as CAS node
|
|
||||||
|
|
||||||
### createAgent Factory (\`util-agent/src/run.ts\`)
|
|
||||||
|
|
||||||
Shared entry point for all agent CLIs. Handles:
|
|
||||||
- Argument parsing (\`--thread\`, \`--role\`, \`--prompt\`)
|
|
||||||
- Context building (thread history, workflow definition)
|
|
||||||
- Output extraction and CAS persistence
|
|
||||||
- Frontmatter retry loop
|
|
||||||
|
|
||||||
### CAS Integration
|
|
||||||
|
|
||||||
All data is CAS-addressed via \`@ocas/core\`:
|
|
||||||
- \`store.put(schemaHash, data)\` → content hash
|
|
||||||
- \`store.get(hash)\` → node
|
|
||||||
- \`validate(store, node)\` → schema check
|
|
||||||
- Schemas registered at workflow add time
|
|
||||||
|
|
||||||
## Commit Convention
|
|
||||||
|
|
||||||
\`\`\`
|
|
||||||
<type>(<scope>): <description>
|
|
||||||
|
|
||||||
type: feat | fix | refactor | docs | chore | test
|
|
||||||
scope: workflow | cli | moderator | util-agent | hermes | util | protocol
|
|
||||||
\`\`\`
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
export { generateActorReference } from "./actor-reference.js";
|
export { generateActorReference } from "./actor-reference.js";
|
||||||
export { generateAdapterReference } from "./adapter-reference.js";
|
export { generateAdapterDevelopingReference } from "./adapter-developing-reference.js";
|
||||||
export { generateArchitectureReference } from "./architecture-reference.js";
|
export { generateArchitectureReference } from "./architecture-reference.js";
|
||||||
export { generateAuthorReference } from "./author-reference.js";
|
|
||||||
export { encodeUint64AsCrockford } from "./base32.js";
|
export { encodeUint64AsCrockford } from "./base32.js";
|
||||||
export { generateBootstrapReference } from "./bootstrap-reference.js";
|
export { generateBootstrapReference } from "./bootstrap-reference.js";
|
||||||
export { generateCliReference } from "./cli-reference.js";
|
export { generateCliReference } from "./cli-reference.js";
|
||||||
export { generateDeveloperReference } from "./developer-reference.js";
|
|
||||||
export { env } from "./env.js";
|
export { env } from "./env.js";
|
||||||
export type {
|
export type {
|
||||||
AgentFrontmatter,
|
AgentFrontmatter,
|
||||||
@@ -35,5 +33,7 @@ export {
|
|||||||
} from "./storage-root.js";
|
} from "./storage-root.js";
|
||||||
export type { LogFn, Result } from "./types.js";
|
export type { LogFn, Result } from "./types.js";
|
||||||
export { extractUlidTimestamp, generateUlid } from "./ulid.js";
|
export { extractUlidTimestamp, generateUlid } from "./ulid.js";
|
||||||
export { generateUserReference } from "./user-reference.js";
|
export { generateUsageReference } from "./usage-reference.js";
|
||||||
|
export { VERSION } from "./version.js";
|
||||||
|
export { generateWorkflowAuthoringReference } from "./workflow-authoring-reference.js";
|
||||||
export { generateYamlReference } from "./yaml-reference.js";
|
export { generateYamlReference } from "./yaml-reference.js";
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
export function generateUserReference(): string {
|
import { VERSION } from "./version.js";
|
||||||
return `# User Reference
|
|
||||||
|
export function generateUsageReference(): string {
|
||||||
|
return `---
|
||||||
|
name: uwf-usage
|
||||||
|
description: "Guide for using the uwf CLI to manage workflows and threads."
|
||||||
|
version: ${VERSION}
|
||||||
|
tags: [uwf, workflow, cli, usage]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Usage Reference
|
||||||
|
|
||||||
Guide for using the uwf CLI to manage workflows and threads.
|
Guide for using the uwf CLI to manage workflows and threads.
|
||||||
|
|
||||||
@@ -123,14 +132,13 @@ uwf --format <json|yaml> # output format (default: json)
|
|||||||
uwf -V, --version # print version
|
uwf -V, --version # print version
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
## Other Skill References
|
## Other Prompt References
|
||||||
|
|
||||||
For specific scenarios, run the corresponding \`uwf skill\` command:
|
For specific scenarios, run the corresponding \`uwf prompt\` command:
|
||||||
|
|
||||||
| Scenario | Command | When to use |
|
| Scenario | Command | When to use |
|
||||||
|----------|---------|-------------|
|
|----------|---------|-------------|
|
||||||
| Writing workflow YAML | \`uwf skill author\` | Designing roles, conditions, graphs, and edge prompts |
|
| Writing workflow YAML | \`uwf prompt workflow-authoring\` | Designing roles, conditions, graphs, and edge prompts |
|
||||||
| Contributing to the engine | \`uwf skill developer\` | Modifying the workflow engine codebase itself |
|
| Building a new agent adapter | \`uwf prompt adapter-developing\` | Creating a new \`uwf-<name>\` CLI adapter |
|
||||||
| Building a new agent adapter | \`uwf skill adapter\` | Creating a new \`uwf-<name>\` CLI adapter |
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// This version is kept in sync with package.json during releases.
|
||||||
|
export const VERSION = "0.1.0";
|
||||||
+11
-2
@@ -1,5 +1,14 @@
|
|||||||
export function generateAuthorReference(): string {
|
import { VERSION } from "./version.js";
|
||||||
return `# Author Reference
|
|
||||||
|
export function generateWorkflowAuthoringReference(): string {
|
||||||
|
return `---
|
||||||
|
name: uwf-workflow-authoring
|
||||||
|
description: "Guide for designing and writing workflow YAML definitions."
|
||||||
|
version: ${VERSION}
|
||||||
|
tags: [uwf, workflow, yaml, authoring]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Workflow Authoring Reference
|
||||||
|
|
||||||
Guide for designing and writing workflow YAML definitions.
|
Guide for designing and writing workflow YAML definitions.
|
||||||
|
|
||||||
Reference in New Issue
Block a user