Skip to content

feat: add yarn workspace command with smart filter routing - #226

Closed
denneulin wants to merge 7 commits into
rtk-ai:masterfrom
denneulin:feat/yarn-cmd
Closed

denneulin wants to merge 7 commits into
rtk-ai:masterfrom
denneulin:feat/yarn-cmd

Conversation

@denneulin

Copy link
Copy Markdown

Summary

Add rtk yarn workspace <pkg> [run] <script> command that strips yarn boilerplate and routes script output
through existing specialized filters for maximum token savings.

  • Boilerplate stripping: Removes YN-prefixed info lines, resolution/fetch/link progress, yarn classic
    headers (yarn run v1.x, Done in Xs, info lines). Returns ok ✓ when output is pure boilerplate.
  • Smart filter routing: Routes workspace scripts to existing RTK filters based on script name:
    • vitest → vitest parser, tsc/typecheck → tsc filter, lint/lint:* → generic lint filter,
      prettier/format → prettier filter, test/test:* → test runner summary
    • Prefix exclusions prevent misrouting (test:e2e, test:playwright, test:cypress, lint:fix
      passthrough)
  • Graceful degradation: catch_unwind on filter panics, empty-output guard, fallback to stripped output
    with stderr warning
  • Early-exit on failure: When yarn itself fails (non-zero exit), outputs stripped stderr/stdout directly
    without routing through filters (prevents error masking)

Changes

File Change
src/yarn_cmd.rs New module (704 lines): filter_yarn_output(), route_script(), apply_filter(),
run() + 25 tests
src/main.rs Register Commands::Yarn with trailing_var_arg + 5 Clap parsing tests
src/lint_cmd.rs filter_generic_lint: fn → pub(crate)
src/runner.rs extract_test_summary: fn → pub(crate)
src/tsc_cmd.rs filter_tsc_output: fn → pub(crate)

Test plan

  • cargo fmt --all --check passes
  • cargo clippy --all-targets passes
  • cargo test --all passes (30+ new tests)
  • Manual: rtk yarn workspace <pkg> run vitest on a real yarn workspace project
  • Manual: rtk yarn workspace <pkg> run typecheck with typecheck not existing

denneulin and others added 7 commits February 20, 2026 00:40
…plate filtering

- Add yarn_cmd.rs with run() for workspace command execution
- Implement filter_yarn_output() stripping YN-prefixed, resolution/fetch/link, classic boilerplate
- Add 7 unit tests covering clean output, YN prefix, resolution steps, empty, classic, mixed, and token savings
- Add mod yarn_cmd declaration in main.rs for compilation
- Follow npm_cmd pattern: capture output, filter stdout, pass stderr, track tokens, tee on failure, preserve exit codes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… parsing tests

- Add mod yarn_cmd declaration (alphabetical after wget_cmd)
- Add Commands::Yarn variant with trailing_var_arg and allow_hyphen_values
- Add match arm routing to yarn_cmd::run() with verbose and skip_env
- Add 5 Clap parsing tests: basic, scoped package with slash, without run, extra args, simple package

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ross-module access

- Make filter_tsc_output pub(crate) in tsc_cmd.rs
- Make filter_generic_lint pub(crate) in lint_cmd.rs
- Make extract_test_summary pub(crate) in runner.rs
- Add FilterRoute enum, PREFIX_EXCLUSIONS, route_script(), apply_filter() to yarn_cmd.rs
- apply_filter includes panic catch_unwind and empty-output guard for graceful degradation
…with tracking labels and tests

- Replace passthrough-only filtering with capture+strip+route+filter pattern
- Add "ok checkmark" guard to skip routing when all output is boilerplate
- Routing-aware tracking labels: "vitest (via yarn workspace)" for routed, "yarn workspace (passthrough)" for unrouted
- Add 11 comprehensive tests: 4 routing, 5 apply_filter integration, 1 guard, 1 end-to-end
- Fix clippy suggestion: use PREFIX_EXCLUSIONS.contains() instead of iter().any()
- Check exit code after command execution, before filter routing
- Failed yarn commands now print raw stdout/stderr without filter processing
- Tee raw output and track with "(failed)" label on failure path
- Move exit_code extraction before routing to share variable with safety net
- Prevents misleading "TypeScript compilation completed" on yarn errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test_failed_command_should_not_route_to_filter: proves tsc filter masks yarn errors without early-exit
- test_successful_command_still_routes_through_filters: verifies happy path (strip/route/filter) is unchanged
- 20 yarn_cmd tests total (18 existing + 2 new), full suite 437 pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pszymkowiak

Copy link
Copy Markdown
Collaborator

Review: PR #226

Thanks for this PR! The FilterRoute enum and early-exit on failure are well designed. I tested against a real Yarn 1.x workspace.

Bugs found

1. Non-workspace commands brokenrtk yarn install, add, list, why all fail with usage error. Fix: passthrough for non-workspace args (like pnpm_cmd.rs).

2. Boilerplate leakswarning ..., yarn workspace v1.22.22, $ vitest run not stripped. Regex ^yarn run v\d misses yarn workspace v\d.

3. Vitest routing brokenroute_script("test") → generic TestRunner → OUTPUT (last 5 lines) fallback. Same issue as #232: script name doesn't identify the tool.

4. Double stderr — Line 290 prints filtered output, line 293 prints raw stderr again on top.

5. Subcommand interceptionrtk yarn workspace app add lodash runs yarn run add instead of yarn add. Need a denylist of native yarn subcommands.

Minor

Architecture is solid, just needs these fixes. Happy to re-review!

ThomasHoussin added a commit to ThomasHoussin/rtk that referenced this pull request Mar 5, 2026
Implements `rtk yarn` with:
- Workspace path: `rtk yarn workspace <pkg> [run] <script>` strips yarn
  boilerplate and routes to specialized filters (vitest, tsc, lint, prettier)
- Non-workspace path: `rtk yarn test/lint/typecheck` routes to filters too,
  native commands (install, add, why...) passthrough directly
- Compound scripts (test:lib, lint:check) route by prefix with safe fallback
- Boilerplate stripping: YN prefixes, resolution steps, headers, warnings,
  script echoes, Done lines
- Exit code preservation, separate stdout/stderr handling, graceful degradation

Based on PR rtk-ai#226 (denneulin) architecture, rebased on rtk-ai#241 (rtk rewrite).
Integrates all 5 review fixes from rtk-ai#226.

42 unit tests + 3 registry rewrite tests. 73 registry tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ThomasHoussin

Copy link
Copy Markdown

Hi @denneulin - I opened #317 as a clean rewrite of your yarn workspace support, rebased on #241 (rtk rewrite architecture). Your original implementation was the foundation - I integrated all 5 review fixes and extended it with non-workspace filter routing (rtk yarn test/lint route to specialized filters), compound script routing (test:lib, lint:check route by prefix with safe fallback), and registry integration for rtk rewrite/discover. The PR depends on #241 merging first. Happy to coordinate if you want to review or have feedback.

@FlorianBruniaux

Copy link
Copy Markdown
Contributor

Hi @ThomasHoussin, @dlmw, @denneulin! You've each opened yarn-related PRs (#317, #272, #226) that all create yarn_cmd.rs — they'll conflict with each other. Could you coordinate? @ThomasHoussin's #317 is the most comprehensive, so we're thinking of using it as the base. @dlmw, @denneulin — could you check if your specific additions (vitest support, workspace support) could be contributed to #317 instead, or if #317 already covers them?

ThomasHoussin added a commit to ThomasHoussin/rtk that referenced this pull request Mar 5, 2026
Implements `rtk yarn` with:
- Workspace path: `rtk yarn workspace <pkg> [run] <script>` strips yarn
  boilerplate and routes to specialized filters (vitest, tsc, lint, prettier)
- Non-workspace path: `rtk yarn test/lint/typecheck` routes to filters too,
  native commands (install, add, why...) passthrough directly
- Compound scripts (test:lib, lint:check) route by prefix with safe fallback
- Boilerplate stripping: YN prefixes, resolution steps, headers, warnings,
  script echoes, Done lines
- Exit code preservation, separate stdout/stderr handling, graceful degradation

Based on PR rtk-ai#226 (denneulin) architecture, rebased on rtk-ai#241 (rtk rewrite).
Integrates all 5 review fixes from rtk-ai#226.

42 unit tests + 3 registry rewrite tests. 73 registry tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@pszymkowiak

Copy link
Copy Markdown
Collaborator

Hi! Two things needed before we can review:

  1. Retarget to develop — this PR targets master, but all PRs should target develop. You can change the base branch in the PR settings (right sidebar).
  2. Sign the CLA — if not already done, please sign at https://cla-assistant.io/rtk-ai/rtk

Thanks!

@aeppling

Copy link
Copy Markdown
Contributor

Hey

We are cleaning up the codebase and improving the project structure for better onboarding. As part of this effort, PR #826 reorganizes src/ from a flat layout into subfolders.

No logic changes — only file moves and import path updates.

What you need to do

Rebase your branch on develop when receiving this comment:

git fetch origin && git rebase origin/develop

Git detects renames automatically. If you get import conflicts, update the paths:

use crate::git;        // now: use crate::cmds::git::git;
use crate::tracking;   // now: use crate::core::tracking;
use crate::config;     // now: use crate::core::config;
use crate::init;       // now: use crate::hooks::init;
use crate::gain;       // now: use crate::analytics::gain;

Need help rebasing? Tag @aeppling

@ThomasHoussin

Copy link
Copy Markdown

I rebased #317, which I think covers #226 and #272. I think we could close both #226 and #272 and adjust #317 if necessary.

@pszymkowiak

Copy link
Copy Markdown
Collaborator

Hi @denneulin — closing per @ThomasHoussin's request on 2026-03-30:
his #317 rebased your work onto develop (post-#826 layout refactor),
integrated the 5 review fixes from above, and extended to non-workspace
yarn commands. He explicitly asked to close #226 and #272 in favor of
his consolidated branch.

Your original implementation was the foundation — the FilterRoute
enum and the early-exit-on-failure design carried over to #317. Thanks
for the work that started the conversation.

If you want to follow the merge, #317 is the active thread.

Closing as superseded by #317.

thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
…-ai#232, rtk-ai#233)

Filter-engine cluster, authored by the codex (gpt-5.6) worker:

- rtk-ai#226 whole-blob ANSI/OSC state-machine sanitisation (drops unterminated
  OSC/DCS incl. across line breaks); CTXCRL_TOML_DEBUG logs a redacted
  name/fingerprint not the raw command; AggressiveFilter counts the
  signature brace (no early body exit leaking later secrets); hard
  UTF-8-safe byte ceiling before allocation.
- rtk-ai#232 language-aware stripping: Go receiver signatures, JS/TS template
  literals + raw strings in block-comment scanning, Python raw/f/'''
  docstrings.
- rtk-ai#233 user TOML-filter regex bounded (size/compile limits, ReDoS); total
  byte ceiling on many-small-lines; filter-trust EnvOverride audited.

Refs: rtk-ai#226 rtk-ai#232 rtk-ai#233

Co-Authored-By: Codex (gpt-5.6-sol) <noreply@openai.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
Large security release completing the codex-5.6-max sweep + 5-voice
council audit (rtk-ai#210-rtk-ai#233): rtk-ai#219/rtk-ai#220 (hook-tamper validation rebuild +
trust store), rtk-ai#225 (non-Claude handler gating), rtk-ai#212-rtk-ai#218/rtk-ai#230
(permission gate + lexer), rtk-ai#211 (Tirith deadlock), rtk-ai#222 (config
injection), rtk-ai#226/rtk-ai#232/rtk-ai#233 (filter engine). The two big clusters were
authored by the Codex worker in isolated worktrees, driver-verified and
non-author-council-reviewed. See CHANGELOG.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants