chatroom-cli 1.14.1 → 1.14.2

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.
Files changed (2) hide show
  1. package/dist/index.js +146 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10975,10 +10975,72 @@ var init_registry = __esm(() => {
10975
10975
  registry = new Map;
10976
10976
  });
10977
10977
 
10978
+ // src/infrastructure/services/remote-agents/claude/claude-stream-reader.ts
10979
+ import { createInterface as createInterface3 } from "node:readline";
10980
+
10981
+ class ClaudeStreamReader {
10982
+ textCallbacks = [];
10983
+ thinkingCallbacks = [];
10984
+ endCallbacks = [];
10985
+ toolUseCallbacks = [];
10986
+ constructor(stream) {
10987
+ const rl = createInterface3({ input: stream, crlfDelay: Infinity });
10988
+ rl.on("line", (line) => {
10989
+ if (!line.trim())
10990
+ return;
10991
+ try {
10992
+ const event = JSON.parse(line);
10993
+ this.dispatch(event);
10994
+ } catch (err) {}
10995
+ });
10996
+ }
10997
+ onText(cb) {
10998
+ this.textCallbacks.push(cb);
10999
+ }
11000
+ onThinking(cb) {
11001
+ this.thinkingCallbacks.push(cb);
11002
+ }
11003
+ onEnd(cb) {
11004
+ this.endCallbacks.push(cb);
11005
+ }
11006
+ onToolUse(cb) {
11007
+ this.toolUseCallbacks.push(cb);
11008
+ }
11009
+ dispatch(event) {
11010
+ const { type, subtype, message } = event;
11011
+ if (type === "system") {
11012
+ if (subtype === "init") {}
11013
+ return;
11014
+ }
11015
+ if (type === "assistant" && message?.content) {
11016
+ for (const block of message.content) {
11017
+ if (block.type === "text" && block.text) {
11018
+ for (const cb of this.textCallbacks)
11019
+ cb(block.text);
11020
+ } else if (block.type === "thinking" && block.thinking) {
11021
+ for (const cb of this.thinkingCallbacks)
11022
+ cb(block.thinking);
11023
+ } else if (block.type === "tool_use" && block.name && block.input) {
11024
+ for (const cb of this.toolUseCallbacks)
11025
+ cb(block.name, block.input);
11026
+ }
11027
+ }
11028
+ return;
11029
+ }
11030
+ if (type === "result") {
11031
+ for (const cb of this.endCallbacks)
11032
+ cb();
11033
+ return;
11034
+ }
11035
+ }
11036
+ }
11037
+ var init_claude_stream_reader = () => {};
11038
+
10978
11039
  // src/infrastructure/services/remote-agents/claude/claude-code-agent-service.ts
10979
- var CLAUDE_COMMAND = "claude", DEFAULT_MAX_TURNS = 200, ClaudeCodeAgentService;
11040
+ var DEFAULT_TRIGGER_PROMPT2 = "Please read your system prompt carefully and follow the Getting Started instructions.", CLAUDE_COMMAND = "claude", DEFAULT_MAX_TURNS = 200, ClaudeCodeAgentService;
10980
11041
  var init_claude_code_agent_service = __esm(() => {
10981
11042
  init_base_cli_agent_service();
11043
+ init_claude_stream_reader();
10982
11044
  ClaudeCodeAgentService = class ClaudeCodeAgentService extends BaseCLIAgentService {
10983
11045
  id = "claude";
10984
11046
  displayName = "Claude Code";
@@ -10993,14 +11055,12 @@ var init_claude_code_agent_service = __esm(() => {
10993
11055
  return this.checkVersion(CLAUDE_COMMAND);
10994
11056
  }
10995
11057
  async listModels() {
10996
- return [
10997
- "claude-sonnet-4-20250514",
10998
- "claude-opus-4-20250514"
10999
- ];
11058
+ return ["claude-haiku-4-5", "claude-sonnet-4-6", "claude-opus-4-6"];
11000
11059
  }
11001
11060
  async spawn(options) {
11002
- const { systemPrompt, model, prompt } = options;
11003
- const args = ["-p"];
11061
+ const { systemPrompt, model } = options;
11062
+ const prompt = options.prompt?.trim() ? options.prompt : DEFAULT_TRIGGER_PROMPT2;
11063
+ const args = ["-p", "--output-format", "stream-json", "--verbose"];
11004
11064
  args.push("--max-turns", String(DEFAULT_MAX_TURNS));
11005
11065
  if (model) {
11006
11066
  args.push("--model", model);
@@ -11011,7 +11071,7 @@ var init_claude_code_agent_service = __esm(() => {
11011
11071
  args.push(prompt);
11012
11072
  const childProcess = this.deps.spawn(CLAUDE_COMMAND, args, {
11013
11073
  cwd: options.workingDir,
11014
- stdio: ["pipe", "pipe", "pipe"],
11074
+ stdio: ["ignore", "pipe", "pipe"],
11015
11075
  shell: false,
11016
11076
  detached: true,
11017
11077
  env: {
@@ -11030,11 +11090,72 @@ var init_claude_code_agent_service = __esm(() => {
11030
11090
  const pid = childProcess.pid;
11031
11091
  const context = options.context;
11032
11092
  const entry = this.registerProcess(pid, context);
11093
+ const roleTag = context.role ?? "unknown";
11094
+ const chatroomSuffix = context.chatroomId ? `@${context.chatroomId.slice(-6)}` : "";
11095
+ const logPrefix = `[claude:${roleTag}${chatroomSuffix}]`;
11033
11096
  const outputCallbacks = [];
11034
11097
  if (childProcess.stdout) {
11035
- childProcess.stdout.pipe(process.stdout, { end: false });
11036
- childProcess.stdout.on("data", () => {
11098
+ const reader = new ClaudeStreamReader(childProcess.stdout);
11099
+ let textBuffer = "";
11100
+ let thinkingBuffer = "";
11101
+ const flushText = () => {
11102
+ if (!textBuffer)
11103
+ return;
11104
+ for (const line of textBuffer.split(`
11105
+ `)) {
11106
+ if (line)
11107
+ process.stdout.write(`${logPrefix} text] ${line}
11108
+ `);
11109
+ }
11110
+ textBuffer = "";
11111
+ };
11112
+ const flushThinking = () => {
11113
+ if (!thinkingBuffer)
11114
+ return;
11115
+ for (const line of thinkingBuffer.split(`
11116
+ `)) {
11117
+ if (line)
11118
+ process.stdout.write(`${logPrefix} thinking] ${line}
11119
+ `);
11120
+ }
11121
+ thinkingBuffer = "";
11122
+ };
11123
+ reader.onText((text) => {
11124
+ entry.lastOutputAt = Date.now();
11125
+ textBuffer += text;
11126
+ if (text.includes(`
11127
+
11128
+ `) || text.endsWith(`
11129
+ `)) {
11130
+ flushText();
11131
+ }
11132
+ for (const cb of outputCallbacks)
11133
+ cb();
11134
+ });
11135
+ reader.onThinking((thinking) => {
11037
11136
  entry.lastOutputAt = Date.now();
11137
+ thinkingBuffer += thinking;
11138
+ if (thinking.includes(`
11139
+
11140
+ `) || thinking.endsWith(`
11141
+ `)) {
11142
+ flushThinking();
11143
+ }
11144
+ for (const cb of outputCallbacks)
11145
+ cb();
11146
+ });
11147
+ reader.onToolUse((name, input) => {
11148
+ entry.lastOutputAt = Date.now();
11149
+ const inputStr = JSON.stringify(input);
11150
+ process.stdout.write(`${logPrefix} tool] ${name}(${inputStr.slice(0, 100)}${inputStr.length > 100 ? "..." : ""})
11151
+ `);
11152
+ for (const cb of outputCallbacks)
11153
+ cb();
11154
+ });
11155
+ reader.onEnd(() => {
11156
+ entry.lastOutputAt = Date.now();
11157
+ flushText();
11158
+ flushThinking();
11038
11159
  for (const cb of outputCallbacks)
11039
11160
  cb();
11040
11161
  });
@@ -14047,6 +14168,21 @@ async function taskRead(chatroomId, options, deps) {
14047
14168
  }
14048
14169
  console.log(`
14049
14170
  ${result.content}`);
14171
+ if (result.attachedBacklogItems && result.attachedBacklogItems.length > 0) {
14172
+ console.log("");
14173
+ console.log("<attachments>");
14174
+ for (const item of result.attachedBacklogItems) {
14175
+ console.log(` <attachment type="backlog-item">`);
14176
+ console.log(` - [${item.status.toUpperCase()}] ${item.content}`);
14177
+ console.log(` ID: ${item._id}`);
14178
+ console.log(` <hint>`);
14179
+ console.log(` If you have completed work on a backlog item and it is ready for review, run:`);
14180
+ console.log(` chatroom backlog mark-for-review --chatroom-id="${chatroomId}" --role="${role}" --backlog-item-id=${item._id}`);
14181
+ console.log(` </hint>`);
14182
+ console.log(` </attachment>`);
14183
+ }
14184
+ console.log("</attachments>");
14185
+ }
14050
14186
  } catch (error) {
14051
14187
  const err = error;
14052
14188
  console.error(`❌ Failed to read task`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {