feat: !include YAML tag and folder-based workflow layout

- Add !include custom YAML tag for referencing external files (Fixes #582)
  - .md/.txt files included as strings
  - .json files parsed as JSON objects
  - .yaml/.yml files parsed as YAML objects
  - Paths resolved relative to the workflow YAML file

- Support foo/index.yaml as alternative to foo.yaml (Fixes #583)
  - Updated discoverProjectWorkflows(), findWorkflowInDir()
  - Updated workflowNameFromPath() for index.yaml detection
  - Flat files take priority over folder layout

- Added tests for both features
This commit is contained in:
2026-05-31 04:12:11 +00:00
parent 9fb817a99c
commit 88c251fc14
7 changed files with 160 additions and 14 deletions
@@ -1,9 +1,11 @@
import { readFile } from "node:fs/promises";
import { dirname, resolve as resolvePath } from "node:path";
import type { JSONSchema } from "@uncaged/json-cas";
import { putSchema, validate } from "@uncaged/json-cas";
import type { CasRef, RoleDefinition, Target, WorkflowPayload } from "@uncaged/workflow-protocol";
import { parse } from "yaml";
import { createIncludeTag } from "../include.js";
import {
createUwfStore,
@@ -123,7 +125,7 @@ export async function cmdWorkflowAdd(
let raw: unknown;
try {
raw = parse(text) as unknown;
raw = parse(text, { customTags: [createIncludeTag(dirname(resolvePath(filePath)))] }) as unknown;
} catch (e) {
fail(`invalid YAML: ${e instanceof Error ? e.message : String(e)}`);
}