@outputai/cli 0.14.1-next.5381b5e.0 → 0.14.1-next.6a7a07a.0

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.
@@ -80,7 +80,7 @@ services:
80
80
  condition: service_healthy
81
81
  worker:
82
82
  condition: service_healthy
83
- image: outputai/api:${OUTPUT_API_VERSION:-0.14.1-next.5381b5e.0}
83
+ image: outputai/api:${OUTPUT_API_VERSION:-0.14.1-next.6a7a07a.0}
84
84
  init: true
85
85
  networks:
86
86
  - main
@@ -1,3 +1,3 @@
1
1
  {
2
- "framework": "0.14.1-next.5381b5e.0"
2
+ "framework": "0.14.1-next.6a7a07a.0"
3
3
  }
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import yaml from 'js-yaml';
3
+ import { load as parseYaml } from 'js-yaml';
4
4
  const ARRAY_ACCESS_PATTERN = /^(\w+)\[(\d+)\]$/;
5
5
  function tokenCost(tokens, pricePerMillion) {
6
6
  return (tokens / 1_000_000) * pricePerMillion;
@@ -144,7 +144,7 @@ export function extractValue(obj, path) {
144
144
  }, obj);
145
145
  }
146
146
  function loadYaml(filePath) {
147
- return yaml.load(readFileSync(filePath, 'utf-8'));
147
+ return parseYaml(readFileSync(filePath, 'utf-8'));
148
148
  }
149
149
  export function loadPricingConfig(configPath) {
150
150
  const bundledPath = new URL('../assets/config/costs.yml', import.meta.url).pathname;
@@ -7,7 +7,7 @@ vi.mock('node:fs', () => ({
7
7
  }));
8
8
  const mockLoad = vi.fn();
9
9
  vi.mock('js-yaml', () => ({
10
- default: { load: (...args) => mockLoad(...args) }
10
+ load: (...args) => mockLoad(...args)
11
11
  }));
12
12
  import { extractValue, findLLMCalls, findHTTPCalls, identifyService, calculateServiceCost, calculateCost, loadPricingConfig } from '#services/cost_calculator.js';
13
13
  // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  import { readFile, writeFile, readdir, mkdir } from 'node:fs/promises';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { resolve, join } from 'node:path';
4
- import yaml from 'js-yaml';
4
+ import { load as parseYaml, dump as stringifyYaml } from 'js-yaml';
5
5
  import { DatasetSchema } from '@outputai/evals';
6
6
  import { getTrace } from '#services/trace_reader.js';
7
7
  import { sanitizeSecrets } from '#utils/secret_sanitizer.js';
@@ -27,7 +27,7 @@ export async function resolveDefaultDatasetsDir(workflowName, basePath, workflow
27
27
  return resolve(basePath ?? getWorkflowsBasePath(), WORKFLOWS_PATHS[0], workflowName, DATASETS_DIR);
28
28
  }
29
29
  export async function readDatasetFile(filePath) {
30
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
30
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
31
31
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
32
32
  throw new Error(`Invalid dataset file: ${filePath}`);
33
33
  }
@@ -69,13 +69,13 @@ export async function writeDataset(dataset, filePath) {
69
69
  if (!existsSync(dir)) {
70
70
  await mkdir(dir, { recursive: true });
71
71
  }
72
- const loaded = existsSync(filePath) ? yaml.load(await readFile(filePath, 'utf-8')) : null;
72
+ const loaded = existsSync(filePath) ? parseYaml(await readFile(filePath, 'utf-8')) : null;
73
73
  const fileObj = (loaded && typeof loaded === 'object' && !Array.isArray(loaded)) ?
74
74
  loaded :
75
75
  {};
76
76
  const { name, _source, ...caseBody } = dataset;
77
77
  fileObj[name] = { ...fileObj[name], ...caseBody };
78
- await writeFile(filePath, yaml.dump(fileObj, { lineWidth: 120, noRefs: true, sortKeys: false }), 'utf-8');
78
+ await writeFile(filePath, stringifyYaml(fileObj, { lineWidth: 120, noRefs: true, sortKeys: false }), 'utf-8');
79
79
  }
80
80
  export async function listDatasets(workflowName, basePath) {
81
81
  const dir = await resolveDatasetsDir(workflowName, basePath);
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
2
  import { mkdtemp, rm, writeFile, readFile, mkdir } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
- import yaml from 'js-yaml';
5
+ import { load as parseYaml, dump as stringifyYaml } from 'js-yaml';
6
6
  import { readDatasetFile, readAllDatasets, writeDataset, listDatasets, resolveDefaultDatasetsDir, datasetFilePath } from './datasets.js';
7
7
  import * as catalog from '#api/workflow_catalog.js';
8
8
  vi.mock('#api/workflow_catalog.js', () => ({
@@ -20,7 +20,7 @@ afterEach(async () => {
20
20
  await rm(ctx.tmpDir, { recursive: true, force: true });
21
21
  });
22
22
  function writeYaml(filePath, obj) {
23
- return writeFile(filePath, yaml.dump(obj, { lineWidth: 120, noRefs: true, sortKeys: false }), 'utf-8');
23
+ return writeFile(filePath, stringifyYaml(obj, { lineWidth: 120, noRefs: true, sortKeys: false }), 'utf-8');
24
24
  }
25
25
  // ---------------------------------------------------------------------------
26
26
  // readDatasetFile
@@ -142,7 +142,7 @@ describe('writeDataset', () => {
142
142
  const filePath = join(ctx.tmpDir, 'cases.yml');
143
143
  const dataset = { name: 'new_case', input: { q: 'hello' } };
144
144
  await writeDataset(dataset, filePath);
145
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
145
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
146
146
  expect(raw).toHaveProperty('new_case');
147
147
  expect(raw.new_case.input).toEqual({ q: 'hello' });
148
148
  expect(raw.new_case).not.toHaveProperty('name');
@@ -151,7 +151,7 @@ describe('writeDataset', () => {
151
151
  const filePath = join(ctx.tmpDir, 'cases.yml');
152
152
  const dataset = { name: 'my_case', input: { q: 'x' }, _source: '/some/path.yml' };
153
153
  await writeDataset(dataset, filePath);
154
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
154
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
155
155
  expect(raw.my_case).not.toHaveProperty('_source');
156
156
  });
157
157
  it('updates only the target case, leaving other cases untouched', async () => {
@@ -161,7 +161,7 @@ describe('writeDataset', () => {
161
161
  case_b: { input: { x: 2 }, ground_truth: { expected: 2 } }
162
162
  });
163
163
  await writeDataset({ name: 'case_a', input: { x: 1 }, last_output: { output: { result: 1 }, date: '2026-01-01T00:00:00.000Z' } }, filePath);
164
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
164
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
165
165
  expect(raw).toHaveProperty('case_b');
166
166
  expect(raw.case_b.ground_truth).toEqual({ expected: 2 });
167
167
  });
@@ -175,7 +175,7 @@ describe('writeDataset', () => {
175
175
  name: 'my_case', input: { q: 'hello' },
176
176
  last_eval: { output: { datasetName: 'my_case', verdict: 'pass', evaluators: [] }, date: '2026-01-01T00:01:00.000Z' }
177
177
  }, filePath);
178
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
178
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
179
179
  const caseObj = raw.my_case;
180
180
  expect(caseObj).toHaveProperty('last_output');
181
181
  expect(caseObj).toHaveProperty('last_eval');
@@ -184,14 +184,14 @@ describe('writeDataset', () => {
184
184
  it('creates parent directories if they do not exist', async () => {
185
185
  const filePath = join(ctx.tmpDir, 'deep', 'nested', 'cases.yml');
186
186
  await writeDataset({ name: 'my_case', input: { q: 'x' } }, filePath);
187
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
187
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
188
188
  expect(raw).toHaveProperty('my_case');
189
189
  });
190
190
  it('recovers gracefully when existing file contains non-object YAML', async () => {
191
191
  const filePath = join(ctx.tmpDir, 'cases.yml');
192
192
  await writeFile(filePath, 'just a string', 'utf-8');
193
193
  await writeDataset({ name: 'my_case', input: { q: 'x' } }, filePath);
194
- const raw = yaml.load(await readFile(filePath, 'utf-8'));
194
+ const raw = parseYaml(await readFile(filePath, 'utf-8'));
195
195
  expect(raw).toHaveProperty('my_case');
196
196
  });
197
197
  });
@@ -1752,5 +1752,5 @@
1752
1752
  ]
1753
1753
  }
1754
1754
  },
1755
- "version": "0.14.1-next.5381b5e.0"
1755
+ "version": "0.14.1-next.6a7a07a.0"
1756
1756
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/cli",
3
- "version": "0.14.1-next.5381b5e.0",
3
+ "version": "0.14.1-next.6a7a07a.0",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "output": "./bin/run.js"
18
18
  },
19
19
  "dependencies": {
20
- "@anthropic-ai/claude-agent-sdk": "0.3.278",
20
+ "@anthropic-ai/claude-agent-sdk": "0.3.281",
21
21
  "@hackylabs/deep-redact": "3.0.5",
22
22
  "@inquirer/prompts": "8.7.2",
23
23
  "@oclif/core": "4.10.6",
@@ -36,9 +36,9 @@
36
36
  "react": "19.3.0",
37
37
  "semver": "7.8.5",
38
38
  "undici": "8.11.0",
39
- "@outputai/core": "0.14.1-next.5381b5e.0",
40
- "@outputai/llm": "0.14.1-next.5381b5e.0",
41
- "@outputai/evals": "0.14.1-next.5381b5e.0"
39
+ "@outputai/evals": "0.14.1-next.6a7a07a.0",
40
+ "@outputai/llm": "0.14.1-next.6a7a07a.0",
41
+ "@outputai/core": "0.14.1-next.6a7a07a.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/cli-progress": "3.11.6",
@@ -47,7 +47,7 @@
47
47
  "@types/react": "19.3.0",
48
48
  "@types/semver": "7.8.0",
49
49
  "oclif": "4.23.10",
50
- "orval": "8.35.0"
50
+ "orval": "8.37.0"
51
51
  },
52
52
  "license": "Apache-2.0",
53
53
  "publishConfig": {