@sweny-ai/core 0.1.173 → 0.1.175

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.
package/dist/cli/main.js CHANGED
@@ -39,6 +39,7 @@ import { JournalLockedError, JournalMismatchError, RunJournal, runSecretValues }
39
39
  import { journalDisabled, prepareResume, RESUME_SHARED_RUN_FLAGS, WORKFLOW_RESUME_OPTIONS, } from "./resume.js";
40
40
  import { runE2eRun, runWithWallClockBudget, DEFAULT_WORKFLOW_TIMEOUT_MS } from "./e2e.js";
41
41
  import { createVerboseToolObserver } from "./verbose-observer.js";
42
+ import { createStreamObserver } from "./stream-observer.js";
42
43
  import { createRunLogger, summarizeRun, writeStepSummary, WORKFLOW_RUN_DESCRIPTION, WORKFLOW_RUN_OPTIONS, } from "./run-output.js";
43
44
  import { writeRunComment } from "./comment-output.js";
44
45
  import { writeReceipt } from "./ticket.js";
@@ -56,15 +57,9 @@ import { beginCloudLifecycle, finishCloudLifecycle, createCloudStreamObserver }
56
57
  import { runUpgrade, fetchLatestFromNpm } from "./upgrade.js";
57
58
  import { maybeNudge, defaultCachePath } from "./version-check.js";
58
59
  import { spawnSync } from "node:child_process";
59
- // ── Stream observer (NDJSON) ────────────────────────────────────────
60
- /**
61
- * Create an observer that writes NDJSON ExecutionEvents to stdout.
62
- * Studio and other consumers parse these line-by-line.
63
- */
64
- function createStreamObserver() {
65
- return (event) => {
66
- process.stdout.write(JSON.stringify(event) + "\n");
67
- };
60
+ /** Secret values a run can see, for redacting everything that prints node output. */
61
+ function outputSecrets(skills) {
62
+ return runSecretValues([...(skills?.values() ?? []), ...builtinSkills], process.env);
68
63
  }
69
64
  // Verbose tool-detail observer lives in ./verbose-observer.ts so tests can
70
65
  // import it without triggering main.ts's top-level CLI parser.
@@ -446,7 +441,7 @@ triageCmd.action(async (options) => {
446
441
  if (cloudHandle?.dashboardUrl) {
447
442
  console.log(c.subtle(` cloud: ${cloudHandle.dashboardUrl}`));
448
443
  }
449
- const observer = composeObservers(progressObserver, config.verbose ? createVerboseToolObserver() : undefined, config.stream ? createStreamObserver() : undefined, createCloudStreamObserver(config, cloudHandle));
444
+ const observer = composeObservers(progressObserver, config.verbose ? createVerboseToolObserver() : undefined, config.stream ? createStreamObserver(outputSecrets(skills)) : undefined, createCloudStreamObserver(config, cloudHandle));
450
445
  // #365: pin safe outputs to the configured tracker and repo; nodes these
451
446
  // providers cannot run read-only or through safe outputs keep their old shape.
452
447
  const triageRun = bindForCli(triageWorkflow, config);
@@ -466,7 +461,7 @@ triageCmd.action(async (options) => {
466
461
  const durationMs = Date.now() - runStart;
467
462
  // Output
468
463
  if (config.json) {
469
- await writeResultJson(results);
464
+ await writeResultJson(results, outputSecrets(skills));
470
465
  }
471
466
  else {
472
467
  console.log(formatDagResultHuman(results, durationMs, config));
@@ -654,7 +649,7 @@ implementCmd.action(async (issueId, options) => {
654
649
  if (implCloudHandle?.dashboardUrl) {
655
650
  console.log(c.subtle(` cloud: ${implCloudHandle.dashboardUrl}`));
656
651
  }
657
- const observer = composeObservers(implProgressObserver, config.verbose ? createVerboseToolObserver() : undefined, Boolean(options.stream) ? createStreamObserver() : undefined, createCloudStreamObserver(config, implCloudHandle));
652
+ const observer = composeObservers(implProgressObserver, config.verbose ? createVerboseToolObserver() : undefined, Boolean(options.stream) ? createStreamObserver(outputSecrets(skills)) : undefined, createCloudStreamObserver(config, implCloudHandle));
658
653
  const implementRun = bindForCli(implementWorkflow, config);
659
654
  try {
660
655
  const { results } = await execute(implementRun, workflowInput, {
@@ -681,7 +676,7 @@ implementCmd.action(async (issueId, options) => {
681
676
  // silent
682
677
  }
683
678
  if (config.json) {
684
- await writeResultJson(results);
679
+ await writeResultJson(results, outputSecrets(skills));
685
680
  }
686
681
  if (hasFailed) {
687
682
  console.error(chalk.red(`\n Implement workflow failed\n`));
@@ -1023,7 +1018,7 @@ resume) {
1023
1018
  // history must never fail a run
1024
1019
  }
1025
1020
  };
1026
- const observer = composeObservers(wfProgressObserver, nodeTimer.observer, options.verbose ? createVerboseToolObserver() : undefined, options.stream ? createStreamObserver() : undefined, createCloudStreamObserver(config, wfCloudHandle));
1021
+ const observer = composeObservers(wfProgressObserver, nodeTimer.observer, options.verbose ? createVerboseToolObserver() : undefined, options.stream ? createStreamObserver(outputSecrets(skills)) : undefined, createCloudStreamObserver(config, wfCloudHandle));
1027
1022
  // #325: this is the primary run path (GitHub Action / CLI / MCP all land
1028
1023
  // here), and previously never passed signal/timeoutMs/max_steps to
1029
1024
  // execute() at all: a wedged node (hung tool call, runaway model turn)
@@ -1077,7 +1072,7 @@ resume) {
1077
1072
  });
1078
1073
  }
1079
1074
  if (isJson) {
1080
- await writeResultJson(results);
1075
+ await writeResultJson(results, outputSecrets(skills));
1081
1076
  process.exit(wfHasFailed ? 1 : 0);
1082
1077
  return;
1083
1078
  }
@@ -24,9 +24,13 @@ export declare function formatValidationErrors(errors: string[]): string;
24
24
  export declare function extractCredentialHint(err: unknown): string | null;
25
25
  export declare function formatCrashError(error: unknown): string;
26
26
  export declare function formatCheckResults(results: CheckResult[]): string;
27
- export declare function formatResultJson(results: Map<string, NodeResult>): string;
27
+ /**
28
+ * Node results as JSON, redacted with the run journal's redactor (secret
29
+ * values, secret-named fields, known token shapes). Structure and keys stay.
30
+ */
31
+ export declare function formatResultJson(results: Map<string, NodeResult>, secrets?: string[]): string;
28
32
  /** Drain terminal JSON before process.exit(), including when stdout is a pipe. */
29
- export declare function writeResultJson(results: Map<string, NodeResult>): Promise<void>;
33
+ export declare function writeResultJson(results: Map<string, NodeResult>, secrets?: string[]): Promise<void>;
30
34
  /**
31
35
  * Format triage results as GitHub-flavored markdown for `$GITHUB_STEP_SUMMARY`.
32
36
  *
@@ -1,4 +1,5 @@
1
1
  import chalk from "chalk";
2
+ import { redact } from "../journal.js";
2
3
  import { toMermaidBlock } from "../mermaid.js";
3
4
  import { PALETTE, ROLE_COLORS } from "../theme.js";
4
5
  // ── Color palette (tokens from theme.ts; one color per meaning) ─
@@ -404,13 +405,17 @@ export function formatCheckResults(results) {
404
405
  ].join("\n");
405
406
  }
406
407
  // ── JSON output ─────────────────────────────────────────────────
407
- export function formatResultJson(results) {
408
- return JSON.stringify(Object.fromEntries(results), null, 2);
408
+ /**
409
+ * Node results as JSON, redacted with the run journal's redactor (secret
410
+ * values, secret-named fields, known token shapes). Structure and keys stay.
411
+ */
412
+ export function formatResultJson(results, secrets = []) {
413
+ return JSON.stringify(redact(Object.fromEntries(results), secrets).value, null, 2);
409
414
  }
410
415
  /** Drain terminal JSON before process.exit(), including when stdout is a pipe. */
411
- export function writeResultJson(results) {
416
+ export function writeResultJson(results, secrets = []) {
412
417
  return new Promise((resolve, reject) => {
413
- process.stdout.write(formatResultJson(results) + "\n", (error) => {
418
+ process.stdout.write(formatResultJson(results, secrets) + "\n", (error) => {
414
419
  if (error)
415
420
  reject(error);
416
421
  else
@@ -0,0 +1,10 @@
1
+ import type { Observer } from "../types.js";
2
+ /**
3
+ * Observer that writes NDJSON ExecutionEvents to stdout (`--stream`).
4
+ * Studio and other consumers parse these line-by-line.
5
+ *
6
+ * Every event goes through the run journal's redactor first (secret values,
7
+ * secret-named fields, known token shapes): node data, summaries, errors,
8
+ * tool inputs and outputs. Keys and structure are untouched.
9
+ */
10
+ export declare function createStreamObserver(secrets?: string[], write?: (line: string) => void): Observer;
@@ -0,0 +1,14 @@
1
+ import { redact } from "../journal.js";
2
+ /**
3
+ * Observer that writes NDJSON ExecutionEvents to stdout (`--stream`).
4
+ * Studio and other consumers parse these line-by-line.
5
+ *
6
+ * Every event goes through the run journal's redactor first (secret values,
7
+ * secret-named fields, known token shapes): node data, summaries, errors,
8
+ * tool inputs and outputs. Keys and structure are untouched.
9
+ */
10
+ export function createStreamObserver(secrets = [], write = (line) => void process.stdout.write(line)) {
11
+ return (event) => {
12
+ write(JSON.stringify(redact(event, secrets).value) + "\n");
13
+ };
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweny-ai/core",
3
- "version": "0.1.173",
3
+ "version": "0.1.175",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sweny": "./dist/cli/main.js"
@@ -58,7 +58,8 @@
58
58
  "typecheck": "tsc --noEmit",
59
59
  "test": "vitest run --exclude 'src/__tests__/integration/**' --exclude 'dist/**'",
60
60
  "test:integration": "vitest run --config vitest.integration.config.ts",
61
- "check:schema-drift": "node scripts/write-public-schema.mjs && git diff --exit-code -- ../../spec/public/schemas/workflow.json ../../spec/public/schemas/skill.json"
61
+ "check:schema-drift": "node scripts/write-public-schema.mjs && git diff --exit-code -- ../../spec/public/schemas/workflow.json ../../spec/public/schemas/skill.json",
62
+ "mutation": "stryker run"
62
63
  },
63
64
  "dependencies": {
64
65
  "@anthropic-ai/claude-agent-sdk": "^0.3.220",
@@ -71,6 +72,8 @@
71
72
  },
72
73
  "devDependencies": {
73
74
  "@anthropic-ai/claude-code": "^2.1.220",
75
+ "@stryker-mutator/core": "^10.0.0",
76
+ "@stryker-mutator/vitest-runner": "^10.0.0",
74
77
  "ajv": "^8.20.0",
75
78
  "esbuild": "^0.28.1",
76
79
  "fast-check": "^3.23.2",