@formtrieb/cdf-core
Advanced tools
+38
-0
@@ -8,2 +8,40 @@ # Changelog | ||
| ## [1.0.3] — 2026-04-26 | ||
| ### Fixed — `parseConfigFile` crashes when `profile_path` set but file missing | ||
| The MCP server (and any tool calling `parseConfigFile`) used to crash on | ||
| startup with `ENOENT` when `.cdf.config.yaml` declared a `profile_path:` | ||
| that didn't exist yet. This is the **normal bootstrap state** — the | ||
| `/cdf:scaffold-profile` skill writes the profile YAML mid-run, so the | ||
| config validly references a file that won't exist until after the | ||
| scaffold completes. | ||
| `parseConfigFile` now checks `existsSync(profileAbsPath)` before | ||
| attempting the read. If the file is missing it leaves `ds_profile` | ||
| undefined and emits one stderr line: | ||
| ``` | ||
| [cdf-core] profile_path './my-ds.profile.yaml' set in /path/.cdf.config.yaml but file does not exist (...); ds_profile not loaded. | ||
| ``` | ||
| The warning preserves the diagnostic signal for genuine misconfigurations | ||
| (typos, wrong relative paths) while letting bootstrap states proceed. | ||
| Downstream consumers already check `config.ds_profile` for `undefined` | ||
| so no cascading changes are needed. | ||
| Affected: any caller of `parseConfigFile` — most visibly | ||
| [`@formtrieb/cdf-mcp`](https://www.npmjs.com/package/@formtrieb/cdf-mcp) | ||
| v1.7.0–1.7.1 (where this manifested as | ||
| `MCP error -32000: Connection closed` in the | ||
| [`cdf` Claude Code plugin](https://github.com/formtrieb/cdf-plugin)). | ||
| v1.7.2 of cdf-mcp pins `^1.0.3` to force a clean dep refresh. | ||
| ### Tests | ||
| - 4 new `test/config-parser.test.ts` tests: existing-profile happy | ||
| path, missing-profile skip+warn, no-profile_path quiet path, | ||
| relative-path resolution from config dir | ||
| - 427/427 total tests green (423 → 427) | ||
| ## [1.0.2] — 2026-04-26 | ||
@@ -10,0 +48,0 @@ |
@@ -8,5 +8,10 @@ import type { CDFConfig } from "../types/cdf.js"; | ||
| * Parse a .cdf.config.yaml file from disk. | ||
| * If `profile_path` is set, loads the Profile YAML and attaches it as `ds_profile`. | ||
| * | ||
| * If `profile_path` is set AND the referenced file exists, loads the Profile | ||
| * YAML and attaches it as `ds_profile`. If the path is set but the file is | ||
| * missing, skips loading and emits a one-line stderr warning — this is the | ||
| * normal bootstrap state (`/cdf:scaffold-profile` writes the file mid-run), | ||
| * so failing here would brick the MCP server before its tools could register. | ||
| */ | ||
| export declare function parseConfigFile(filePath: string): CDFConfig; | ||
| //# sourceMappingURL=config-parser.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/parser/config-parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAE1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAU3D"} | ||
| {"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/parser/config-parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAiB3D"} |
@@ -1,2 +0,2 @@ | ||
| import { readFileSync } from "node:fs"; | ||
| import { readFileSync, existsSync } from "node:fs"; | ||
| import { resolve, dirname } from "node:path"; | ||
@@ -13,3 +13,8 @@ import { parse as parseYAML } from "yaml"; | ||
| * Parse a .cdf.config.yaml file from disk. | ||
| * If `profile_path` is set, loads the Profile YAML and attaches it as `ds_profile`. | ||
| * | ||
| * If `profile_path` is set AND the referenced file exists, loads the Profile | ||
| * YAML and attaches it as `ds_profile`. If the path is set but the file is | ||
| * missing, skips loading and emits a one-line stderr warning — this is the | ||
| * normal bootstrap state (`/cdf:scaffold-profile` writes the file mid-run), | ||
| * so failing here would brick the MCP server before its tools could register. | ||
| */ | ||
@@ -21,3 +26,9 @@ export function parseConfigFile(filePath) { | ||
| const profileAbsPath = resolve(dirname(filePath), config.profile_path); | ||
| config.ds_profile = parseProfile(readFileSync(profileAbsPath, "utf-8")); | ||
| if (existsSync(profileAbsPath)) { | ||
| config.ds_profile = parseProfile(readFileSync(profileAbsPath, "utf-8")); | ||
| } | ||
| else { | ||
| process.stderr.write(`[cdf-core] profile_path '${config.profile_path}' set in ${filePath} ` + | ||
| `but file does not exist (${profileAbsPath}); ds_profile not loaded.\n`); | ||
| } | ||
| } | ||
@@ -24,0 +35,0 @@ return config; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../../src/parser/config-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,SAAS,CAAC,WAAW,CAAc,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAEpC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACvE,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"} | ||
| {"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../../src/parser/config-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,SAAS,CAAC,WAAW,CAAc,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAEpC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACvE,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4BAA4B,MAAM,CAAC,YAAY,YAAY,QAAQ,GAAG;gBACpE,4BAA4B,cAAc,6BAA6B,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"} |
+1
-1
| { | ||
| "name": "@formtrieb/cdf-core", | ||
| "version": "1.0.2", | ||
| "version": "1.0.3", | ||
| "description": "Core library for the Component Description Format (CDF) — parsing, validation, profile inference, token-tree, and analysis primitives. Pure functions, framework-agnostic.", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
675822
0.4%8661
0.19%