@sweny-ai/core 0.1.19 → 0.1.21

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.
@@ -159,14 +159,36 @@ describe("browser bundle", () => {
159
159
  it("exists in dist", () => {
160
160
  expect(fs.existsSync(browserPath)).toBe(true);
161
161
  });
162
- it("exports match the YAML-loaded workflows", async () => {
162
+ it("triage workflow is deeply equal", async () => {
163
163
  const browser = await import(browserPath);
164
- expect(browser.triageWorkflow.id).toBe(triageWorkflow.id);
165
- expect(browser.triageWorkflow.entry).toBe(triageWorkflow.entry);
166
- expect(Object.keys(browser.triageWorkflow.nodes)).toEqual(Object.keys(triageWorkflow.nodes));
167
- expect(browser.triageWorkflow.edges.length).toBe(triageWorkflow.edges.length);
168
- expect(browser.implementWorkflow.id).toBe(implementWorkflow.id);
169
- expect(Object.keys(browser.implementWorkflow.nodes)).toEqual(Object.keys(implementWorkflow.nodes));
170
- expect(browser.seedContentWorkflow.id).toBe(seedContentWorkflow.id);
164
+ expect(browser.triageWorkflow).toEqual(JSON.parse(JSON.stringify(triageWorkflow)));
165
+ });
166
+ it("implement workflow is deeply equal", async () => {
167
+ const browser = await import(browserPath);
168
+ expect(browser.implementWorkflow).toEqual(JSON.parse(JSON.stringify(implementWorkflow)));
169
+ });
170
+ it("seed-content workflow is deeply equal", async () => {
171
+ const browser = await import(browserPath);
172
+ expect(browser.seedContentWorkflow).toEqual(JSON.parse(JSON.stringify(seedContentWorkflow)));
173
+ });
174
+ it("exports exactly the expected workflow names", async () => {
175
+ const browser = await import(browserPath);
176
+ const exportedKeys = Object.keys(browser).sort();
177
+ expect(exportedKeys).toEqual(["implementWorkflow", "seedContentWorkflow", "triageWorkflow"]);
178
+ });
179
+ });
180
+ // ─── Zod runtime validation ─────────────────────────────────────
181
+ describe("runtime Zod validation in loader", () => {
182
+ it("workflows are Zod-validated at load time (not just cast)", () => {
183
+ // The loader uses workflowZ.parse(), so invalid YAML would throw at import.
184
+ // If we got here, all 3 workflows passed Zod validation at module load.
185
+ // Verify by checking the parsed output has Zod's default-applied fields.
186
+ expect(triageWorkflow.description).toBeDefined();
187
+ expect(implementWorkflow.description).toBeDefined();
188
+ expect(seedContentWorkflow.description).toBeDefined();
189
+ // Zod applies .default([]) to skills arrays — verify it works
190
+ for (const node of Object.values(triageWorkflow.nodes)) {
191
+ expect(Array.isArray(node.skills)).toBe(true);
192
+ }
171
193
  });
172
194
  });
@@ -2,10 +2,12 @@ import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { parse as parseYaml } from "yaml";
5
+ import { workflowZ } from "../schema.js";
5
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
7
  function loadBuiltinWorkflow(filename) {
7
8
  const filePath = path.join(__dirname, filename);
8
- return parseYaml(fs.readFileSync(filePath, "utf-8"));
9
+ const raw = parseYaml(fs.readFileSync(filePath, "utf-8"));
10
+ return workflowZ.parse(raw);
9
11
  }
10
12
  export const triageWorkflow = loadBuiltinWorkflow("triage.yml");
11
13
  export const implementWorkflow = loadBuiltinWorkflow("implement.yml");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweny-ai/core",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sweny": "./dist/cli/main.js"
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "devDependencies": {
58
58
  "@anthropic-ai/claude-code": "^2.1.84",
59
- "vitest": "^3.2.1"
59
+ "vitest": "^4.1.2"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"