Skip to content

v0.9.0 — run-script as a clean Unix filter (ScriptArgs, Stdin, stderr separate)

Choose a tag to compare

@KenM76 KenM76 released this 15 Jun 15:16
· 3 commits to main since this release

Closes TWO FRs that compose into one story:

  • `FR_runscript_script_args.md` — argv channel via `ScriptArgs` global
  • `FR_runscript_stdin_and_stderr_separation.md` — `Stdin` global + stop redirecting `Console.Error` to the output writer

The Args FR had been misfiled to `Complete/` at some point without code actually shipping (verified by repo-wide grep for `ScriptArgs` returning zero matches). v0.9.0 ships both together because they compose: a `.csx` becomes a proper Unix-style stdin → stdout(data) + stderr(diag) filter with argv in and exit code out. The SWBomExcluded ScripTree provider can retire its PowerShell wrapper shim and become plain `combridge solidworks run-script provider.csx -`.

Use it

# ScripTree provider pattern — stdin JSON in, choices JSON out, diagnostics on stderr
echo '{\"target_file\":\"foo.SLDDRW\"}' | combridge solidworks run-script provider.csx --mode quick -

Inside the `.csx`:

using System.Text.Json;

Console.Error.WriteLine($\"[diag] received {Stdin.Length} bytes on stdin, {ScriptArgs.Length} args\");
var req = JsonSerializer.Deserialize<ProviderRequest>(Stdin);
// ... build choices ...
Console.WriteLine(JsonSerializer.Serialize(new { choices, choice_labels }));
return 0;

Same channels work in `.vbs` — `ScriptArgs(0)` and `Stdin`.

The hang trap caught during smoke-test

Naive `if (Console.IsInputRedirected) ReadToEndAsync()` hangs forever when stdin is inherited-but-empty (combridge invoked from bash subprocesses, Task Scheduler, CI runners). `IsInputRedirected` returns `true` for "non-terminal" — NOT "has data available." Fixed with a cancellation-token timeout pattern. Captured as `personal_rag/claude_code/lesson_20260615_console_isinputredirected_inherited_handle_hang.md` for the next implementer.

Verified

All four smoke tests pass end-to-end:

# Test Result
1 ScriptArgs (no pipe) 5 args parsed, no hang, 250 ms wall clock
2 Real stdin pipe 66 bytes received cleanly
3 stderr split STDOUT to ``, STDERR to real stderr
4 Full filter clean JSON on stdout, diag on stderr, args + stdin

See `CHANGELOG.md` v0.9.0 entry for full implementation detail and the IScriptContext interface design.