From 2ef004eecf4a8eae7fdd25a9a201ec0012c71b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=9C=88?= Date: Fri, 8 May 2026 00:36:54 +0800 Subject: [PATCH] refactor(cli): restructure cmd-*.ts into commands/ subdirectories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorganize flat cmd-*.ts files into commands/{workflow,thread,cas,init}/ subdirectories that strictly mirror the CLI subcommand hierarchy: - workflow/: add, list, show, rm, history, rollback - thread/: run, list, show, rm, fork, ps, kill, live, pause, resume - cas/: get, put, list, rm, gc - init/: workspace, template Each group has an index.ts re-export. Split multi-command files (cmd-cas.ts, cmd-thread.ts, cmd-init.ts) into per-subcommand files. Rename cmd-help.ts → skill.ts to match the primary command name. Update all import paths in cli-dispatch.ts and test files. Pure structural change — no logic modifications. Ref: #93, closes #94 --- .../cli-workflow/__tests__/bundle-fixture.ts | 2 +- .../cli-workflow/__tests__/commands.test.ts | 17 +- .../cli-workflow/__tests__/fork-cli.test.ts | 6 +- .../cli-workflow/__tests__/gc-cli.test.ts | 2 +- packages/cli-workflow/__tests__/help.test.ts | 2 +- .../__tests__/init-template.test.ts | 3 +- .../__tests__/init-workspace.test.ts | 2 +- packages/cli-workflow/__tests__/live.test.ts | 2 +- .../cli-workflow/__tests__/thread-cli.test.ts | 19 +- packages/cli-workflow/src/cli-dispatch.ts | 48 ++--- packages/cli-workflow/src/cmd-cas.ts | 43 ---- .../src/{cmd-gc.ts => commands/cas/gc.ts} | 0 packages/cli-workflow/src/commands/cas/get.ts | 14 ++ .../cli-workflow/src/commands/cas/index.ts | 5 + .../cli-workflow/src/commands/cas/list.ts | 10 + packages/cli-workflow/src/commands/cas/put.ts | 11 + packages/cli-workflow/src/commands/cas/rm.ts | 11 + .../cli-workflow/src/commands/init/index.ts | 4 + .../src/commands/init/template.ts | 203 ++++++++++++++++++ .../init/workspace.ts} | 190 +--------------- .../{cmd-fork.ts => commands/thread/fork.ts} | 6 +- .../cli-workflow/src/commands/thread/index.ts | 17 ++ .../{cmd-kill.ts => commands/thread/kill.ts} | 4 +- .../thread/list.ts} | 4 +- .../{cmd-live.ts => commands/thread/live.ts} | 8 +- .../thread/pause.ts} | 4 +- .../src/{cmd-ps.ts => commands/thread/ps.ts} | 2 +- .../thread/resume.ts} | 4 +- .../{cmd-thread.ts => commands/thread/rm.ts} | 18 +- .../{cmd-run.ts => commands/thread/run.ts} | 4 +- .../cli-workflow/src/commands/thread/show.ts | 19 ++ .../{cmd-add.ts => commands/workflow/add.ts} | 4 +- .../workflow/history.ts} | 2 +- .../src/commands/workflow/index.ts | 7 + .../workflow/list.ts} | 0 .../workflow/rm.ts} | 2 +- .../workflow/rollback.ts} | 4 +- .../workflow/show.ts} | 2 +- .../src/{cmd-help.ts => skill.ts} | 0 39 files changed, 384 insertions(+), 321 deletions(-) delete mode 100644 packages/cli-workflow/src/cmd-cas.ts rename packages/cli-workflow/src/{cmd-gc.ts => commands/cas/gc.ts} (100%) create mode 100644 packages/cli-workflow/src/commands/cas/get.ts create mode 100644 packages/cli-workflow/src/commands/cas/index.ts create mode 100644 packages/cli-workflow/src/commands/cas/list.ts create mode 100644 packages/cli-workflow/src/commands/cas/put.ts create mode 100644 packages/cli-workflow/src/commands/cas/rm.ts create mode 100644 packages/cli-workflow/src/commands/init/index.ts create mode 100644 packages/cli-workflow/src/commands/init/template.ts rename packages/cli-workflow/src/{cmd-init.ts => commands/init/workspace.ts} (63%) rename packages/cli-workflow/src/{cmd-fork.ts => commands/thread/fork.ts} (91%) create mode 100644 packages/cli-workflow/src/commands/thread/index.ts rename packages/cli-workflow/src/{cmd-kill.ts => commands/thread/kill.ts} (92%) rename packages/cli-workflow/src/{cmd-threads.ts => commands/thread/list.ts} (86%) rename packages/cli-workflow/src/{cmd-live.ts => commands/thread/live.ts} (98%) rename packages/cli-workflow/src/{cmd-pause.ts => commands/thread/pause.ts} (92%) rename packages/cli-workflow/src/{cmd-ps.ts => commands/thread/ps.ts} (82%) rename packages/cli-workflow/src/{cmd-resume.ts => commands/thread/resume.ts} (92%) rename packages/cli-workflow/src/{cmd-thread.ts => commands/thread/rm.ts} (56%) rename packages/cli-workflow/src/{cmd-run.ts => commands/thread/run.ts} (89%) create mode 100644 packages/cli-workflow/src/commands/thread/show.ts rename packages/cli-workflow/src/{cmd-add.ts => commands/workflow/add.ts} (97%) rename packages/cli-workflow/src/{cmd-history.ts => commands/workflow/history.ts} (94%) create mode 100644 packages/cli-workflow/src/commands/workflow/index.ts rename packages/cli-workflow/src/{cmd-list.ts => commands/workflow/list.ts} (100%) rename packages/cli-workflow/src/{cmd-remove.ts => commands/workflow/rm.ts} (91%) rename packages/cli-workflow/src/{cmd-rollback.ts => commands/workflow/rollback.ts} (91%) rename packages/cli-workflow/src/{cmd-show.ts => commands/workflow/show.ts} (93%) rename packages/cli-workflow/src/{cmd-help.ts => skill.ts} (100%) diff --git a/packages/cli-workflow/__tests__/bundle-fixture.ts b/packages/cli-workflow/__tests__/bundle-fixture.ts index edc207e..7e74d07 100644 --- a/packages/cli-workflow/__tests__/bundle-fixture.ts +++ b/packages/cli-workflow/__tests__/bundle-fixture.ts @@ -1,4 +1,4 @@ -import type { ParsedAddArgv } from "../src/cmd-add.js"; +import type { ParsedAddArgv } from "../src/commands/workflow/add.js"; export function addCliArgs(name: string, filePath: string): ParsedAddArgv { return { name, filePath, typesPath: null }; diff --git a/packages/cli-workflow/__tests__/commands.test.ts b/packages/cli-workflow/__tests__/commands.test.ts index cc4d8e2..0b5135c 100644 --- a/packages/cli-workflow/__tests__/commands.test.ts +++ b/packages/cli-workflow/__tests__/commands.test.ts @@ -4,13 +4,16 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { getGlobalCasDir, getRegisteredWorkflow, readWorkflowRegistry } from "@uncaged/workflow"; -import { cmdAdd } from "../src/cmd-add.js"; -import { cmdCasGet, cmdCasList, cmdCasPut, cmdCasRm } from "../src/cmd-cas.js"; -import { cmdHistory } from "../src/cmd-history.js"; -import { cmdList, formatListLines } from "../src/cmd-list.js"; -import { cmdRemove } from "../src/cmd-remove.js"; -import { cmdRollback } from "../src/cmd-rollback.js"; -import { cmdShow } from "../src/cmd-show.js"; +import { cmdCasGet } from "../src/commands/cas/get.js"; +import { cmdCasList } from "../src/commands/cas/list.js"; +import { cmdCasPut } from "../src/commands/cas/put.js"; +import { cmdCasRm } from "../src/commands/cas/rm.js"; +import { cmdAdd } from "../src/commands/workflow/add.js"; +import { cmdHistory } from "../src/commands/workflow/history.js"; +import { cmdList, formatListLines } from "../src/commands/workflow/list.js"; +import { cmdRemove } from "../src/commands/workflow/rm.js"; +import { cmdRollback } from "../src/commands/workflow/rollback.js"; +import { cmdShow } from "../src/commands/workflow/show.js"; import { addCliArgs } from "./bundle-fixture.js"; const fixtureDescriptor = `export const descriptor = { description: "fixture", roles: {} }; diff --git a/packages/cli-workflow/__tests__/fork-cli.test.ts b/packages/cli-workflow/__tests__/fork-cli.test.ts index a0fe69d..95c50bf 100644 --- a/packages/cli-workflow/__tests__/fork-cli.test.ts +++ b/packages/cli-workflow/__tests__/fork-cli.test.ts @@ -3,9 +3,9 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { createCasStore, getContentMerklePayload, getGlobalCasDir } from "@uncaged/workflow"; -import { cmdAdd } from "../src/cmd-add.js"; -import { cmdFork } from "../src/cmd-fork.js"; -import { cmdRun } from "../src/cmd-run.js"; +import { cmdFork } from "../src/commands/thread/fork.js"; +import { cmdRun } from "../src/commands/thread/run.js"; +import { cmdAdd } from "../src/commands/workflow/add.js"; import { pathExists } from "../src/fs-utils.js"; import { addCliArgs } from "./bundle-fixture.js"; diff --git a/packages/cli-workflow/__tests__/gc-cli.test.ts b/packages/cli-workflow/__tests__/gc-cli.test.ts index 78c9765..f98da4b 100644 --- a/packages/cli-workflow/__tests__/gc-cli.test.ts +++ b/packages/cli-workflow/__tests__/gc-cli.test.ts @@ -10,7 +10,7 @@ import { getGlobalCasDir, putContentMerkleNode, } from "@uncaged/workflow"; -import { cmdThreadRemove } from "../src/cmd-thread.js"; +import { cmdThreadRemove } from "../src/commands/thread/rm.js"; import { pathExists } from "../src/fs-utils.js"; const cliEntryPath = fileURLToPath(new URL("../src/cli.ts", import.meta.url)); diff --git a/packages/cli-workflow/__tests__/help.test.ts b/packages/cli-workflow/__tests__/help.test.ts index bcb7548..a6e9aba 100644 --- a/packages/cli-workflow/__tests__/help.test.ts +++ b/packages/cli-workflow/__tests__/help.test.ts @@ -5,7 +5,7 @@ import { formatSkillIndex, formatSkillTopic, getSkillTopics, -} from "../src/cmd-help.js"; +} from "../src/skill.js"; const STORAGE_ROOT = "/tmp/help-test-storage"; diff --git a/packages/cli-workflow/__tests__/init-template.test.ts b/packages/cli-workflow/__tests__/init-template.test.ts index 4db9614..4927980 100644 --- a/packages/cli-workflow/__tests__/init-template.test.ts +++ b/packages/cli-workflow/__tests__/init-template.test.ts @@ -4,7 +4,8 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { runCli } from "../src/cli-dispatch.js"; -import { cmdInitTemplate, cmdInitWorkspace } from "../src/cmd-init.js"; +import { cmdInitTemplate } from "../src/commands/init/template.js"; +import { cmdInitWorkspace } from "../src/commands/init/workspace.js"; import { pathExists } from "../src/fs-utils.js"; describe("init template", () => { diff --git a/packages/cli-workflow/__tests__/init-workspace.test.ts b/packages/cli-workflow/__tests__/init-workspace.test.ts index 4da8a39..17c91a0 100644 --- a/packages/cli-workflow/__tests__/init-workspace.test.ts +++ b/packages/cli-workflow/__tests__/init-workspace.test.ts @@ -4,7 +4,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { formatCliUsage, runCli } from "../src/cli-dispatch.js"; -import { cmdInitWorkspace } from "../src/cmd-init.js"; +import { cmdInitWorkspace } from "../src/commands/init/workspace.js"; import { pathExists } from "../src/fs-utils.js"; describe("init workspace", () => { diff --git a/packages/cli-workflow/__tests__/live.test.ts b/packages/cli-workflow/__tests__/live.test.ts index 7d44cda..a237b15 100644 --- a/packages/cli-workflow/__tests__/live.test.ts +++ b/packages/cli-workflow/__tests__/live.test.ts @@ -13,7 +13,7 @@ import { LIVE_CONTENT_MAX_LINES, type LiveRoleRow, renderLiveRoleStepLines, -} from "../src/cmd-live.js"; +} from "../src/commands/thread/live.js"; import { parseLiveArgv } from "../src/live-argv.js"; const cliEntryPath = fileURLToPath(new URL("../src/cli.ts", import.meta.url)); diff --git a/packages/cli-workflow/__tests__/thread-cli.test.ts b/packages/cli-workflow/__tests__/thread-cli.test.ts index a8a770b..7163150 100644 --- a/packages/cli-workflow/__tests__/thread-cli.test.ts +++ b/packages/cli-workflow/__tests__/thread-cli.test.ts @@ -5,15 +5,16 @@ import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { getGlobalCasDir } from "@uncaged/workflow"; -import { cmdAdd } from "../src/cmd-add.js"; -import { cmdCasPut } from "../src/cmd-cas.js"; -import { cmdKill } from "../src/cmd-kill.js"; -import { cmdPause } from "../src/cmd-pause.js"; -import { cmdPs } from "../src/cmd-ps.js"; -import { cmdResume } from "../src/cmd-resume.js"; -import { cmdRun } from "../src/cmd-run.js"; -import { cmdThreadRemove, cmdThreadShow } from "../src/cmd-thread.js"; -import { cmdThreads } from "../src/cmd-threads.js"; +import { cmdCasPut } from "../src/commands/cas/put.js"; +import { cmdKill } from "../src/commands/thread/kill.js"; +import { cmdThreads } from "../src/commands/thread/list.js"; +import { cmdPause } from "../src/commands/thread/pause.js"; +import { cmdPs } from "../src/commands/thread/ps.js"; +import { cmdResume } from "../src/commands/thread/resume.js"; +import { cmdThreadRemove } from "../src/commands/thread/rm.js"; +import { cmdRun } from "../src/commands/thread/run.js"; +import { cmdThreadShow } from "../src/commands/thread/show.js"; +import { cmdAdd } from "../src/commands/workflow/add.js"; import { pathExists, readTextFileIfExists } from "../src/fs-utils.js"; import { addCliArgs } from "./bundle-fixture.js"; diff --git a/packages/cli-workflow/src/cli-dispatch.ts b/packages/cli-workflow/src/cli-dispatch.ts index f6dd222..2d98217 100644 --- a/packages/cli-workflow/src/cli-dispatch.ts +++ b/packages/cli-workflow/src/cli-dispatch.ts @@ -1,30 +1,30 @@ import { printCliError, printCliLine, printCliWarn } from "./cli-output.js"; -import { cmdAdd, formatAddSuccess, parseAddArgv } from "./cmd-add.js"; -import { cmdCasGet, cmdCasList, cmdCasPut, cmdCasRm } from "./cmd-cas.js"; -import { cmdFork, parseForkArgv } from "./cmd-fork.js"; -import { cmdGc } from "./cmd-gc.js"; -import { - formatSkillDoc, - formatSkillIndex, - formatSkillTopic, - getSkillTopics, -} from "./cmd-help.js"; -import { cmdHistory } from "./cmd-history.js"; -import { cmdInitTemplate, cmdInitWorkspace } from "./cmd-init.js"; -import { cmdKill } from "./cmd-kill.js"; -import { cmdList, formatListLines } from "./cmd-list.js"; -import { cmdLive } from "./cmd-live.js"; -import { cmdPause } from "./cmd-pause.js"; -import { cmdPs } from "./cmd-ps.js"; -import { cmdRemove } from "./cmd-remove.js"; -import { cmdResume } from "./cmd-resume.js"; -import { cmdRollback } from "./cmd-rollback.js"; -import { cmdRun } from "./cmd-run.js"; -import { cmdShow, formatShowYaml } from "./cmd-show.js"; -import { cmdThreadRemove, cmdThreadShow } from "./cmd-thread.js"; -import { cmdThreads } from "./cmd-threads.js"; +import { cmdGc } from "./commands/cas/gc.js"; +import { cmdCasGet } from "./commands/cas/get.js"; +import { cmdCasList } from "./commands/cas/list.js"; +import { cmdCasPut } from "./commands/cas/put.js"; +import { cmdCasRm } from "./commands/cas/rm.js"; +import { cmdInitTemplate } from "./commands/init/template.js"; +import { cmdInitWorkspace } from "./commands/init/workspace.js"; +import { cmdFork, parseForkArgv } from "./commands/thread/fork.js"; +import { cmdKill } from "./commands/thread/kill.js"; +import { cmdThreads } from "./commands/thread/list.js"; +import { cmdLive } from "./commands/thread/live.js"; +import { cmdPause } from "./commands/thread/pause.js"; +import { cmdPs } from "./commands/thread/ps.js"; +import { cmdResume } from "./commands/thread/resume.js"; +import { cmdThreadRemove } from "./commands/thread/rm.js"; +import { cmdRun } from "./commands/thread/run.js"; +import { cmdThreadShow } from "./commands/thread/show.js"; +import { cmdAdd, formatAddSuccess, parseAddArgv } from "./commands/workflow/add.js"; +import { cmdHistory } from "./commands/workflow/history.js"; +import { cmdList, formatListLines } from "./commands/workflow/list.js"; +import { cmdRemove } from "./commands/workflow/rm.js"; +import { cmdRollback } from "./commands/workflow/rollback.js"; +import { cmdShow, formatShowYaml } from "./commands/workflow/show.js"; import { parseLiveArgv } from "./live-argv.js"; import { parseRunArgv } from "./run-argv.js"; +import { formatSkillIndex, formatSkillTopic, getSkillTopics } from "./skill.js"; type DispatchFn = (storageRoot: string, argv: string[]) => Promise; diff --git a/packages/cli-workflow/src/cmd-cas.ts b/packages/cli-workflow/src/cmd-cas.ts deleted file mode 100644 index 8774d4b..0000000 --- a/packages/cli-workflow/src/cmd-cas.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createCasStore, err, getGlobalCasDir, ok, type Result } from "@uncaged/workflow"; - -export async function cmdCasGet( - storageRoot: string, - _threadId: string, - hash: string, -): Promise> { - const cas = createCasStore(getGlobalCasDir(storageRoot)); - const content = await cas.get(hash); - if (content === null) { - return err(`cas entry not found: ${hash}`); - } - return ok(content); -} - -export async function cmdCasPut( - storageRoot: string, - _threadId: string, - content: string, -): Promise> { - const cas = createCasStore(getGlobalCasDir(storageRoot)); - const hash = await cas.put(content); - return ok(hash); -} - -export async function cmdCasList( - storageRoot: string, - _threadId: string, -): Promise> { - const cas = createCasStore(getGlobalCasDir(storageRoot)); - const hashes = await cas.list(); - return ok(hashes); -} - -export async function cmdCasRm( - storageRoot: string, - _threadId: string, - hash: string, -): Promise> { - const cas = createCasStore(getGlobalCasDir(storageRoot)); - await cas.delete(hash); - return ok(undefined); -} diff --git a/packages/cli-workflow/src/cmd-gc.ts b/packages/cli-workflow/src/commands/cas/gc.ts similarity index 100% rename from packages/cli-workflow/src/cmd-gc.ts rename to packages/cli-workflow/src/commands/cas/gc.ts diff --git a/packages/cli-workflow/src/commands/cas/get.ts b/packages/cli-workflow/src/commands/cas/get.ts new file mode 100644 index 0000000..3b45e67 --- /dev/null +++ b/packages/cli-workflow/src/commands/cas/get.ts @@ -0,0 +1,14 @@ +import { createCasStore, err, getGlobalCasDir, ok, type Result } from "@uncaged/workflow"; + +export async function cmdCasGet( + storageRoot: string, + _threadId: string, + hash: string, +): Promise> { + const cas = createCasStore(getGlobalCasDir(storageRoot)); + const content = await cas.get(hash); + if (content === null) { + return err(`cas entry not found: ${hash}`); + } + return ok(content); +} diff --git a/packages/cli-workflow/src/commands/cas/index.ts b/packages/cli-workflow/src/commands/cas/index.ts new file mode 100644 index 0000000..5340a0e --- /dev/null +++ b/packages/cli-workflow/src/commands/cas/index.ts @@ -0,0 +1,5 @@ +export { cmdGc } from "./gc.js"; +export { cmdCasGet } from "./get.js"; +export { cmdCasList } from "./list.js"; +export { cmdCasPut } from "./put.js"; +export { cmdCasRm } from "./rm.js"; diff --git a/packages/cli-workflow/src/commands/cas/list.ts b/packages/cli-workflow/src/commands/cas/list.ts new file mode 100644 index 0000000..ae0694b --- /dev/null +++ b/packages/cli-workflow/src/commands/cas/list.ts @@ -0,0 +1,10 @@ +import { createCasStore, getGlobalCasDir, ok, type Result } from "@uncaged/workflow"; + +export async function cmdCasList( + storageRoot: string, + _threadId: string, +): Promise> { + const cas = createCasStore(getGlobalCasDir(storageRoot)); + const hashes = await cas.list(); + return ok(hashes); +} diff --git a/packages/cli-workflow/src/commands/cas/put.ts b/packages/cli-workflow/src/commands/cas/put.ts new file mode 100644 index 0000000..2fa0e25 --- /dev/null +++ b/packages/cli-workflow/src/commands/cas/put.ts @@ -0,0 +1,11 @@ +import { createCasStore, getGlobalCasDir, ok, type Result } from "@uncaged/workflow"; + +export async function cmdCasPut( + storageRoot: string, + _threadId: string, + content: string, +): Promise> { + const cas = createCasStore(getGlobalCasDir(storageRoot)); + const hash = await cas.put(content); + return ok(hash); +} diff --git a/packages/cli-workflow/src/commands/cas/rm.ts b/packages/cli-workflow/src/commands/cas/rm.ts new file mode 100644 index 0000000..5d85a3b --- /dev/null +++ b/packages/cli-workflow/src/commands/cas/rm.ts @@ -0,0 +1,11 @@ +import { createCasStore, getGlobalCasDir, ok, type Result } from "@uncaged/workflow"; + +export async function cmdCasRm( + storageRoot: string, + _threadId: string, + hash: string, +): Promise> { + const cas = createCasStore(getGlobalCasDir(storageRoot)); + await cas.delete(hash); + return ok(undefined); +} diff --git a/packages/cli-workflow/src/commands/init/index.ts b/packages/cli-workflow/src/commands/init/index.ts new file mode 100644 index 0000000..c5c75af --- /dev/null +++ b/packages/cli-workflow/src/commands/init/index.ts @@ -0,0 +1,4 @@ +export type { CmdInitTemplateSuccess } from "./template.js"; +export { cmdInitTemplate } from "./template.js"; +export type { CmdInitWorkspaceSuccess } from "./workspace.js"; +export { cmdInitWorkspace } from "./workspace.js"; diff --git a/packages/cli-workflow/src/commands/init/template.ts b/packages/cli-workflow/src/commands/init/template.ts new file mode 100644 index 0000000..01b7a44 --- /dev/null +++ b/packages/cli-workflow/src/commands/init/template.ts @@ -0,0 +1,203 @@ +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { dirname, join, resolve } from "node:path"; + +import { err, ok, type Result } from "@uncaged/workflow"; + +import { pathExists } from "../../fs-utils.js"; + +export type CmdInitTemplateSuccess = { + templatePath: string; +}; + +function validateWorkspaceSegment(name: string): Result { + if (name.length === 0) { + return err("workspace name must not be empty"); + } + if (name === "." || name === "..") { + return err("invalid workspace name"); + } + if (name.includes("/") || name.includes("\\")) { + return err("workspace name must not contain path separators"); + } + return ok(undefined); +} + +function hasTemplatesWorkspaceGlob(workspaces: unknown): boolean { + return Array.isArray(workspaces) && workspaces.includes("templates/*"); +} + +async function readPackageJsonWorkspaces(dir: string): Promise { + const pkgPath = join(dir, "package.json"); + if (!(await pathExists(pkgPath))) { + return null; + } + let raw: string; + try { + raw = await readFile(pkgPath, "utf8"); + } catch { + return null; + } + let parsed: unknown; + try { + parsed = JSON.parse(raw) as unknown; + } catch { + return null; + } + if (typeof parsed !== "object" || parsed === null || !("workspaces" in parsed)) { + return null; + } + return (parsed as { workspaces: unknown }).workspaces; +} + +/** Resolve uncaged-workflow workspace root (package.json with `templates/*` in `workspaces`). */ +async function findWorkflowWorkspaceRoot(startDir: string): Promise> { + let dir = resolve(startDir); + for (;;) { + const workspaces = await readPackageJsonWorkspaces(dir); + if (workspaces !== null && hasTemplatesWorkspaceGlob(workspaces)) { + return ok(dir); + } + const parent = dirname(dir); + if (parent === dir) { + return err( + 'not inside a workflow workspace (no package.json with workspaces containing "templates/*")', + ); + } + dir = parent; + } +} + +function templatePackageJson(templateName: string): string { + return `${JSON.stringify( + { + name: `template-${templateName}`, + version: "0.0.0", + private: true, + type: "module", + dependencies: { + "@uncaged/workflow": "^0.1.0", + zod: "^4.0.0", + }, + }, + null, + 2, + )}\n`; +} + +function templateTsconfigJson(): string { + return `${JSON.stringify( + { + extends: "../../tsconfig.json", + compilerOptions: { + rootDir: "src", + outDir: "dist", + }, + include: ["src/**/*.ts"], + }, + null, + 2, + )}\n`; +} + +function templateRolesTs(): string { + return `import type { RoleDefinition } from "@uncaged/workflow"; +import * as z from "zod/v4"; + +export const HELLO_TEMPLATE_DESCRIPTION = + "Minimal starter template: one greeter role, then END."; + +export type HelloTemplateMeta = { + greeter: { + message: string; + }; +}; + +const greeterMetaSchema = z.object({ + message: z.string(), +}); + +export const greeterRole: RoleDefinition = { + description: "Says hello — replace with your first role.", + systemPrompt: "You are a helpful assistant. Reply with one short friendly sentence.", + extractPrompt: "Extract the assistant's greeting as message.", + schema: greeterMetaSchema, + extractRefs: null, +}; +`; +} + +function templateModeratorTs(): string { + return `import { END, type Moderator, type ModeratorContext } from "@uncaged/workflow"; + +import type { HelloTemplateMeta } from "./roles.js"; + +export const helloTemplateModerator: Moderator = ( + ctx: ModeratorContext, +) => { + if (ctx.steps.length === 0) { + return "greeter"; + } + return END; +}; +`; +} + +function templateIndexTs(): string { + return `import type { WorkflowDefinition } from "@uncaged/workflow"; + +import { helloTemplateModerator } from "./moderator.js"; +import { + HELLO_TEMPLATE_DESCRIPTION, + type HelloTemplateMeta, + greeterRole, +} from "./roles.js"; + +export { + HELLO_TEMPLATE_DESCRIPTION, + type HelloTemplateMeta, + greeterRole, +} from "./roles.js"; +export { helloTemplateModerator } from "./moderator.js"; + +export const helloTemplateWorkflowDefinition: WorkflowDefinition = { + description: HELLO_TEMPLATE_DESCRIPTION, + roles: { + greeter: greeterRole, + }, + moderator: helloTemplateModerator, +}; +`; +} + +export async function cmdInitTemplate( + startDir: string, + templateName: string, +): Promise> { + const validated = validateWorkspaceSegment(templateName); + if (!validated.ok) { + return validated; + } + + const rootResult = await findWorkflowWorkspaceRoot(startDir); + if (!rootResult.ok) { + return rootResult; + } + + const workspaceRoot = rootResult.value; + const templateDir = join(workspaceRoot, "templates", templateName); + if (await pathExists(templateDir)) { + return err(`template already exists: ${templateDir}`); + } + + await mkdir(join(templateDir, "src"), { recursive: true }); + + await Promise.all([ + writeFile(join(templateDir, "package.json"), templatePackageJson(templateName), "utf8"), + writeFile(join(templateDir, "tsconfig.json"), templateTsconfigJson(), "utf8"), + writeFile(join(templateDir, "src", "roles.ts"), templateRolesTs(), "utf8"), + writeFile(join(templateDir, "src", "moderator.ts"), templateModeratorTs(), "utf8"), + writeFile(join(templateDir, "src", "index.ts"), templateIndexTs(), "utf8"), + ]); + + return ok({ templatePath: templateDir }); +} diff --git a/packages/cli-workflow/src/cmd-init.ts b/packages/cli-workflow/src/commands/init/workspace.ts similarity index 63% rename from packages/cli-workflow/src/cmd-init.ts rename to packages/cli-workflow/src/commands/init/workspace.ts index c30ca68..0da8177 100644 --- a/packages/cli-workflow/src/cmd-init.ts +++ b/packages/cli-workflow/src/commands/init/workspace.ts @@ -1,18 +1,14 @@ -import { mkdir, readFile, writeFile } from "node:fs/promises"; -import { dirname, join, resolve } from "node:path"; +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; import { err, ok, type Result } from "@uncaged/workflow"; -import { pathExists } from "./fs-utils.js"; +import { pathExists } from "../../fs-utils.js"; export type CmdInitWorkspaceSuccess = { rootPath: string; }; -export type CmdInitTemplateSuccess = { - templatePath: string; -}; - function validateWorkspaceSegment(name: string): Result { if (name.length === 0) { return err("workspace name must not be empty"); @@ -233,183 +229,3 @@ export async function cmdInitWorkspace( return ok({ rootPath }); } - -function hasTemplatesWorkspaceGlob(workspaces: unknown): boolean { - return Array.isArray(workspaces) && workspaces.includes("templates/*"); -} - -async function readPackageJsonWorkspaces(dir: string): Promise { - const pkgPath = join(dir, "package.json"); - if (!(await pathExists(pkgPath))) { - return null; - } - let raw: string; - try { - raw = await readFile(pkgPath, "utf8"); - } catch { - return null; - } - let parsed: unknown; - try { - parsed = JSON.parse(raw) as unknown; - } catch { - return null; - } - if (typeof parsed !== "object" || parsed === null || !("workspaces" in parsed)) { - return null; - } - return (parsed as { workspaces: unknown }).workspaces; -} - -/** Resolve uncaged-workflow workspace root (package.json with `templates/*` in `workspaces`). */ -async function findWorkflowWorkspaceRoot(startDir: string): Promise> { - let dir = resolve(startDir); - for (;;) { - const workspaces = await readPackageJsonWorkspaces(dir); - if (workspaces !== null && hasTemplatesWorkspaceGlob(workspaces)) { - return ok(dir); - } - const parent = dirname(dir); - if (parent === dir) { - return err( - 'not inside a workflow workspace (no package.json with workspaces containing "templates/*")', - ); - } - dir = parent; - } -} - -function templatePackageJson(templateName: string): string { - return `${JSON.stringify( - { - name: `template-${templateName}`, - version: "0.0.0", - private: true, - type: "module", - dependencies: { - "@uncaged/workflow": "^0.1.0", - zod: "^4.0.0", - }, - }, - null, - 2, - )}\n`; -} - -function templateTsconfigJson(): string { - return `${JSON.stringify( - { - extends: "../../tsconfig.json", - compilerOptions: { - rootDir: "src", - outDir: "dist", - }, - include: ["src/**/*.ts"], - }, - null, - 2, - )}\n`; -} - -function templateRolesTs(): string { - return `import type { RoleDefinition } from "@uncaged/workflow"; -import * as z from "zod/v4"; - -export const HELLO_TEMPLATE_DESCRIPTION = - "Minimal starter template: one greeter role, then END."; - -export type HelloTemplateMeta = { - greeter: { - message: string; - }; -}; - -const greeterMetaSchema = z.object({ - message: z.string(), -}); - -export const greeterRole: RoleDefinition = { - description: "Says hello — replace with your first role.", - systemPrompt: "You are a helpful assistant. Reply with one short friendly sentence.", - extractPrompt: "Extract the assistant's greeting as message.", - schema: greeterMetaSchema, - extractRefs: null, -}; -`; -} - -function templateModeratorTs(): string { - return `import { END, type Moderator, type ModeratorContext } from "@uncaged/workflow"; - -import type { HelloTemplateMeta } from "./roles.js"; - -export const helloTemplateModerator: Moderator = ( - ctx: ModeratorContext, -) => { - if (ctx.steps.length === 0) { - return "greeter"; - } - return END; -}; -`; -} - -function templateIndexTs(): string { - return `import type { WorkflowDefinition } from "@uncaged/workflow"; - -import { helloTemplateModerator } from "./moderator.js"; -import { - HELLO_TEMPLATE_DESCRIPTION, - type HelloTemplateMeta, - greeterRole, -} from "./roles.js"; - -export { - HELLO_TEMPLATE_DESCRIPTION, - type HelloTemplateMeta, - greeterRole, -} from "./roles.js"; -export { helloTemplateModerator } from "./moderator.js"; - -export const helloTemplateWorkflowDefinition: WorkflowDefinition = { - description: HELLO_TEMPLATE_DESCRIPTION, - roles: { - greeter: greeterRole, - }, - moderator: helloTemplateModerator, -}; -`; -} - -export async function cmdInitTemplate( - startDir: string, - templateName: string, -): Promise> { - const validated = validateWorkspaceSegment(templateName); - if (!validated.ok) { - return validated; - } - - const rootResult = await findWorkflowWorkspaceRoot(startDir); - if (!rootResult.ok) { - return rootResult; - } - - const workspaceRoot = rootResult.value; - const templateDir = join(workspaceRoot, "templates", templateName); - if (await pathExists(templateDir)) { - return err(`template already exists: ${templateDir}`); - } - - await mkdir(join(templateDir, "src"), { recursive: true }); - - await Promise.all([ - writeFile(join(templateDir, "package.json"), templatePackageJson(templateName), "utf8"), - writeFile(join(templateDir, "tsconfig.json"), templateTsconfigJson(), "utf8"), - writeFile(join(templateDir, "src", "roles.ts"), templateRolesTs(), "utf8"), - writeFile(join(templateDir, "src", "moderator.ts"), templateModeratorTs(), "utf8"), - writeFile(join(templateDir, "src", "index.ts"), templateIndexTs(), "utf8"), - ]); - - return ok({ templatePath: templateDir }); -} diff --git a/packages/cli-workflow/src/cmd-fork.ts b/packages/cli-workflow/src/commands/thread/fork.ts similarity index 91% rename from packages/cli-workflow/src/cmd-fork.ts rename to packages/cli-workflow/src/commands/thread/fork.ts index acdb0a2..a99333a 100644 --- a/packages/cli-workflow/src/cmd-fork.ts +++ b/packages/cli-workflow/src/commands/thread/fork.ts @@ -2,9 +2,9 @@ import { join } from "node:path"; import { buildForkPlan, err, generateUlid, ok, type Result } from "@uncaged/workflow"; -import { pathExists, readTextFileIfExists } from "./fs-utils.js"; -import { resolveThreadDataPath } from "./thread-scan.js"; -import { ensureWorkerForHash, sendWorkerTcpCommand } from "./worker-spawn.js"; +import { pathExists, readTextFileIfExists } from "../../fs-utils.js"; +import { resolveThreadDataPath } from "../../thread-scan.js"; +import { ensureWorkerForHash, sendWorkerTcpCommand } from "../../worker-spawn.js"; export function parseForkArgv( argv: string[], diff --git a/packages/cli-workflow/src/commands/thread/index.ts b/packages/cli-workflow/src/commands/thread/index.ts new file mode 100644 index 0000000..e9a3a92 --- /dev/null +++ b/packages/cli-workflow/src/commands/thread/index.ts @@ -0,0 +1,17 @@ +export { cmdFork, parseForkArgv } from "./fork.js"; +export { cmdKill } from "./kill.js"; +export { cmdThreads } from "./list.js"; +export type { LiveRoleRow } from "./live.js"; +export { + cmdLive, + formatLiveDebugLine, + formatLiveTimeLabel, + LIVE_CONTENT_MAX_LINES, + renderLiveRoleStepLines, +} from "./live.js"; +export { cmdPause } from "./pause.js"; +export { cmdPs } from "./ps.js"; +export { cmdResume } from "./resume.js"; +export { cmdThreadRemove } from "./rm.js"; +export { cmdRun } from "./run.js"; +export { cmdThreadShow } from "./show.js"; diff --git a/packages/cli-workflow/src/cmd-kill.ts b/packages/cli-workflow/src/commands/thread/kill.ts similarity index 92% rename from packages/cli-workflow/src/cmd-kill.ts rename to packages/cli-workflow/src/commands/thread/kill.ts index 2bad4eb..3ccb2fa 100644 --- a/packages/cli-workflow/src/cmd-kill.ts +++ b/packages/cli-workflow/src/commands/thread/kill.ts @@ -2,12 +2,12 @@ import { join } from "node:path"; import { err, type Result } from "@uncaged/workflow"; -import { readTextFileIfExists } from "./fs-utils.js"; +import { readTextFileIfExists } from "../../fs-utils.js"; import { resolveRunningHashForThread, sendWorkerTcpCommand, type WorkerCtl, -} from "./worker-spawn.js"; +} from "../../worker-spawn.js"; export async function cmdKill( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-threads.ts b/packages/cli-workflow/src/commands/thread/list.ts similarity index 86% rename from packages/cli-workflow/src/cmd-threads.ts rename to packages/cli-workflow/src/commands/thread/list.ts index ac55cca..214d532 100644 --- a/packages/cli-workflow/src/cmd-threads.ts +++ b/packages/cli-workflow/src/commands/thread/list.ts @@ -1,7 +1,7 @@ import { err, ok, type Result } from "@uncaged/workflow"; -import { listHistoricalThreads } from "./thread-scan.js"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { listHistoricalThreads } from "../../thread-scan.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdThreads( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-live.ts b/packages/cli-workflow/src/commands/thread/live.ts similarity index 98% rename from packages/cli-workflow/src/cmd-live.ts rename to packages/cli-workflow/src/commands/thread/live.ts index ccbfcba..31d79ba 100644 --- a/packages/cli-workflow/src/cmd-live.ts +++ b/packages/cli-workflow/src/commands/thread/live.ts @@ -12,10 +12,10 @@ import { type WorkflowCompletion, } from "@uncaged/workflow"; -import { printCliError, printCliLine } from "./cli-output.js"; -import { pathExists } from "./fs-utils.js"; -import type { ParsedLiveArgv } from "./live-argv.js"; -import { findLatestThreadDataPath, resolveThreadDataPath } from "./thread-scan.js"; +import { printCliError, printCliLine } from "../../cli-output.js"; +import { pathExists } from "../../fs-utils.js"; +import type { ParsedLiveArgv } from "../../live-argv.js"; +import { findLatestThreadDataPath, resolveThreadDataPath } from "../../thread-scan.js"; export const LIVE_CONTENT_MAX_LINES = 10; diff --git a/packages/cli-workflow/src/cmd-pause.ts b/packages/cli-workflow/src/commands/thread/pause.ts similarity index 92% rename from packages/cli-workflow/src/cmd-pause.ts rename to packages/cli-workflow/src/commands/thread/pause.ts index a54f8aa..a8a414d 100644 --- a/packages/cli-workflow/src/cmd-pause.ts +++ b/packages/cli-workflow/src/commands/thread/pause.ts @@ -2,12 +2,12 @@ import { join } from "node:path"; import { err, type Result } from "@uncaged/workflow"; -import { readTextFileIfExists } from "./fs-utils.js"; +import { readTextFileIfExists } from "../../fs-utils.js"; import { resolveRunningHashForThread, sendWorkerTcpCommand, type WorkerCtl, -} from "./worker-spawn.js"; +} from "../../worker-spawn.js"; export async function cmdPause( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-ps.ts b/packages/cli-workflow/src/commands/thread/ps.ts similarity index 82% rename from packages/cli-workflow/src/cmd-ps.ts rename to packages/cli-workflow/src/commands/thread/ps.ts index e24a0ab..213aa49 100644 --- a/packages/cli-workflow/src/cmd-ps.ts +++ b/packages/cli-workflow/src/commands/thread/ps.ts @@ -1,4 +1,4 @@ -import { listRunningThreads } from "./thread-scan.js"; +import { listRunningThreads } from "../../thread-scan.js"; export async function cmdPs(storageRoot: string): Promise { const rows = await listRunningThreads(storageRoot); diff --git a/packages/cli-workflow/src/cmd-resume.ts b/packages/cli-workflow/src/commands/thread/resume.ts similarity index 92% rename from packages/cli-workflow/src/cmd-resume.ts rename to packages/cli-workflow/src/commands/thread/resume.ts index c8264dc..890dbb8 100644 --- a/packages/cli-workflow/src/cmd-resume.ts +++ b/packages/cli-workflow/src/commands/thread/resume.ts @@ -2,12 +2,12 @@ import { join } from "node:path"; import { err, type Result } from "@uncaged/workflow"; -import { readTextFileIfExists } from "./fs-utils.js"; +import { readTextFileIfExists } from "../../fs-utils.js"; import { resolveRunningHashForThread, sendWorkerTcpCommand, type WorkerCtl, -} from "./worker-spawn.js"; +} from "../../worker-spawn.js"; export async function cmdResume( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-thread.ts b/packages/cli-workflow/src/commands/thread/rm.ts similarity index 56% rename from packages/cli-workflow/src/cmd-thread.ts rename to packages/cli-workflow/src/commands/thread/rm.ts index ec01385..2e88e12 100644 --- a/packages/cli-workflow/src/cmd-thread.ts +++ b/packages/cli-workflow/src/commands/thread/rm.ts @@ -3,23 +3,7 @@ import { dirname, join } from "node:path"; import { err, garbageCollectCas, ok, type Result } from "@uncaged/workflow"; -import { readTextFileIfExists } from "./fs-utils.js"; -import { resolveThreadDataPath } from "./thread-scan.js"; - -export async function cmdThreadShow( - storageRoot: string, - threadId: string, -): Promise> { - const dataPath = await resolveThreadDataPath(storageRoot, threadId); - if (dataPath === null) { - return err(`thread not found: ${threadId}`); - } - const text = await readTextFileIfExists(dataPath); - if (text === null) { - return err(`thread data missing: ${threadId}`); - } - return ok(text.endsWith("\n") ? text.slice(0, -1) : text); -} +import { resolveThreadDataPath } from "../../thread-scan.js"; export async function cmdThreadRemove( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-run.ts b/packages/cli-workflow/src/commands/thread/run.ts similarity index 89% rename from packages/cli-workflow/src/cmd-run.ts rename to packages/cli-workflow/src/commands/thread/run.ts index 12be277..7af87ce 100644 --- a/packages/cli-workflow/src/cmd-run.ts +++ b/packages/cli-workflow/src/commands/thread/run.ts @@ -8,8 +8,8 @@ import { type Result, readWorkflowRegistry, } from "@uncaged/workflow"; -import { ensureWorkerForHash, sendWorkerTcpCommand } from "./worker-spawn.js"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { ensureWorkerForHash, sendWorkerTcpCommand } from "../../worker-spawn.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdRun( storageRoot: string, diff --git a/packages/cli-workflow/src/commands/thread/show.ts b/packages/cli-workflow/src/commands/thread/show.ts new file mode 100644 index 0000000..460ca5f --- /dev/null +++ b/packages/cli-workflow/src/commands/thread/show.ts @@ -0,0 +1,19 @@ +import { err, ok, type Result } from "@uncaged/workflow"; + +import { readTextFileIfExists } from "../../fs-utils.js"; +import { resolveThreadDataPath } from "../../thread-scan.js"; + +export async function cmdThreadShow( + storageRoot: string, + threadId: string, +): Promise> { + const dataPath = await resolveThreadDataPath(storageRoot, threadId); + if (dataPath === null) { + return err(`thread not found: ${threadId}`); + } + const text = await readTextFileIfExists(dataPath); + if (text === null) { + return err(`thread data missing: ${threadId}`); + } + return ok(text.endsWith("\n") ? text.slice(0, -1) : text); +} diff --git a/packages/cli-workflow/src/cmd-add.ts b/packages/cli-workflow/src/commands/workflow/add.ts similarity index 97% rename from packages/cli-workflow/src/cmd-add.ts rename to packages/cli-workflow/src/commands/workflow/add.ts index a865255..1cb1af4 100644 --- a/packages/cli-workflow/src/cmd-add.ts +++ b/packages/cli-workflow/src/commands/workflow/add.ts @@ -14,8 +14,8 @@ import { writeWorkflowRegistry, } from "@uncaged/workflow"; -import { storeWorkflowBundleArtifacts } from "./bundle-store.js"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { storeWorkflowBundleArtifacts } from "../../bundle-store.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export type ParsedAddArgv = { name: string; diff --git a/packages/cli-workflow/src/cmd-history.ts b/packages/cli-workflow/src/commands/workflow/history.ts similarity index 94% rename from packages/cli-workflow/src/cmd-history.ts rename to packages/cli-workflow/src/commands/workflow/history.ts index 30ed2c0..ecf41d1 100644 --- a/packages/cli-workflow/src/cmd-history.ts +++ b/packages/cli-workflow/src/commands/workflow/history.ts @@ -6,7 +6,7 @@ import { readWorkflowRegistry, } from "@uncaged/workflow"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdHistory( storageRoot: string, diff --git a/packages/cli-workflow/src/commands/workflow/index.ts b/packages/cli-workflow/src/commands/workflow/index.ts new file mode 100644 index 0000000..6cfde82 --- /dev/null +++ b/packages/cli-workflow/src/commands/workflow/index.ts @@ -0,0 +1,7 @@ +export type { CmdAddSuccess, ParsedAddArgv } from "./add.js"; +export { cmdAdd, formatAddSuccess, parseAddArgv } from "./add.js"; +export { cmdHistory } from "./history.js"; +export { cmdList, formatListLines } from "./list.js"; +export { cmdRemove } from "./rm.js"; +export { cmdRollback } from "./rollback.js"; +export { cmdShow, formatShowYaml } from "./show.js"; diff --git a/packages/cli-workflow/src/cmd-list.ts b/packages/cli-workflow/src/commands/workflow/list.ts similarity index 100% rename from packages/cli-workflow/src/cmd-list.ts rename to packages/cli-workflow/src/commands/workflow/list.ts diff --git a/packages/cli-workflow/src/cmd-remove.ts b/packages/cli-workflow/src/commands/workflow/rm.ts similarity index 91% rename from packages/cli-workflow/src/cmd-remove.ts rename to packages/cli-workflow/src/commands/workflow/rm.ts index 95185a5..0a1a7cf 100644 --- a/packages/cli-workflow/src/cmd-remove.ts +++ b/packages/cli-workflow/src/commands/workflow/rm.ts @@ -7,7 +7,7 @@ import { writeWorkflowRegistry, } from "@uncaged/workflow"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdRemove(storageRoot: string, name: string): Promise> { const nameOk = validateCliWorkflowName(name); diff --git a/packages/cli-workflow/src/cmd-rollback.ts b/packages/cli-workflow/src/commands/workflow/rollback.ts similarity index 91% rename from packages/cli-workflow/src/cmd-rollback.ts rename to packages/cli-workflow/src/commands/workflow/rollback.ts index 91e834d..77d4852 100644 --- a/packages/cli-workflow/src/cmd-rollback.ts +++ b/packages/cli-workflow/src/commands/workflow/rollback.ts @@ -10,8 +10,8 @@ import { writeWorkflowRegistry, } from "@uncaged/workflow"; -import { pathExists } from "./fs-utils.js"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { pathExists } from "../../fs-utils.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdRollback( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-show.ts b/packages/cli-workflow/src/commands/workflow/show.ts similarity index 93% rename from packages/cli-workflow/src/cmd-show.ts rename to packages/cli-workflow/src/commands/workflow/show.ts index ce54a45..5b4543a 100644 --- a/packages/cli-workflow/src/cmd-show.ts +++ b/packages/cli-workflow/src/commands/workflow/show.ts @@ -8,7 +8,7 @@ import { } from "@uncaged/workflow"; import { stringify } from "yaml"; -import { validateCliWorkflowName } from "./workflow-name.js"; +import { validateCliWorkflowName } from "../../workflow-name.js"; export async function cmdShow( storageRoot: string, diff --git a/packages/cli-workflow/src/cmd-help.ts b/packages/cli-workflow/src/skill.ts similarity index 100% rename from packages/cli-workflow/src/cmd-help.ts rename to packages/cli-workflow/src/skill.ts