Skip to content

refactor(cli): cover apps/cli/scripts with effect lint (CLI-2853) - #7336

Open
7ttp wants to merge 2 commits into
developfrom
7ttp/cli-2853-scripts-coverage
Open

7ttp wants to merge 2 commits into
developfrom
7ttp/cli-2853-scripts-coverage

Conversation

@7ttp

@7ttp 7ttp commented Oct 26, 2026

Copy link
Copy Markdown
Member

TL;DR

brings apps/cli/scripts under the effect lint, so the allow list collapses into one !apps/cli/** entry

whats introduced?

  • apps/cli/scripts/** joins the allow list, and the src, tests and vitest.config.ts entries collapse into !apps/cli/**
  • the build, release, publish and docs scripts run as effect programs on FileSystem, HttpClient and Config, with the same arguments, output, error messages, generated files and exit codes
  • a failed run still crashes with the original error, so malformed json keeps its native SyntaxError, and a signal during refresh-e2e-timings still waits for its cleanup
  • the scripts tests move to it.effect and it.live with the same names and assertions

ref

@7ttp 7ttp self-assigned this Oct 26, 2026
@7ttp
7ttp requested a review from a team as a code owner October 26, 2026 17:27

@github-actions github-actions 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.

Superseded by a newer AI review

🤖 AI Review

Adjudicated all seven findings: five confirmed, one refuted, and one uncertain. The cancellation cleanup and tracing gaps are confirmed, alongside three nonblocking nits. The docs publisher's cause-less error scenario remains unverified because platform dependencies are unavailable.

Findings

Severity Location Category Sources Claim
🟡 MINOR apps/cli/scripts/publish-docs-spec.ts:217 error-handling claude The final handler loses the original diagnostic if it receives an error whose cause is undefined.
🟡 MINOR apps/cli/scripts/upload-release-assets.ts:249 resource-lifecycle codex Interrupting the upload effect cancels its termination watchdog without terminating the running subprocess.
🟡 MINOR apps/cli/scripts/build.ts:297 observability codex The migrated aggregate build phases omit the named spans required by the repository's tracing conventions.
⚪ NIT apps/cli/scripts/build.ts:66 consistency claude The migrated scripts inconsistently wrap process.exit calls inside Effect generators.
⚪ NIT apps/cli/scripts/bench-cli.ts:95 maintainability claude parseBenchArgs constructs and runs an Effect layer on every successful parse solely to obtain path resolution.
⚪ NIT apps/cli/scripts/detect-unmirrored-images.ts:161 maintainability claude The subprocess compatibility adapter depends on exact diagnostic strings and mutates the caught host error in place.
Refuted findings (kept for transparency, not posted as review comments)
  • apps/cli/scripts/refresh-e2e-timings.ts:127 (robustness): Following a symlink back to an ancestor makes listRegularFiles run forever and allocate without bound.
    Refuted: The walk retains expanding lexical paths, so an ancestor cycle eventually hits the host's symlink-resolution or path-length limit. The directory-read handler propagates that error and terminates the effect. A read-only host check returned ELOOP after repeated symlink traversals. Repeated traversal is possible, but the claimed infinite walk is not.

Stats

Claude findings: 5 · Codex findings: 2 · Confirmed: 5 · Refuted: 1 · Uncertain: 1


Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: auto · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread apps/cli/scripts/publish-docs-spec.ts Outdated
Comment thread apps/cli/scripts/build.ts
Comment thread apps/cli/scripts/bench-cli.ts
Comment thread apps/cli/scripts/detect-unmirrored-images.ts
Comment thread apps/cli/scripts/upload-release-assets.ts
Comment thread apps/cli/scripts/build.ts
@7ttp

7ttp commented Oct 26, 2026

Copy link
Copy Markdown
Member Author

/ai-review

@github-actions github-actions 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.

🤖 AI Review

Verified all six findings from both independent reviews. Confirmed one minor subprocess cancellation leak and two consistency/duplication nits; refuted three findings with code and convention evidence. No critical or major findings were confirmed. Effect runtime tests were unavailable because dependencies are absent.

Findings

Severity Location Category Sources Claim
🟡 MINOR apps/cli/scripts/upload-release-assets.ts:240 resource-management codex Interrupting createSpawnRun cancels its watchdog without terminating the subprocess, allowing gh to continue uploading after the caller stops.
⚪ NIT apps/cli/scripts/build.ts:260 consistency claude The migration leaves direct throws and process.exit calls inside Effect generators, unlike the typed failures and Effect.sync exits used in other converted scripts.
⚪ NIT apps/cli/scripts/apply-release-notes.ts:51 maintainability claude The same thrownValue helper is duplicated across numerous scripts, spreading maintenance of their shared top-level error conversion.
Refuted findings (kept for transparency, not posted as review comments)
  • apps/cli/scripts/refresh-e2e-timings.ts:155 (correctness): Symlink cycles make listRegularFiles run forever and grow its queue without bound because it never records visited directories.
    Refuted: The missing visited set is real, but the claimed infinite traversal is not. The walker passes full paths to filesystem operations; repeated symlink traversal eventually produces ELOOP or a path-length error. Lines 138-145 do not suppress those errors, so the listing fails. A read-only filesystem probe also verified ELOOP on repeated symlink traversal.
  • apps/cli/scripts/detect-unmirrored-images.ts:265 (robustness): The separately computed first-probe count can diverge from partitionUnmirroredImages' fan-out and permanently hang failure reporting.
    Refuted: The current counts match exactly: main passes the same images without overriding registries, mirrorImageTargets maps each registry once, and partitionUnmirroredImages does not deduplicate targets or short-circuit probes. The ensuring block counts failed first probes too. The proposed mismatch requires a future implementation change; no current mismatch was found.
  • apps/cli/scripts/bench-cli.ts:96 (readability): Building and running BunPath.layer synchronously just to resolve benchmark paths is unnecessary indirection that should move into main or use node:path directly.
    Refuted: This bridge preserves the existing synchronous parser API and its absolute-path behavior while following the trusted requirement to express runtime operations through Effect. Lines 99-102 explain why paths must resolve before launches change cwd. The finding establishes neither incorrect behavior nor material overhead, and its direct node:path alternative conflicts with the documented convention.

Stats

Claude findings: 5 · Codex findings: 1 · Confirmed: 3 · Refuted: 3 · Uncertain: 0


Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread apps/cli/scripts/build.ts
Comment thread apps/cli/scripts/apply-release-notes.ts
Comment thread apps/cli/scripts/upload-release-assets.ts

This branch has not been deployed

No deployments
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