Skip to content

silent verify script#282

Open
jasonmorais wants to merge 9 commits into
mainfrom
jason/silent-verify
Open

silent verify script#282
jasonmorais wants to merge 9 commits into
mainfrom
jason/silent-verify

Conversation

@jasonmorais

@jasonmorais jasonmorais commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Introduce a reusable silent verification runner package and wire the root verify workflow through it while keeping successful runs quiet.

New Features:

  • Add the @cellix/local-dev package with silent command runners, verification sequence builder, and tool-specific wrappers for pnpm, audits, Snyk, Sonar, and tests.
  • Add a Node-based verify script that composes the verification sequence using the new local-dev utilities and prints a simple success message only on complete pass.

Bug Fixes:

  • Suppress agent formatter result output entirely when there are no issues, avoiding noisy logs for fully passing runs.

Enhancements:

  • Export a consolidated public API surface from @cellix/local-dev for silent runners and verification helpers.
  • Adjust the agent verification formatter to always log the issue count when there are failures.

Build:

  • Change the root verify npm script to invoke the new TypeScript verify runner instead of a long inline command chain.
  • Register @cellix/local-dev as a workspace package dependency and slightly bump the protobufjs override in the pnpm workspace.

Documentation:

  • Document the @cellix/local-dev package, its silent runner concepts, public API, and usage patterns, and update the repo README formatting around managed skills.
  • Add a manifest file describing the intent, scope, and API shape of @cellix/local-dev.

Tests:

  • Add Vitest-based tests for @cellix/local-dev to validate silent command behavior, failure replay, buffer configuration, and the verify sequence wiring.
  • Introduce a Vitest config and TypeScript configs specific to the @cellix/local-dev package.

@sourcery-ai

sourcery-ai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces a new @cellix/local-dev workspace package that provides silent command runners and typed wrappers around pnpm/knip/audit/Snyk/Sonar tooling, wires the root verify workflow through a new TypeScript verify script built on these runners, silences agent formatter output when there are no issues, and performs minor dependency/workspace/docs updates.

Sequence diagram for TypeScript-based verify workflow using silent runners

sequenceDiagram
    actor Developer
    participant NpmVerify as npm_verify_script
    participant VerifyTs as verify_ts
    participant VerificationSequence
    participant RunSequence as runSilentCommandSequence
    participant RunCommand as runSilentCommand
    participant Tool as External_tool

    Developer->>NpmVerify: pnpm run verify
    NpmVerify->>VerifyTs: node build-pipeline/scripts/verify.ts
    VerifyTs->>VerificationSequence: verificationSequence.addStep(...)+
    VerifyTs->>VerificationSequence: VerificationSequence.run()
    VerificationSequence->>RunSequence: runSilentCommandSequence(steps)

    loop for each step
      RunSequence->>RunCommand: runSilentCommand(SilentCommandOptions)
      RunCommand->>Tool: spawnSync(command, args)
      Tool-->>RunCommand: status, stdout, stderr
      alt status == 0
        RunCommand-->>RunSequence: SilentCommandResult (no output replayed)
      else status != 0
        RunCommand-->>RunSequence: SilentCommandResult
        RunCommand->>Developer: replayFailureOutput(stdout, stderr)
        break loop
          RunSequence-->>VerificationSequence: SilentCommandSequenceResult (failing step)
          VerificationSequence-->>VerifyTs: SilentCommandSequenceResult
          VerifyTs->>Developer: process.exitCode = status
        end
      end
    end

    alt all steps succeed
      RunSequence-->>VerificationSequence: SilentCommandSequenceResult (status 0)
      VerificationSequence-->>VerifyTs: SilentCommandSequenceResult
      VerifyTs->>Developer: write verify passed
      VerifyTs->>Developer: process.exitCode = 0
    end
Loading

File-Level Changes

Change Details Files
Add reusable silent command runner and verification sequence API in @cellix/local-dev, plus wrappers for core tooling (pnpm scripts, audit, knip, Snyk, Sonar) and tests.
  • Implement runSilentCommand and runSilentCommandSequence to capture child-process output, keep successful runs quiet, and replay output on failure with configurable maxBuffer and injectable spawn/streams.
  • Introduce VerificationSequence and verificationSequence fluent builder to compose ordered, stop-on-failure verification workflows with per-step output policies (silent vs inherit).
  • Add typed wrappers for pnpm scripts (including live output variant), pnpm audit, knip, Snyk dependency/code/IaC scans, and Sonar PR/quality-gate scripts that return CommandSequenceStep descriptors.
  • Expose the silent-runner API and tool wrappers through the @cellix/local-dev root index and add Vitest config, TS configs, package.json metadata/scripts, and README/manifest documentation for the new package.
  • Add unit tests covering silent behavior, buffer configuration, sequencing, failure propagation, and fluent sequence immutability using a fake spawn implementation.
packages/cellix/local-dev/src/silent-runners/index.ts
packages/cellix/local-dev/src/silent-runners/pnpm.ts
packages/cellix/local-dev/src/silent-runners/pnpm-audit.ts
packages/cellix/local-dev/src/silent-runners/knip.ts
packages/cellix/local-dev/src/silent-runners/snyk.ts
packages/cellix/local-dev/src/silent-runners/sonar.ts
packages/cellix/local-dev/src/silent-runners/test-runners.ts
packages/cellix/local-dev/src/index.ts
packages/cellix/local-dev/src/index.test.ts
packages/cellix/local-dev/package.json
packages/cellix/local-dev/vitest.config.ts
packages/cellix/local-dev/tsconfig.json
packages/cellix/local-dev/tsconfig.vitest.json
packages/cellix/local-dev/README.md
packages/cellix/local-dev/manifest.md
Wire the root repository verify workflow through the new TypeScript-based verify runner built on @cellix/local-dev silent runners.
  • Replace the existing shell-based package.json verify script command chain with a Node invocation of build-pipeline/scripts/verify.ts using node --conditions=source.
  • Implement build-pipeline/scripts/verify.ts to compose the Cellix verify sequence using pnpmScript, architectureTests, coverageMerge, e2eTests, knipCheck, pnpmAudit, Snyk scans, and Sonar scripts, including Snyk org/remote-repo arguments.
  • Have the verify runner print a single 'verify passed' line on success while leaving underlying tools silent unless they fail, and propagate the final step’s exit status as process.exitCode.
  • Add @cellix/local-dev as a workspace devDependency in the root package.json so the verify script can import silent-runners.
package.json
build-pipeline/scripts/verify.ts
Adjust agent verification formatter to be completely silent when there are no issues instead of printing a 'success' summary.
  • Change AgentFormatter.onTestRunFinished to early-return when issueCount is zero so no banner or summary is logged.
  • Remove the previous conditional logging of 'All scenarios passed.' vs issue count and always log Issues: only when there was at least one issue.
packages/ocom-verification/verification-shared/src/formatters/agent-formatter.ts
Update workspace configuration, overrides, and documentation for the new package and dependency adjustments.
  • Register @cellix/local-dev as a workspace package (implicitly via package.json) and add its build/test/lint scripts and TS/Vitest configs.
  • Bump protobufjs override from 7.6.1 to 7.6.3 in pnpm-workspace.yaml and update pnpm-lock.yaml accordingly.
  • Tidy README formatting around managed skills (add spacing before the managed skills list).
pnpm-workspace.yaml
pnpm-lock.yaml
readme.md
packages/cellix/local-dev/.gitignore
knip.json

Possibly linked issues

  • #unknown: They both aim to make verify commands silent on success using reusable wrappers and a new verify pipeline.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@jasonmorais jasonmorais marked this pull request as ready for review June 22, 2026 15:32
@jasonmorais jasonmorais requested a review from a team June 22, 2026 15:32
@jasonmorais jasonmorais requested a review from a team as a code owner June 22, 2026 15:32

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In AgentFormatter.onTestRunFinished you now return early when issueCount === 0, which removes the previous "All scenarios passed" messaging entirely; if that feedback is still desired, consider keeping a minimal success summary instead of returning silently.
  • The verify.ts script prints a custom failure line after runSilentCommandSequence has already replayed the failing step's stdout/stderr; consider including the step exit status in that replay or adjusting the extra message to avoid redundant-but-slightly-different failure context.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AgentFormatter.onTestRunFinished` you now return early when `issueCount === 0`, which removes the previous "All scenarios passed" messaging entirely; if that feedback is still desired, consider keeping a minimal success summary instead of returning silently.
- The `verify.ts` script prints a custom failure line after `runSilentCommandSequence` has already replayed the failing step's stdout/stderr; consider including the step exit status in that replay or adjusting the extra message to avoid redundant-but-slightly-different failure context.

## Individual Comments

### Comment 1
<location path="build-pipeline/scripts/verify.ts" line_range="29-38" />
<code_context>
+	.addStep(sonarPullRequestAnalysis())
+	.addStep(sonarQualityGate());
+
+const isRunningAsCommand = import.meta.main;
+
+function runVerifyCommand(): void {
+	const result = cellixVerify.run();
+	if (result.status !== 0) {
+		process.stderr.write(`\nverify failed at step "${result.step.name}" (exit ${result.status})\n`);
+	} else {
+		process.stdout.write('verify passed\n');
+	}
+	process.exitCode = result.status;
+}
+
+if (isRunningAsCommand) {
+	runVerifyCommand();
+}
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `import.meta.main` will never trigger in Node.js and prevents the script from running when executed directly.

In Node.js, `import.meta.main` is always `undefined`, so `runVerifyCommand()` never runs, even when this file is invoked as the entry script (e.g. via `pnpm run verify`). Use a Node-compatible check instead, such as comparing `import.meta.url` to `pathToFileURL(process.argv[1]).href`, or invoke `runVerifyCommand()` from a dedicated bootstrap file that always calls it.
</issue_to_address>

### Comment 2
<location path="package.json" line_range="52" />
<code_context>
 		"sonar:pr-windows": "for /f %i in ('node build-pipeline/scripts/get-pr-number.cjs') do set PR_NUMBER=%i && sonar-scanner -Dsonar.pullrequest.key=%PR_NUMBER% -Dsonar.pullrequest.branch=%BRANCH_NAME% -Dsonar.pullrequest.base=main",
 		"check-sonar": "node build-pipeline/scripts/check-sonar-quality-gate.cjs",
-		"verify": "pnpm run format:check && pnpm run test:arch && pnpm run test:coverage:merge && pnpm run test:e2e && pnpm run knip && pnpm run audit && pnpm run snyk && pnpm run sonar:pr && pnpm run check-sonar",
+		"verify": "node build-pipeline/scripts/verify.ts",
 		"knip": "knip",
 		"snyk": "pnpm run snyk:test && pnpm run snyk:code",
</code_context>
<issue_to_address>
**issue (bug_risk):** Running a `.ts` file directly with `node` will fail without a custom loader or precompiled JS.

This script now calls `node build-pipeline/scripts/verify.ts`, but Node can’t run TypeScript directly. Unless there’s an existing loader configured for this command (e.g. `tsx`, `ts-node`, or a custom `--loader`), it will fail at runtime. Consider either targeting the compiled `.js` file or running it via the configured TS runner instead of plain `node`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread build-pipeline/scripts/verify.ts Outdated
Comment thread package.json Outdated
@jasonmorais

Copy link
Copy Markdown
Contributor Author

image For reference

@jasonmorais

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="build-pipeline/scripts/verify.ts" line_range="29-38" />
<code_context>
+	.addStep(sonarPullRequestAnalysis())
+	.addStep(sonarQualityGate());
+
+const isRunningAsCommand = import.meta.main;
+
+function runVerifyCommand(): void {
+	const result = cellixVerify.run();
+	if (result.status !== 0) {
+		process.stderr.write(`\nverify failed at step "${result.step.name}" (exit ${result.status})\n`);
+	} else {
+		process.stdout.write('verify passed\n');
+	}
+	process.exitCode = result.status;
+}
+
+if (isRunningAsCommand) {
+	runVerifyCommand();
+}
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `import.meta.main` is likely non-portable and may prevent the verify script from running when invoked directly.

In Node’s current ESM implementation `import.meta.main` is not available, so `isRunningAsCommand` will be `undefined` and `runVerifyCommand()` will never run, even when you call `node build-pipeline/scripts/verify.ts` directly. To ensure the script actually executes as a CLI, switch to the common pattern of comparing `import.meta.url` with `pathToFileURL(process.argv[1]).href` (or another supported entry-point check).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread build-pipeline/scripts/verify.ts Outdated
@jasonmorais

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new verify.ts script prints verify passed on success, which slightly conflicts with the goal of keeping successful verification runs silent; consider making this success message optional (e.g., behind a flag) or removing it to keep the workflow fully quiet when healthy.
  • The runSilentCommand helper hardcodes a 64MB maxBuffer; if you expect some tools to produce larger output, consider exposing maxBuffer (or a similar option) on SilentCommandOptions so callers can tune this per command.
  • The construction of the cellixVerify sequence in verify.ts is fairly specific and could be reused elsewhere; consider extracting this builder into a small shared helper in @cellix/local-dev (or a nearby module) so local/CI verification flows can share the same sequence definition without duplication.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `verify.ts` script prints `verify passed` on success, which slightly conflicts with the goal of keeping successful verification runs silent; consider making this success message optional (e.g., behind a flag) or removing it to keep the workflow fully quiet when healthy.
- The `runSilentCommand` helper hardcodes a 64MB `maxBuffer`; if you expect some tools to produce larger output, consider exposing `maxBuffer` (or a similar option) on `SilentCommandOptions` so callers can tune this per command.
- The construction of the `cellixVerify` sequence in `verify.ts` is fairly specific and could be reused elsewhere; consider extracting this builder into a small shared helper in `@cellix/local-dev` (or a nearby module) so local/CI verification flows can share the same sequence definition without duplication.

## Individual Comments

### Comment 1
<location path="packages/cellix/local-dev/src/silent-runners/index.ts" line_range="177-186" />
<code_context>
+ * @param options - Sequence steps and optional process context.
+ * @returns The final successful step result or the first failing step result.
+ */
+export function runSilentCommandSequence(options: SilentCommandSequenceOptions): SilentCommandSequenceResult {
+	const { cwd, env, spawn, steps, streams } = options;
+	if (steps.length === 0) {
+		throw new Error('runSilentCommandSequence requires at least one step');
+	}
+
+	let lastResult: SilentCommandSequenceResult | undefined;
+
+	for (const step of steps) {
+		const context: CommandSequenceContext = { cwd, env, spawn, streams };
+		const result = step.output === 'inherit' ? runInheritedCommand(buildCommandOptions(step, context)) : runSilentCommand(buildCommandOptions(step, context));
+		lastResult = {
+			...result,
+			step,
+		};
+
+		if (result.status !== 0) {
+			return lastResult;
+		}
+	}
+
+	if (!lastResult) {
+		throw new Error('runSilentCommandSequence requires at least one step');
+	}
</code_context>
<issue_to_address>
**nitpick:** The `runSilentCommandSequence` empty-steps guard is duplicated and could be simplified.

The function throws `runSilentCommandSequence requires at least one step` both on the initial `steps.length === 0` check and again when `!lastResult` after the loop. Because of the initial check, the post-loop guard is unreachable and can be removed, or you can drop the initial check and rely solely on the `lastResult` check to cover the empty-steps case.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread packages/cellix/local-dev/src/silent-runners/index.ts Outdated
@jasonmorais jasonmorais changed the title initial commit for precommit silent verify script Jun 23, 2026
@jasonmorais

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The new verify runner currently writes verify passed on success, which slightly conflicts with the "silent on success" contract of the silent runners; consider omitting this message so local runs stay fully quiet when healthy.
  • In replayFailureOutput, the stderr replay concatenates the failure banner and the tool stderr without ensuring a trailing newline from the tool output; consider always terminating the combined message with a newline to avoid malformed prompts when the tool's stderr is not newline-terminated.
  • The Snyk helper snykIacScan takes targets as the first argument whereas the other Snyk helpers accept only an options object; consider making its signature consistent (e.g., snykIacScan({ targets, args, name })) to keep the public API uniform.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new verify runner currently writes `verify passed` on success, which slightly conflicts with the "silent on success" contract of the silent runners; consider omitting this message so local runs stay fully quiet when healthy.
- In `replayFailureOutput`, the stderr replay concatenates the failure banner and the tool stderr without ensuring a trailing newline from the tool output; consider always terminating the combined message with a newline to avoid malformed prompts when the tool's stderr is not newline-terminated.
- The Snyk helper `snykIacScan` takes `targets` as the first argument whereas the other Snyk helpers accept only an options object; consider making its signature consistent (e.g., `snykIacScan({ targets, args, name })`) to keep the public API uniform.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant