Problem
The repo depends on two YAML libraries: js-yaml (4.2.0) and yaml (2.9.0, the eemeli/yaml library). Newer code uses yaml; older modules and some tests still use js-yaml. Carrying two libraries for one job adds dependency surface, splits idioms, and forces contributors to know which one to reach for.
Context
packages/kb is exclusively on yaml and relies on its richer API (parseDocument, isMap/isPair/isScalar/isSeq, CST position tracking), so reverting to js-yaml is not viable. The migration toward yaml is already organically underway: every recently written module uses it. The @eemeli/yaml name (the library's pre-1.0 scoped publication) is unpublished and now 404s on npm; the canonical package is the unscoped yaml.
Remaining js-yaml usage (verified against the branch):
- Source:
packages/agents/src/lib/frontmatter-merger.ts, packages/agents/src/lib/tool-name-rewriter.ts, packages/run-core/src/resolve-base-dir.ts
- Tests:
packages/agents/src/commands/__tests__/install.test.ts, packages/agents/src/lib/__tests__/preferences-schema.test.ts
- Comments that name
js-yaml (no longer accurate after the swap): frontmatter-merger.ts, preferences-schema.test.ts, resolve-base-dir.test.ts
Every call site uses yaml.load only — there are no yaml.dump call sites in scope.
Dependency state differs per package:
packages/agents already declares yaml@2.9.0 → removal-only (drop js-yaml, @types/js-yaml).
packages/run-core declares only js-yaml → must add yaml@2.9.0 and drop js-yaml, @types/js-yaml.
The swap is behavior-preserving here (verified empirically): js-yaml 4.x already parses with YAML 1.2 core-schema semantics, matching yaml; the undefined-vs-null empty-input difference is absorbed by the isRecord() guard at every call site; and the malformed-input catch in resolve-base-dir.ts is error-type-agnostic, so the YAMLException → YAMLParseError change is invisible.
Proposed solution
Replace each yaml.load(x) with yaml's parse(x), using the named-import idiom already established in packages/agents (import { parse as parseYaml } from 'yaml'). Add yaml@2.9.0 to packages/run-core, which currently lacks it; packages/agents already declares it. Remove js-yaml and @types/js-yaml from both package.json files once no imports remain. Refresh the three comments that name js-yaml so they describe the yaml API (or drop the reference). No stringify/dump work is required — no such call sites exist. Confirm the full suite passes.
Acceptance criteria
Must have
Problem
The repo depends on two YAML libraries:
js-yaml(4.2.0) andyaml(2.9.0, the eemeli/yaml library). Newer code usesyaml; older modules and some tests still usejs-yaml. Carrying two libraries for one job adds dependency surface, splits idioms, and forces contributors to know which one to reach for.Context
packages/kbis exclusively onyamland relies on its richer API (parseDocument,isMap/isPair/isScalar/isSeq, CST position tracking), so reverting tojs-yamlis not viable. The migration towardyamlis already organically underway: every recently written module uses it. The@eemeli/yamlname (the library's pre-1.0 scoped publication) is unpublished and now 404s on npm; the canonical package is the unscopedyaml.Remaining
js-yamlusage (verified against the branch):packages/agents/src/lib/frontmatter-merger.ts,packages/agents/src/lib/tool-name-rewriter.ts,packages/run-core/src/resolve-base-dir.tspackages/agents/src/commands/__tests__/install.test.ts,packages/agents/src/lib/__tests__/preferences-schema.test.tsjs-yaml(no longer accurate after the swap):frontmatter-merger.ts,preferences-schema.test.ts,resolve-base-dir.test.tsEvery call site uses
yaml.loadonly — there are noyaml.dumpcall sites in scope.Dependency state differs per package:
packages/agentsalready declaresyaml@2.9.0→ removal-only (dropjs-yaml,@types/js-yaml).packages/run-coredeclares onlyjs-yaml→ must addyaml@2.9.0and dropjs-yaml,@types/js-yaml.The swap is behavior-preserving here (verified empirically):
js-yaml4.x already parses with YAML 1.2 core-schema semantics, matchingyaml; theundefined-vs-nullempty-input difference is absorbed by theisRecord()guard at every call site; and the malformed-inputcatchinresolve-base-dir.tsis error-type-agnostic, so theYAMLException→YAMLParseErrorchange is invisible.Proposed solution
Replace each
yaml.load(x)withyaml'sparse(x), using the named-import idiom already established inpackages/agents(import { parse as parseYaml } from 'yaml'). Addyaml@2.9.0topackages/run-core, which currently lacks it;packages/agentsalready declares it. Removejs-yamland@types/js-yamlfrom bothpackage.jsonfiles once no imports remain. Refresh the three comments that namejs-yamlso they describe theyamlAPI (or drop the reference). Nostringify/dumpwork is required — no such call sites exist. Confirm the full suite passes.Acceptance criteria
Must have
js-yamlimports remain anywhere in the repo (source or tests).js-yamland@types/js-yamlare removed from everypackage.json.yamlis declared as a dependency of every package that imports it (run-coregainsyaml@2.9.0;agentsalready declares it).js-yamlwhere the code no longer uses it.