rtk-ai / rtk-ai/rtk

npm filter buffers stdout until exit, breaking long-running readiness protocols

Open
#3,604 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:cli enhancement help wanted priority:medium
Dominant language
Rust
Stars
81.1k
Forks
5.1k
Avg merge
4d 21h
Merged PRs (30d)
35

Description

Bug description

rtk npm captures child output until the child exits. For a long-running npm script (dev server, watcher, daemon, or parent process that emits a readiness receipt and stays alive), this means the caller cannot observe readiness while the process is running.

This breaks agent orchestration that starts a background service and waits for an early stdout receipt before launching a dependent worker.

Minimal reproduction

package.json:

{
  "private": true,
  "scripts": {
    "ready": "node ready.mjs"
  }
}

ready.mjs:

process.stdout.write(JSON.stringify({ kind: "ready", pid: process.pid }) + "\n");
setInterval(() => {}, 1000);

Run:

rtk npm run --silent ready
Actual

The process remains alive, but no READY JSON is visible to the parent. A background process poll/log remains empty.

Control:

rtk proxy npm run --silent ready

The JSON line is visible immediately while the process remains alive.

PTY allocation does not change the rtk npm behavior.

Environment

  • RTK installed: 0.42.4
  • Current stable source inspected: v0.45.0
  • Linux / Node.js / npm

The current v0.45.0 implementation routes npm through runner::run_filtered(...), and run_captured_filter(...) uses FilterMode::CaptureOnly, emitting filtered output only after run_streaming(...) returns.

Expected behavior

RTK should provide a documented, reliable way to preserve streaming for long-running filtered commands, for example one of:

  • a generic --stream / passthrough option on filtered subcommands;
  • automatic passthrough for explicitly declared long-running mode;
  • hook metadata/routing that selects rtk proxy when the caller launches a background/watch process.

Automatic guessing from npm script names alone would be incomplete because readiness processes can use arbitrary script names.

Current workaround

Use rtk proxy <command> for servers, watch/dev modes, daemons, readiness protocols, and other background processes whose output must be observed before exit.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the npm path through runner::run_filtered(...), then inspect run_captured_filter(...) and run_streaming(...); compare it with the rtk proxy behavior. Reproduce the long-running ready.mjs case and determine how a documented streaming mode should be routed. Done means early stdout is observable while the filtered process remains alive, with coverage for the readiness scenario.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.