chatroom-cli 1.29.1 → 1.30.0

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 +193 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10960,6 +10960,168 @@ var init_cursor = __esm(() => {
10960
10960
  init_cursor_agent_service();
10961
10961
  });
10962
10962
 
10963
+ // src/infrastructure/services/remote-agents/copilot/copilot-stream-reader.ts
10964
+ import { createInterface as createInterface3 } from "node:readline";
10965
+
10966
+ class CopilotStreamReader {
10967
+ textCallbacks = [];
10968
+ agentEndCallbacks = [];
10969
+ anyEventCallbacks = [];
10970
+ agentEnded = false;
10971
+ toolCallCallbacks = [];
10972
+ toolResultCallbacks = [];
10973
+ constructor(stream) {
10974
+ const rl = createInterface3({ input: stream, crlfDelay: Infinity });
10975
+ rl.on("line", (line) => this._handleLine(line));
10976
+ }
10977
+ onText(cb) {
10978
+ this.textCallbacks.push(cb);
10979
+ }
10980
+ onAgentEnd(cb) {
10981
+ this.agentEndCallbacks.push(cb);
10982
+ }
10983
+ onToolCall(_cb) {}
10984
+ onToolResult(_cb) {}
10985
+ onAnyEvent(cb) {
10986
+ this.anyEventCallbacks.push(cb);
10987
+ }
10988
+ _handleLine(line) {
10989
+ for (const cb of this.anyEventCallbacks)
10990
+ cb();
10991
+ if (line.trim() === DONE_MARKER) {
10992
+ this.agentEnded = true;
10993
+ for (const cb of this.agentEndCallbacks)
10994
+ cb();
10995
+ return;
10996
+ }
10997
+ const trimmed = line.trim();
10998
+ if (!trimmed)
10999
+ return;
11000
+ for (const prefix of SKIP_PREFIXES) {
11001
+ if (trimmed.startsWith(prefix))
11002
+ return;
11003
+ }
11004
+ for (const cb of this.textCallbacks)
11005
+ cb(trimmed);
11006
+ }
11007
+ }
11008
+ var DONE_MARKER = "Done.", SKIP_PREFIXES;
11009
+ var init_copilot_stream_reader = __esm(() => {
11010
+ SKIP_PREFIXES = ["Total usage est:", "API time spent:", "Total session time:", "Total code changes:", "Breakdown by AI model:"];
11011
+ });
11012
+
11013
+ // src/infrastructure/services/remote-agents/copilot/copilot-agent-service.ts
11014
+ var COPILOT_COMMAND = "copilot", DEFAULT_TRIGGER_PROMPT2 = "Please read your system prompt carefully and follow the Getting Started instructions.", CopilotAgentService;
11015
+ var init_copilot_agent_service = __esm(() => {
11016
+ init_base_cli_agent_service();
11017
+ init_copilot_stream_reader();
11018
+ CopilotAgentService = class CopilotAgentService extends BaseCLIAgentService {
11019
+ id = "copilot";
11020
+ displayName = "GitHub Copilot";
11021
+ command = COPILOT_COMMAND;
11022
+ constructor(deps) {
11023
+ super(deps);
11024
+ }
11025
+ isInstalled() {
11026
+ return this.checkInstalled(COPILOT_COMMAND);
11027
+ }
11028
+ getVersion() {
11029
+ return this.checkVersion(COPILOT_COMMAND);
11030
+ }
11031
+ async listModels() {
11032
+ return [
11033
+ "claude-3-5-sonnet-20241022",
11034
+ "claude-3-5-haiku-20241022",
11035
+ "claude-haiku-4.5",
11036
+ "claude-sonnet-4-6",
11037
+ "claude-opus-4-6",
11038
+ "gpt-4o",
11039
+ "gpt-4o-mini",
11040
+ "gpt-4-turbo",
11041
+ "gemini-3-pro-preview",
11042
+ "gemini-2-5-flash"
11043
+ ];
11044
+ }
11045
+ async spawn(options) {
11046
+ const prompt = options.prompt?.trim() ? options.prompt : DEFAULT_TRIGGER_PROMPT2;
11047
+ const args = ["-p"];
11048
+ args.push("--stream", "on");
11049
+ if (options.model) {
11050
+ args.push("--model", options.model);
11051
+ }
11052
+ args.push("--allow-all");
11053
+ args.push(prompt);
11054
+ const childProcess = this.deps.spawn(COPILOT_COMMAND, args, {
11055
+ cwd: options.workingDir,
11056
+ stdio: ["pipe", "pipe", "pipe"],
11057
+ shell: false,
11058
+ detached: true,
11059
+ env: {
11060
+ ...process.env,
11061
+ GIT_EDITOR: "true",
11062
+ GIT_SEQUENCE_EDITOR: "true"
11063
+ }
11064
+ });
11065
+ await new Promise((resolve) => setTimeout(resolve, 500));
11066
+ if (childProcess.killed || childProcess.exitCode !== null) {
11067
+ throw new Error(`Agent process exited immediately (exit code: ${childProcess.exitCode})`);
11068
+ }
11069
+ if (!childProcess.pid) {
11070
+ throw new Error("Agent process started but has no PID");
11071
+ }
11072
+ const pid = childProcess.pid;
11073
+ const context = options.context;
11074
+ const entry = this.registerProcess(pid, context);
11075
+ const roleTag = context.role ?? "unknown";
11076
+ const chatroomSuffix = context.chatroomId ? `@${context.chatroomId.slice(-6)}` : "";
11077
+ const logPrefix = `[copilot:${roleTag}${chatroomSuffix}]`;
11078
+ const outputCallbacks = [];
11079
+ if (childProcess.stdout) {
11080
+ const reader = new CopilotStreamReader(childProcess.stdout);
11081
+ reader.onText((text) => {
11082
+ process.stdout.write(`${logPrefix} ${text}
11083
+ `);
11084
+ });
11085
+ reader.onAnyEvent(() => {
11086
+ entry.lastOutputAt = Date.now();
11087
+ for (const cb of outputCallbacks)
11088
+ cb();
11089
+ });
11090
+ reader.onAgentEnd(() => {
11091
+ process.stdout.write(`${logPrefix} agent_end
11092
+ `);
11093
+ });
11094
+ }
11095
+ if (childProcess.stderr) {
11096
+ childProcess.stderr.pipe(process.stderr, { end: false });
11097
+ childProcess.stderr.on("data", () => {
11098
+ entry.lastOutputAt = Date.now();
11099
+ for (const cb of outputCallbacks)
11100
+ cb();
11101
+ });
11102
+ }
11103
+ return {
11104
+ pid,
11105
+ onExit: (cb) => {
11106
+ childProcess.on("exit", (code2, signal) => {
11107
+ this.deleteProcess(pid);
11108
+ cb({ code: code2, signal, context });
11109
+ });
11110
+ },
11111
+ onOutput: (cb) => {
11112
+ outputCallbacks.push(cb);
11113
+ }
11114
+ };
11115
+ }
11116
+ };
11117
+ });
11118
+
11119
+ // src/infrastructure/services/remote-agents/copilot/index.ts
11120
+ var init_copilot = __esm(() => {
11121
+ init_copilot_agent_service();
11122
+ init_copilot_stream_reader();
11123
+ });
11124
+
10963
11125
  // src/infrastructure/services/remote-agents/registry.ts
10964
11126
  function registerHarness(service) {
10965
11127
  registry.set(service.id, service);
@@ -10976,7 +11138,7 @@ var init_registry = __esm(() => {
10976
11138
  });
10977
11139
 
10978
11140
  // src/infrastructure/services/remote-agents/claude/claude-stream-reader.ts
10979
- import { createInterface as createInterface3 } from "node:readline";
11141
+ import { createInterface as createInterface4 } from "node:readline";
10980
11142
 
10981
11143
  class ClaudeStreamReader {
10982
11144
  textCallbacks = [];
@@ -10984,7 +11146,7 @@ class ClaudeStreamReader {
10984
11146
  endCallbacks = [];
10985
11147
  toolUseCallbacks = [];
10986
11148
  constructor(stream) {
10987
- const rl = createInterface3({ input: stream, crlfDelay: Infinity });
11149
+ const rl = createInterface4({ input: stream, crlfDelay: Infinity });
10988
11150
  rl.on("line", (line) => {
10989
11151
  if (!line.trim())
10990
11152
  return;
@@ -11037,7 +11199,7 @@ class ClaudeStreamReader {
11037
11199
  var init_claude_stream_reader = () => {};
11038
11200
 
11039
11201
  // src/infrastructure/services/remote-agents/claude/claude-code-agent-service.ts
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;
11202
+ var DEFAULT_TRIGGER_PROMPT3 = "Please read your system prompt carefully and follow the Getting Started instructions.", CLAUDE_COMMAND = "claude", DEFAULT_MAX_TURNS = 200, ClaudeCodeAgentService;
11041
11203
  var init_claude_code_agent_service = __esm(() => {
11042
11204
  init_base_cli_agent_service();
11043
11205
  init_claude_stream_reader();
@@ -11059,7 +11221,7 @@ var init_claude_code_agent_service = __esm(() => {
11059
11221
  }
11060
11222
  async spawn(options) {
11061
11223
  const { systemPrompt, model } = options;
11062
- const prompt = options.prompt?.trim() ? options.prompt : DEFAULT_TRIGGER_PROMPT2;
11224
+ const prompt = options.prompt?.trim() ? options.prompt : DEFAULT_TRIGGER_PROMPT3;
11063
11225
  const args = ["-p", "--output-format", "stream-json", "--verbose"];
11064
11226
  args.push("--max-turns", String(DEFAULT_MAX_TURNS));
11065
11227
  if (model) {
@@ -11197,11 +11359,13 @@ function initHarnessRegistry() {
11197
11359
  registerHarness(new PiAgentService);
11198
11360
  registerHarness(new CursorAgentService);
11199
11361
  registerHarness(new ClaudeCodeAgentService);
11362
+ registerHarness(new CopilotAgentService);
11200
11363
  initialized = true;
11201
11364
  }
11202
11365
  var initialized = false;
11203
11366
  var init_init_registry = __esm(() => {
11204
11367
  init_claude();
11368
+ init_copilot();
11205
11369
  init_cursor();
11206
11370
  init_opencode();
11207
11371
  init_pi();
@@ -11213,6 +11377,7 @@ var init_remote_agents = __esm(() => {
11213
11377
  init_opencode();
11214
11378
  init_pi();
11215
11379
  init_cursor();
11380
+ init_copilot();
11216
11381
  init_registry();
11217
11382
  init_init_registry();
11218
11383
  });
@@ -55461,7 +55626,7 @@ async function scanFileTree(rootDir, options) {
55461
55626
  const maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
55462
55627
  const scannedAt = Date.now();
55463
55628
  const filePaths = await getGitFiles(rootDir);
55464
- const filteredPaths = filePaths.filter((p) => !isExcluded(p));
55629
+ const filteredPaths = filePaths.filter((p) => !isExcluded(p) && !matchesExcludePattern(p));
55465
55630
  const entries = buildEntries(filteredPaths, rootDir, maxEntries);
55466
55631
  return {
55467
55632
  entries,
@@ -55503,6 +55668,9 @@ function isExcluded(filePath) {
55503
55668
  const segments = filePath.split("/");
55504
55669
  return segments.some((segment) => ALWAYS_EXCLUDE.has(segment));
55505
55670
  }
55671
+ function matchesExcludePattern(filePath) {
55672
+ return EXCLUDE_PATTERNS.some((pattern) => pattern.test(filePath));
55673
+ }
55506
55674
  function buildEntries(filePaths, rootDir, maxEntries) {
55507
55675
  const directories = new Set;
55508
55676
  for (const filePath of filePaths) {
@@ -55526,7 +55694,7 @@ function buildEntries(filePaths, rootDir, maxEntries) {
55526
55694
  }
55527
55695
  return entries;
55528
55696
  }
55529
- var execAsync3, DEFAULT_MAX_ENTRIES = 1e4, ALWAYS_EXCLUDE;
55697
+ var execAsync3, DEFAULT_MAX_ENTRIES = 1e4, ALWAYS_EXCLUDE, EXCLUDE_PATTERNS;
55530
55698
  var init_file_tree_scanner = __esm(() => {
55531
55699
  execAsync3 = promisify4(exec4);
55532
55700
  ALWAYS_EXCLUDE = new Set([
@@ -55537,8 +55705,26 @@ var init_file_tree_scanner = __esm(() => {
55537
55705
  ".next",
55538
55706
  "coverage",
55539
55707
  "__pycache__",
55540
- ".turbo"
55708
+ ".turbo",
55709
+ ".cache",
55710
+ ".tmp",
55711
+ "tmp",
55712
+ ".DS_Store"
55541
55713
  ]);
55714
+ EXCLUDE_PATTERNS = [
55715
+ /node_modules/i,
55716
+ /\.git/i,
55717
+ /dist/i,
55718
+ /build/i,
55719
+ /\.next/i,
55720
+ /coverage/i,
55721
+ /__pycache__/i,
55722
+ /\.turbo/i,
55723
+ /\.cache/i,
55724
+ /\.tmp/i,
55725
+ /tmp/i,
55726
+ /\.DS_Store/i
55727
+ ];
55542
55728
  });
55543
55729
 
55544
55730
  // src/commands/machine/daemon-start/file-tree-subscription.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.29.1",
3
+ "version": "1.30.0",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {