@openworkflow/cli 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -35,6 +35,7 @@ workerCmd
35
35
  program
36
36
  .command("dashboard")
37
37
  .description("start the dashboard to view workflow runs")
38
+ .option("-p, --port <number>", "custom port for the dashboard server", Number.parseInt)
38
39
  .option("--config <path>", "path to OpenWorkflow config file")
39
40
  .action(withErrorHandling(dashboard));
40
41
  await program.parseAsync(process.argv);
@@ -2,6 +2,9 @@ import { WorkerConfig } from "./config.js";
2
2
  interface CommandOptions {
3
3
  config?: string;
4
4
  }
5
+ interface DashboardOptions extends CommandOptions {
6
+ port?: number;
7
+ }
5
8
  /**
6
9
  * openworkflow -V | --version
7
10
  * @returns the version string, or "-" if it cannot be determined
@@ -26,9 +29,30 @@ export declare function workerStart(options?: WorkerStartOptions): Promise<void>
26
29
  /**
27
30
  * openworkflow dashboard
28
31
  * Starts the dashboard by delegating to `@openworkflow/dashboard` via npx.
29
- * @param options - Command options
32
+ * @param port - Optional dashboard port.
33
+ * @returns Spawn configuration for launching the dashboard process.
34
+ */
35
+ export declare function getDashboardSpawnOptions(port?: number): {
36
+ command: string;
37
+ args: string[];
38
+ spawnOptions: {
39
+ stdio: "inherit";
40
+ env?: NodeJS.ProcessEnv;
41
+ };
42
+ };
43
+ /**
44
+ * Validate dashboard port option.
45
+ * @param port - Optional dashboard port.
46
+ * @returns Validated dashboard port.
47
+ * @throws {CLIError} If the provided port is not an integer in the 1-65535 range.
48
+ */
49
+ export declare function validateDashboardPort(port?: number): number | undefined;
50
+ /**
51
+ * Start the dashboard process.
52
+ * @param options - Dashboard command options.
53
+ * @returns Resolves when the dashboard process exits.
30
54
  */
31
- export declare function dashboard(options?: CommandOptions): Promise<void>;
55
+ export declare function dashboard(options?: DashboardOptions): Promise<void>;
32
56
  /**
33
57
  * Discover workflow files from directories. Recursively scans directories for
34
58
  * workflow files with supported extensions (.ts, .js, .mjs, .cjs).
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkC,MAAM,aAAa,CAAC;AAiC3E,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAoBnC;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoItE;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDxE;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,cAAc,CAAC;AAE/D;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2D3E;AAwOD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,MAAM,EAAO,GAC5B,MAAM,EAAE,CA4CV;AA8VD,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAsBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkC,MAAM,aAAa,CAAC;AAiC3E,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,gBAAiB,SAAQ,cAAc;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAoBnC;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoItE;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDxE;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,cAAc,CAAC;AAE/D;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE;QACZ,KAAK,EAAE,SAAS,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACzB,CAAC;CACH,CAYA;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAavE;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D7E;AAwOD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,MAAM,EAAO,GAC5B,MAAM,EAAE,CA4CV;AAiWD,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAsBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR"}
package/dist/commands.js CHANGED
@@ -247,20 +247,52 @@ export async function workerStart(options = {}) {
247
247
  /**
248
248
  * openworkflow dashboard
249
249
  * Starts the dashboard by delegating to `@openworkflow/dashboard` via npx.
250
- * @param options - Command options
250
+ * @param port - Optional dashboard port.
251
+ * @returns Spawn configuration for launching the dashboard process.
252
+ */
253
+ export function getDashboardSpawnOptions(port) {
254
+ return {
255
+ command: "npx",
256
+ args: ["@openworkflow/dashboard"],
257
+ spawnOptions: {
258
+ stdio: "inherit",
259
+ env: port === undefined
260
+ ? process.env
261
+ : { ...process.env, PORT: String(port) },
262
+ },
263
+ };
264
+ }
265
+ /**
266
+ * Validate dashboard port option.
267
+ * @param port - Optional dashboard port.
268
+ * @returns Validated dashboard port.
269
+ * @throws {CLIError} If the provided port is not an integer in the 1-65535 range.
270
+ */
271
+ export function validateDashboardPort(port) {
272
+ if (port === undefined) {
273
+ return undefined;
274
+ }
275
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
276
+ throw new CLIError("Invalid dashboard port.", "Use an integer between 1 and 65535, for example `--port 3001`.");
277
+ }
278
+ return port;
279
+ }
280
+ /**
281
+ * Start the dashboard process.
282
+ * @param options - Dashboard command options.
283
+ * @returns Resolves when the dashboard process exits.
251
284
  */
252
285
  export async function dashboard(options = {}) {
253
286
  const configPath = options.config;
287
+ const port = validateDashboardPort(options.port);
254
288
  consola.start("Starting dashboard...");
255
289
  const { configFile } = await loadConfigWithEnv(configPath);
256
290
  if (!configFile) {
257
291
  throw new CLIError("No config file found.", "Run `npx @openworkflow/cli init` to create a config file before starting the dashboard.");
258
292
  }
259
293
  consola.info(`Using config: ${configFile}`);
260
- // eslint-disable-next-line sonarjs/no-os-command-from-path
261
- const child = spawn("npx", ["@openworkflow/dashboard"], {
262
- stdio: "inherit",
263
- });
294
+ const spawnConfig = getDashboardSpawnOptions(port);
295
+ const child = spawn(spawnConfig.command, spawnConfig.args, spawnConfig.spawnOptions);
264
296
  await new Promise((resolve, reject) => {
265
297
  /** remove signal handlers after the child exits */
266
298
  function cleanupSignalHandlers() {
@@ -686,10 +718,10 @@ function updateGitignoreForSqlite() {
686
718
  const gitignorePath = path.join(process.cwd(), ".gitignore");
687
719
  const spinner = p.spinner();
688
720
  spinner.start("Updating .gitignore...");
689
- const result = ensureGitignoreEntry(gitignorePath, "openworkflow/backend.db");
721
+ const result = ensureGitignoreEntry(gitignorePath, "openworkflow/backend.db*");
690
722
  spinner.stop(result.added
691
- ? "Added openworkflow/backend.db to .gitignore"
692
- : "openworkflow/backend.db already in .gitignore");
723
+ ? "Added openworkflow/backend.db* to .gitignore"
724
+ : "openworkflow/backend.db* already in .gitignore");
693
725
  }
694
726
  /**
695
727
  * Add worker script to package.json.
@@ -717,7 +749,7 @@ function addWorkerScriptToPackageJson() {
717
749
  * Ensure a specific entry exists in a .gitignore file. Creates the file if it
718
750
  * doesn't exist, appends the entry if not present.
719
751
  * @param gitignorePath - Path to the .gitignore file
720
- * @param entry - The entry to add (e.g. "openworkflow/backend.db")
752
+ * @param entry - The entry to add (e.g. "openworkflow/backend.db*")
721
753
  * @returns Object indicating whether the entry was added or already existed
722
754
  */
723
755
  function ensureGitignoreEntry(gitignorePath, entry) {
@@ -3,5 +3,5 @@ export declare const POSTGRES_CLIENT = "import { BackendPostgres } from \"openwo
3
3
  export declare const POSTGRES_PROD_SQLITE_DEV_CLIENT = "import { BackendPostgres } from \"openworkflow/postgres\";\nimport { BackendSqlite } from \"openworkflow/sqlite\";\nimport { OpenWorkflow } from \"openworkflow\";\n\nexport const backend =\n process.env[\"NODE_ENV\"] === \"production\"\n ? await BackendPostgres.connect(process.env[\"OPENWORKFLOW_POSTGRES_URL\"])\n : BackendSqlite.connect(\"openworkflow/backend.db\");\nexport const ow = new OpenWorkflow({ backend });\n";
4
4
  export declare const CONFIG = "import { backend } from \"./openworkflow/client.js\";\nimport { defineConfig } from \"@openworkflow/cli\";\n\nexport default defineConfig({\n backend,\n dirs: \"./openworkflow\",\n ignorePatterns: [\"**/*.run.*\"],\n});\n";
5
5
  export declare const HELLO_WORLD_WORKFLOW = "import { defineWorkflow } from \"openworkflow\";\n\n/**\n * Example workflow that greets the world.\n *\n * This workflow is auto-discovered by the CLI worker.\n * To trigger it, use ow.runWorkflow() from your app:\n * ```ts\n * import { ow } from \"./openworkflow/client.js\";\n * import { helloWorld } from \"./openworkflow/hello-world.js\";\n * const handle = await ow.runWorkflow(helloWorld.spec, {});\n * const result = await handle.result();\n * ```\n */\nexport const helloWorld = defineWorkflow(\n { name: \"hello-world\" },\n async ({ step }) => {\n const greeting = await step.run({ name: \"greet\" }, () => {\n return \"Hello, World!\";\n });\n\n await step.sleep(\"wait-a-bit\", \"1s\");\n\n return { greeting };\n },\n);\n";
6
- export declare const HELLO_WORLD_RUNNER = "import { ow } from \"./client.js\";\nimport { helloWorld } from \"./hello-world.js\";\n\n// Run this file:\n// JS: `node openworkflow/hello-world.run.js`\n// TS: `npx tsx openworkflow/hello-world.run.ts`\n//\n// This file is a temporary dev helper generated by\n// `npx @openworkflow/cli init` so you can quickly run the example workflow.\n//\n// Copy the code anywhere in your app (e.g., an API route or a script) and\n// modify it to run your workflows.\n//\n// You can delete this file once you're done with it.\n\nconsole.log(\"Running hello-world workflow...\");\nconst handle = await ow.runWorkflow(helloWorld.spec, {});\n\nconsole.log(\"Waiting for result...\");\nconst result = await handle.result(); // for very short workflows only\n\nconsole.log(`Workflow result: ${JSON.stringify(result, null, 2)}`);\n";
6
+ export declare const HELLO_WORLD_RUNNER = "import { backend, ow } from \"./client.js\";\nimport { helloWorld } from \"./hello-world.js\";\n\n// Run this file:\n// JS: `node openworkflow/hello-world.run.js`\n// TS: `npx tsx openworkflow/hello-world.run.ts`\n//\n// This file is a temporary dev helper generated by\n// `npx @openworkflow/cli init` so you can quickly run the example workflow.\n//\n// Copy the code anywhere in your app (e.g., an API route or a script) and\n// modify it to run your workflows.\n//\n// You can delete this file once you're done with it.\n\nconsole.log(\"Running hello-world workflow...\");\nconst handle = await ow.runWorkflow(helloWorld.spec, {});\n\nconsole.log(\"Waiting for result...\");\nconst result = await handle.result(); // for very short workflows only\n\nconsole.log(`Workflow result: ${JSON.stringify(result, null, 2)}`);\n\n// Stop backend. Only needed if this is a standalone script that you want to\n// exit after running the workflow.\nawait backend.stop();\n";
7
7
  //# sourceMappingURL=templates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,6OAKzB,CAAC;AAEF,eAAO,MAAM,eAAe,+QAO3B,CAAC;AAEF,eAAO,MAAM,+BAA+B,ibAS3C,CAAC;AAEF,eAAO,MAAM,MAAM,qOAQlB,CAAC;AAEF,eAAO,MAAM,oBAAoB,wvBA0BhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,mzBAsB9B,CAAC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,6OAKzB,CAAC;AAEF,eAAO,MAAM,eAAe,+QAO3B,CAAC;AAEF,eAAO,MAAM,+BAA+B,ibAS3C,CAAC;AAEF,eAAO,MAAM,MAAM,qOAQlB,CAAC;AAEF,eAAO,MAAM,oBAAoB,wvBA0BhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,w8BA0B9B,CAAC"}
package/dist/templates.js CHANGED
@@ -58,7 +58,7 @@ export const helloWorld = defineWorkflow(
58
58
  },
59
59
  );
60
60
  `;
61
- export const HELLO_WORLD_RUNNER = `import { ow } from "./client.js";
61
+ export const HELLO_WORLD_RUNNER = `import { backend, ow } from "./client.js";
62
62
  import { helloWorld } from "./hello-world.js";
63
63
 
64
64
  // Run this file:
@@ -80,4 +80,8 @@ console.log("Waiting for result...");
80
80
  const result = await handle.result(); // for very short workflows only
81
81
 
82
82
  console.log(\`Workflow result: \${JSON.stringify(result, null, 2)}\`);
83
+
84
+ // Stop backend. Only needed if this is a standalone script that you want to
85
+ // exit after running the workflow.
86
+ await backend.stop();
83
87
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openworkflow/cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -22,14 +22,15 @@
22
22
  "!*.tsbuildinfo"
23
23
  ],
24
24
  "scripts": {
25
- "build": "tsc",
25
+ "build": "npm run clean && tsc",
26
+ "clean": "rm -rf dist",
26
27
  "prepublishOnly": "npm run build"
27
28
  },
28
29
  "dependencies": {
29
- "@clack/prompts": "^1.0.0",
30
+ "@clack/prompts": "^1.0.1",
30
31
  "commander": "^14.0.3",
31
32
  "consola": "^3.4.2",
32
- "dotenv": "^17.2.4",
33
+ "dotenv": "^17.3.1",
33
34
  "jiti": "^2.6.1",
34
35
  "nypm": "^0.6.5"
35
36
  },
@@ -38,6 +39,6 @@
38
39
  "vitest": "^4.0.18"
39
40
  },
40
41
  "peerDependencies": {
41
- "openworkflow": "^0.6.0 || ^0.7.0"
42
+ "openworkflow": "^0.6.0 || ^0.7.0 || ^0.8.0"
42
43
  }
43
44
  }
package/dist/skills.d.ts DELETED
@@ -1,61 +0,0 @@
1
- declare const SUPPORTED_SKILL_AGENTS: readonly ["codex", "claude"];
2
- export type SkillAgent = (typeof SUPPORTED_SKILL_AGENTS)[number];
3
- export interface SkillCatalogEntry {
4
- name: string;
5
- description: string;
6
- }
7
- export interface InstallOpenWorkflowSkillsOptions {
8
- agent: SkillAgent;
9
- force: boolean;
10
- requestedSkillNames?: string[];
11
- targetDirectory?: string;
12
- workspaceDirectory: string;
13
- }
14
- export interface InstalledSkill {
15
- name: string;
16
- overwritten: boolean;
17
- path: string;
18
- }
19
- export interface InstallOpenWorkflowSkillsResult {
20
- installedSkills: InstalledSkill[];
21
- targetDirectory: string;
22
- }
23
- /**
24
- * True when the provided value is a supported skill agent.
25
- * @param value - Agent value from CLI options
26
- * @returns Whether the value is supported
27
- */
28
- export declare function isSkillAgent(value: string): value is SkillAgent;
29
- /**
30
- * Returns the default skill directory for an agent.
31
- * @param agent - Skill agent
32
- * @returns Relative target directory
33
- */
34
- export declare function getDefaultSkillDirectory(agent: SkillAgent): string;
35
- /**
36
- * List available OpenWorkflow skills.
37
- * @returns Skill catalog entries
38
- */
39
- export declare function listOpenWorkflowSkills(): SkillCatalogEntry[];
40
- /**
41
- * Resolve requested skill names, defaulting to all.
42
- * @param requestedSkillNames - Skill names from CLI options
43
- * @returns Unique, validated skill names
44
- * @throws {Error} When one or more skill names are unknown
45
- */
46
- export declare function resolveSkillNames(requestedSkillNames?: string[]): string[];
47
- /**
48
- * Install OpenWorkflow skills to an agent skill directory.
49
- * @param options - Install options
50
- * @returns Install result metadata
51
- * @throws {Error} When skill names are invalid or files already exist without force
52
- */
53
- export declare function installOpenWorkflowSkills(options: InstallOpenWorkflowSkillsOptions): InstallOpenWorkflowSkillsResult;
54
- /**
55
- * Read a skill file from disk. Used by tests.
56
- * @param skillPath - Path to the skill file
57
- * @returns File content
58
- */
59
- export declare function readSkillFile(skillPath: string): string;
60
- export {};
61
- //# sourceMappingURL=skills.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../skills.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,sBAAsB,8BAA+B,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC9C,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;CACzB;AAyMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAElE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,iBAAiB,EAAE,CAK5D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiB1E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,+BAA+B,CA2CjC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD"}
package/dist/skills.js DELETED
@@ -1,286 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
- import path from "node:path";
3
- const SUPPORTED_SKILL_AGENTS = ["codex", "claude"];
4
- const DEFAULT_SKILL_DIRECTORIES = {
5
- codex: path.join(".agents", "skills"),
6
- claude: path.join(".claude", "skills"),
7
- };
8
- const OPENWORKFLOW_SKILLS = [
9
- {
10
- name: "openworkflow-quickstart",
11
- description: "Scaffold, implement, and run durable workflows with the OpenWorkflow CLI.",
12
- files: {
13
- "SKILL.md": `---
14
- name: openworkflow-quickstart
15
- description: Use when a user asks to create, run, or update OpenWorkflow workflows in an app codebase.
16
- ---
17
-
18
- # OpenWorkflow Quickstart
19
-
20
- Use this skill when the user wants to build or update a workflow quickly.
21
-
22
- ## Standard flow
23
-
24
- 1. Confirm the project has OpenWorkflow set up. If not, run \`npx @openworkflow/cli init\`.
25
- 2. Create or update workflow code in \`openworkflow/\` with \`defineWorkflow\`.
26
- 3. Keep side effects inside \`step.run(...)\` calls, and keep step names stable.
27
- 4. Start a worker with \`npx @openworkflow/cli worker start\`.
28
- 5. Trigger the workflow with \`ow.runWorkflow(workflow.spec, input)\`.
29
- 6. Validate setup with \`npx @openworkflow/cli doctor\`.
30
-
31
- ## Guardrails
32
-
33
- - Keep workflow replay deterministic outside of \`step.run\`.
34
- - Use explicit, descriptive, stable step names.
35
- - Use \`step.sleep\` for durable waits instead of process timers.
36
- - Return JSON-serializable values from steps and workflow output.
37
-
38
- ## Useful commands
39
-
40
- \`\`\`bash
41
- npx @openworkflow/cli init
42
- npx @openworkflow/cli worker start
43
- npx @openworkflow/cli doctor
44
- npx @openworkflow/cli dashboard
45
- \`\`\`
46
- `,
47
- },
48
- },
49
- {
50
- name: "openworkflow-patterns",
51
- description: "Apply durable workflow patterns for retries, idempotency, and versioning.",
52
- files: {
53
- "SKILL.md": `---
54
- name: openworkflow-patterns
55
- description: Use when a user asks for production workflow design patterns in OpenWorkflow.
56
- ---
57
-
58
- # OpenWorkflow Patterns
59
-
60
- Use this skill for architecture and implementation guidance on durable workflows.
61
-
62
- ## Patterns to apply
63
-
64
- 1. Prefer many small \`step.run\` calls over one large step.
65
- 2. Keep external side effects in steps with stable names to preserve memoization.
66
- 3. Use idempotency keys for enqueue endpoints that may be retried.
67
- 4. Use workflow versioning when behavior changes in non-backward-compatible ways.
68
- 5. Use \`step.sleep\` for delays and backoff scheduling.
69
-
70
- ## Failure handling
71
-
72
- - Let transient failures throw from step functions so retries can reschedule runs.
73
- - Use explicit deadlines for workflows that should fail fast.
74
- - Add compensation steps for side effects that need rollback behavior.
75
-
76
- ## Review checklist
77
-
78
- - Is workflow code deterministic between checkpoints?
79
- - Are step names stable across deployments?
80
- - Are retry expectations documented for each external dependency?
81
- - Are deadline and workflow cancel paths tested?
82
- `,
83
- },
84
- },
85
- {
86
- name: "openworkflow-sql-inspector",
87
- description: "Inspect workflow and step state directly in SQLite or PostgreSQL with read-only SQL.",
88
- files: {
89
- "SKILL.md": `---
90
- name: openworkflow-sql-inspector
91
- description: Use when a user asks why workflows are stuck, slow, failed, or repeatedly retried.
92
- ---
93
-
94
- # OpenWorkflow SQL Inspector
95
-
96
- Use this skill to answer workflow runtime questions from database state.
97
-
98
- ## Safety rules
99
-
100
- 1. Use read-only SQL only.
101
- 2. Do not run INSERT, UPDATE, DELETE, ALTER, DROP, TRUNCATE, or CREATE.
102
- 3. Always add \`LIMIT\` to exploratory queries (default 100).
103
- 4. Redact sensitive values before sharing query output.
104
-
105
- ## Database notes
106
-
107
- - SQLite default path from CLI init: \`openworkflow/backend.db\`.
108
- - PostgreSQL default schema: \`openworkflow\`.
109
- - Core tables: \`workflow_runs\`, \`step_attempts\`.
110
-
111
- Read [references/sql-queries.md](references/sql-queries.md) for practical query templates.
112
- `,
113
- "references/sql-queries.md": `# SQL Query Templates
114
-
115
- ## PostgreSQL
116
-
117
- Use a read-only transaction for ad hoc inspection:
118
-
119
- \`\`\`sql
120
- BEGIN READ ONLY;
121
- SELECT
122
- namespace_id,
123
- id,
124
- workflow_name,
125
- status,
126
- attempts,
127
- available_at,
128
- deadline_at,
129
- created_at,
130
- updated_at
131
- FROM openworkflow.workflow_runs
132
- ORDER BY created_at DESC
133
- LIMIT 100;
134
- COMMIT;
135
- \`\`\`
136
-
137
- Recent step attempts for a workflow run:
138
-
139
- \`\`\`sql
140
- SELECT
141
- namespace_id,
142
- id,
143
- workflow_run_id,
144
- step_name,
145
- kind,
146
- status,
147
- started_at,
148
- finished_at,
149
- created_at
150
- FROM openworkflow.step_attempts
151
- WHERE workflow_run_id = $1
152
- ORDER BY created_at DESC
153
- LIMIT 200;
154
- \`\`\`
155
-
156
- ## SQLite
157
-
158
- List recent workflow runs:
159
-
160
- \`\`\`sql
161
- SELECT
162
- namespace_id,
163
- id,
164
- workflow_name,
165
- status,
166
- attempts,
167
- available_at,
168
- deadline_at,
169
- created_at,
170
- updated_at
171
- FROM workflow_runs
172
- ORDER BY created_at DESC
173
- LIMIT 100;
174
- \`\`\`
175
-
176
- List step attempts for one run:
177
-
178
- \`\`\`sql
179
- SELECT
180
- namespace_id,
181
- id,
182
- workflow_run_id,
183
- step_name,
184
- kind,
185
- status,
186
- started_at,
187
- finished_at,
188
- created_at
189
- FROM step_attempts
190
- WHERE workflow_run_id = ?
191
- ORDER BY created_at DESC
192
- LIMIT 200;
193
- \`\`\`
194
- `,
195
- },
196
- },
197
- ];
198
- /**
199
- * True when the provided value is a supported skill agent.
200
- * @param value - Agent value from CLI options
201
- * @returns Whether the value is supported
202
- */
203
- export function isSkillAgent(value) {
204
- return SUPPORTED_SKILL_AGENTS.includes(value);
205
- }
206
- /**
207
- * Returns the default skill directory for an agent.
208
- * @param agent - Skill agent
209
- * @returns Relative target directory
210
- */
211
- export function getDefaultSkillDirectory(agent) {
212
- return DEFAULT_SKILL_DIRECTORIES[agent];
213
- }
214
- /**
215
- * List available OpenWorkflow skills.
216
- * @returns Skill catalog entries
217
- */
218
- export function listOpenWorkflowSkills() {
219
- return OPENWORKFLOW_SKILLS.map((skill) => ({
220
- name: skill.name,
221
- description: skill.description,
222
- }));
223
- }
224
- /**
225
- * Resolve requested skill names, defaulting to all.
226
- * @param requestedSkillNames - Skill names from CLI options
227
- * @returns Unique, validated skill names
228
- * @throws {Error} When one or more skill names are unknown
229
- */
230
- export function resolveSkillNames(requestedSkillNames) {
231
- const requested = requestedSkillNames && requestedSkillNames.length > 0
232
- ? requestedSkillNames
233
- : OPENWORKFLOW_SKILLS.map((skill) => skill.name);
234
- const deduped = [...new Set(requested)];
235
- const unknownSkills = deduped.filter((name) => OPENWORKFLOW_SKILLS.every((skill) => skill.name !== name));
236
- if (unknownSkills.length > 0) {
237
- throw new Error(`Unknown skill name${unknownSkills.length === 1 ? "" : "s"}: ${unknownSkills.join(", ")}`);
238
- }
239
- return deduped;
240
- }
241
- /**
242
- * Install OpenWorkflow skills to an agent skill directory.
243
- * @param options - Install options
244
- * @returns Install result metadata
245
- * @throws {Error} When skill names are invalid or files already exist without force
246
- */
247
- export function installOpenWorkflowSkills(options) {
248
- const requestedSkillNames = resolveSkillNames(options.requestedSkillNames);
249
- const defaultDirectory = getDefaultSkillDirectory(options.agent);
250
- const targetDirectory = path.resolve(options.workspaceDirectory, options.targetDirectory ?? defaultDirectory);
251
- mkdirSync(targetDirectory, { recursive: true });
252
- const installedSkills = [];
253
- for (const skillName of requestedSkillNames) {
254
- const skill = OPENWORKFLOW_SKILLS.find((item) => item.name === skillName);
255
- if (!skill) {
256
- continue;
257
- }
258
- const skillDirectory = path.join(targetDirectory, skill.name);
259
- const hadExistingDirectory = existsSync(skillDirectory);
260
- if (hadExistingDirectory && !options.force) {
261
- throw new Error(`Skill "${skill.name}" already exists at ${skillDirectory}. Use --force to overwrite.`);
262
- }
263
- if (hadExistingDirectory) {
264
- rmSync(skillDirectory, { force: true, recursive: true });
265
- }
266
- for (const [relativePath, content] of Object.entries(skill.files)) {
267
- const destinationPath = path.join(skillDirectory, relativePath);
268
- mkdirSync(path.dirname(destinationPath), { recursive: true });
269
- writeFileSync(destinationPath, content, "utf8");
270
- }
271
- installedSkills.push({
272
- name: skill.name,
273
- overwritten: hadExistingDirectory,
274
- path: skillDirectory,
275
- });
276
- }
277
- return { installedSkills, targetDirectory };
278
- }
279
- /**
280
- * Read a skill file from disk. Used by tests.
281
- * @param skillPath - Path to the skill file
282
- * @returns File content
283
- */
284
- export function readSkillFile(skillPath) {
285
- return readFileSync(skillPath, "utf8");
286
- }