@klaudworks/rmr 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10104,6 +10104,9 @@ function getHarnessAdapter(name) {
10104
10104
  return adapter;
10105
10105
  }
10106
10106
 
10107
+ // src/lib/process-runner.ts
10108
+ import { spawn } from "node:child_process";
10109
+
10107
10110
  // node_modules/chalk/source/vendor/ansi-styles/index.js
10108
10111
  var ANSI_BACKGROUND_OFFSET = 10;
10109
10112
  var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
@@ -10822,25 +10825,6 @@ var ui = {
10822
10825
  };
10823
10826
 
10824
10827
  // src/lib/process-runner.ts
10825
- async function consumeStream(stream, onText) {
10826
- if (!stream) {
10827
- return "";
10828
- }
10829
- const reader = stream.getReader();
10830
- const decoder = new TextDecoder;
10831
- let fullText = "";
10832
- while (true) {
10833
- const { done, value } = await reader.read();
10834
- if (done) {
10835
- break;
10836
- }
10837
- const chunk = decoder.decode(value, { stream: true });
10838
- fullText += chunk;
10839
- onText(chunk);
10840
- }
10841
- fullText += decoder.decode();
10842
- return fullText;
10843
- }
10844
10828
  function formatToolInput(toolInput) {
10845
10829
  try {
10846
10830
  const parsed = JSON.parse(toolInput);
@@ -10858,95 +10842,83 @@ function formatToolInput(toolInput) {
10858
10842
  return toolInput.length > 100 ? toolInput.slice(0, 97) + "..." : toolInput;
10859
10843
  }
10860
10844
  }
10861
- async function consumeStreamParsed(stream, parser) {
10862
- if (!stream) {
10863
- return { rawOutput: "", displayText: "", sessionId: null };
10864
- }
10865
- const reader = stream.getReader();
10866
- const decoder = new TextDecoder;
10867
- let rawOutput = "";
10868
- let displayText = "";
10869
- let sessionId = null;
10870
- let lineBuf = "";
10871
- let lastTextWasContent = false;
10872
- function processLine(line) {
10873
- const parsed = parser(line);
10874
- if (!parsed) {
10875
- return;
10876
- }
10877
- if (parsed.toolName) {
10878
- if (lastTextWasContent) {
10879
- process.stderr.write(`
10845
+ async function runHarnessCommand(command, parseStreamLine) {
10846
+ return new Promise((resolve5, reject) => {
10847
+ const child = spawn(command.binary, command.args, {
10848
+ stdio: ["ignore", "pipe", "pipe"]
10849
+ });
10850
+ child.on("error", (err) => {
10851
+ if (err.code === "ENOENT") {
10852
+ reject(new StorageError(`Harness binary "${command.binary}" not found. ` + `Make sure it is installed and available on your PATH.`));
10853
+ } else if (err.code === "EACCES") {
10854
+ reject(new StorageError(`Permission denied when trying to run "${command.binary}". ` + `Check that the binary is executable.`));
10855
+ } else {
10856
+ reject(new StorageError(`Failed to launch harness binary "${command.binary}": ${err.message}`));
10857
+ }
10858
+ });
10859
+ let interrupted = false;
10860
+ const onSigint = () => {
10861
+ interrupted = true;
10862
+ };
10863
+ process.on("SIGINT", onSigint);
10864
+ let displayText = "";
10865
+ let sessionId = null;
10866
+ let stderrText = "";
10867
+ let stdoutLineBuf = "";
10868
+ let lastTextWasContent = false;
10869
+ function processLine(line) {
10870
+ const parsed = parseStreamLine(line);
10871
+ if (!parsed) {
10872
+ return;
10873
+ }
10874
+ if (parsed.toolName) {
10875
+ if (lastTextWasContent) {
10876
+ process.stderr.write(`
10880
10877
  `);
10881
- lastTextWasContent = false;
10878
+ lastTextWasContent = false;
10879
+ }
10880
+ const inputDisplay = parsed.toolInput ? formatToolInput(parsed.toolInput) : "";
10881
+ ui.printToolCall(parsed.toolName, inputDisplay);
10882
+ }
10883
+ if (parsed.text) {
10884
+ displayText += parsed.text;
10885
+ ui.content(parsed.text);
10886
+ lastTextWasContent = true;
10887
+ }
10888
+ if (parsed.sessionId) {
10889
+ sessionId = parsed.sessionId;
10882
10890
  }
10883
- const inputDisplay = parsed.toolInput ? formatToolInput(parsed.toolInput) : "";
10884
- ui.printToolCall(parsed.toolName, inputDisplay);
10885
- }
10886
- if (parsed.text) {
10887
- displayText += parsed.text;
10888
- ui.content(parsed.text);
10889
- lastTextWasContent = true;
10890
- }
10891
- if (parsed.sessionId) {
10892
- sessionId = parsed.sessionId;
10893
- }
10894
- }
10895
- while (true) {
10896
- const { done, value } = await reader.read();
10897
- if (done) {
10898
- break;
10899
10891
  }
10900
- const chunk = decoder.decode(value, { stream: true });
10901
- rawOutput += chunk;
10902
- lineBuf += chunk;
10903
- const lines = lineBuf.split(`
10892
+ child.stdout.on("data", (chunk) => {
10893
+ const text = chunk.toString();
10894
+ stdoutLineBuf += text;
10895
+ const lines = stdoutLineBuf.split(`
10904
10896
  `);
10905
- lineBuf = lines.pop() ?? "";
10906
- for (const line of lines) {
10907
- processLine(line);
10908
- }
10909
- }
10910
- rawOutput += decoder.decode();
10911
- if (lineBuf.trim()) {
10912
- processLine(lineBuf);
10913
- }
10914
- return { rawOutput, displayText, sessionId };
10915
- }
10916
- async function runHarnessCommand(command, parseStreamLine) {
10917
- let processRef;
10918
- try {
10919
- processRef = Bun.spawn({
10920
- cmd: [command.binary, ...command.args],
10921
- stdin: "ignore",
10922
- stdout: "pipe",
10923
- stderr: "pipe"
10897
+ stdoutLineBuf = lines.pop() ?? "";
10898
+ for (const line of lines) {
10899
+ processLine(line);
10900
+ }
10901
+ });
10902
+ child.stderr.on("data", (chunk) => {
10903
+ const text = chunk.toString();
10904
+ stderrText += text;
10905
+ process.stderr.write(text);
10906
+ });
10907
+ child.on("close", (code) => {
10908
+ if (stdoutLineBuf.trim()) {
10909
+ processLine(stdoutLineBuf);
10910
+ }
10911
+ process.removeListener("SIGINT", onSigint);
10912
+ const exitCode = interrupted && code === 0 ? 130 : code ?? 1;
10913
+ resolve5({
10914
+ exitCode,
10915
+ stdout: displayText,
10916
+ stderr: stderrText,
10917
+ combinedOutput: `${displayText}${stderrText}`,
10918
+ sessionId
10919
+ });
10924
10920
  });
10925
- } catch {
10926
- throw new StorageError(`Failed to launch harness binary "${command.binary}".`);
10927
- }
10928
- let interrupted = false;
10929
- const onSigint = () => {
10930
- interrupted = true;
10931
- };
10932
- process.on("SIGINT", onSigint);
10933
- const stdoutPromise = consumeStreamParsed(processRef.stdout, parseStreamLine);
10934
- const stderrPromise = consumeStream(processRef.stderr, (chunk) => {
10935
- process.stderr.write(chunk);
10936
10921
  });
10937
- const [exitCode, stdoutResult, stderr] = await Promise.all([
10938
- processRef.exited,
10939
- stdoutPromise,
10940
- stderrPromise
10941
- ]);
10942
- process.removeListener("SIGINT", onSigint);
10943
- return {
10944
- exitCode: interrupted && exitCode === 0 ? 130 : exitCode,
10945
- stdout: stdoutResult.displayText,
10946
- stderr,
10947
- combinedOutput: `${stdoutResult.displayText}${stderr}`,
10948
- sessionId: stdoutResult.sessionId
10949
- };
10950
10922
  }
10951
10923
 
10952
10924
  // src/lib/rmr-output-parser.ts
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@klaudworks/rex",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@klaudworks/rex",
9
- "version": "0.4.4",
9
+ "version": "0.4.5",
10
10
  "dependencies": {
11
11
  "clipanion": "^4.0.0-rc.4",
12
12
  "yaml": "^2.8.2"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klaudworks/rmr",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Define multi-step coding workflows for AI agents",
5
5
  "repository": {
6
6
  "type": "git",