5970456a54
CI / check (pull_request) Failing after 8m30s
Rename packages/ subdirectories to match their @united-workforce/* scope: cli-workflow → cli workflow-agent-builtin → agent-builtin workflow-agent-claude-code → agent-claude-code workflow-agent-hermes → agent-hermes workflow-dashboard → dashboard workflow-protocol → protocol workflow-util-agent → util-agent workflow-util → util Updated all tsconfig references, scripts, and active docs. Historical docs (docs/plans/, docs/superpowers/) left as-is. Closes #21
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { dirname, extname, resolve } from "node:path";
|
|
import { parse as parseYaml } from "yaml";
|
|
|
|
/**
|
|
* Create a YAML customTags entry for !include that resolves file paths
|
|
* relative to the given base directory.
|
|
*
|
|
* Security: resolved paths must stay within baseDir (path traversal prevention).
|
|
* Nested !include in .yaml/.yml files is supported (customTags passed recursively).
|
|
*/
|
|
export function createIncludeTag(baseDir: string) {
|
|
const resolvedBase = resolve(baseDir);
|
|
return {
|
|
tag: "!include",
|
|
resolve(str: string) {
|
|
const filePath = resolve(resolvedBase, str);
|
|
// Path traversal guard: resolved path must be inside baseDir
|
|
if (!filePath.startsWith(`${resolvedBase}/`) && filePath !== resolvedBase) {
|
|
throw new Error(
|
|
`!include path traversal blocked: "${str}" resolves outside base directory`,
|
|
);
|
|
}
|
|
const content = readFileSync(filePath, "utf8");
|
|
const ext = extname(filePath).toLowerCase();
|
|
if (ext === ".json") {
|
|
return JSON.parse(content);
|
|
}
|
|
if (ext === ".yaml" || ext === ".yml") {
|
|
// Pass customTags recursively so nested !include works,
|
|
// scoped to the included file's directory
|
|
return parseYaml(content, { customTags: [createIncludeTag(dirname(filePath))] });
|
|
}
|
|
return content;
|
|
},
|
|
};
|
|
}
|