chatroom-cli 1.27.0 → 1.29.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 +245 -41
  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
  });
@@ -51816,23 +51981,13 @@ async function completeBacklog(chatroomId, options, deps) {
51816
51981
  return;
51817
51982
  }
51818
51983
  try {
51819
- const result = await d.backend.mutation(api.tasks.completeTaskById, {
51984
+ const result = await d.backend.mutation(api.backlog.completeBacklogItem, {
51820
51985
  sessionId,
51821
- taskId: options.backlogItemId,
51822
- force: options.force
51986
+ itemId: options.backlogItemId
51823
51987
  });
51824
51988
  console.log("");
51825
- if (result.wasForced) {
51826
- console.log("⚠️ Backlog item force-completed (was in_progress or pending)");
51827
- } else {
51828
- console.log("✅ Backlog item completed");
51829
- }
51989
+ console.log("✅ Backlog item completed");
51830
51990
  console.log(` ID: ${options.backlogItemId}`);
51831
- if (result.promoted) {
51832
- console.log(` \uD83D\uDCE4 Next task promoted: ${result.promoted}`);
51833
- console.log("");
51834
- console.log("\uD83D\uDCA1 The next queued task is now pending and ready for processing.");
51835
- }
51836
51991
  console.log("");
51837
51992
  } catch (error) {
51838
51993
  console.error(`❌ Failed to complete backlog item: ${getErrorMessage(error)}`);
@@ -55471,7 +55626,7 @@ async function scanFileTree(rootDir, options) {
55471
55626
  const maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
55472
55627
  const scannedAt = Date.now();
55473
55628
  const filePaths = await getGitFiles(rootDir);
55474
- const filteredPaths = filePaths.filter((p) => !isExcluded(p));
55629
+ const filteredPaths = filePaths.filter((p) => !isExcluded(p) && !matchesExcludePattern(p));
55475
55630
  const entries = buildEntries(filteredPaths, rootDir, maxEntries);
55476
55631
  return {
55477
55632
  entries,
@@ -55513,6 +55668,9 @@ function isExcluded(filePath) {
55513
55668
  const segments = filePath.split("/");
55514
55669
  return segments.some((segment) => ALWAYS_EXCLUDE.has(segment));
55515
55670
  }
55671
+ function matchesExcludePattern(filePath) {
55672
+ return EXCLUDE_PATTERNS.some((pattern) => pattern.test(filePath));
55673
+ }
55516
55674
  function buildEntries(filePaths, rootDir, maxEntries) {
55517
55675
  const directories = new Set;
55518
55676
  for (const filePath of filePaths) {
@@ -55536,7 +55694,7 @@ function buildEntries(filePaths, rootDir, maxEntries) {
55536
55694
  }
55537
55695
  return entries;
55538
55696
  }
55539
- var execAsync3, DEFAULT_MAX_ENTRIES = 1e4, ALWAYS_EXCLUDE;
55697
+ var execAsync3, DEFAULT_MAX_ENTRIES = 1e4, ALWAYS_EXCLUDE, EXCLUDE_PATTERNS;
55540
55698
  var init_file_tree_scanner = __esm(() => {
55541
55699
  execAsync3 = promisify4(exec4);
55542
55700
  ALWAYS_EXCLUDE = new Set([
@@ -55547,8 +55705,26 @@ var init_file_tree_scanner = __esm(() => {
55547
55705
  ".next",
55548
55706
  "coverage",
55549
55707
  "__pycache__",
55550
- ".turbo"
55708
+ ".turbo",
55709
+ ".cache",
55710
+ ".tmp",
55711
+ "tmp",
55712
+ ".DS_Store"
55551
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
+ ];
55552
55728
  });
55553
55729
 
55554
55730
  // src/commands/machine/daemon-start/file-tree-subscription.ts
@@ -56854,34 +57030,61 @@ function createDefaultDeps21() {
56854
57030
  agentProcessManager: null
56855
57031
  };
56856
57032
  }
56857
- function validateAuthentication(convexUrl) {
57033
+ async function waitForAuthentication(convexUrl) {
57034
+ const startTime = Date.now();
57035
+ while (Date.now() - startTime < AUTH_WAIT_TIMEOUT_MS) {
57036
+ await new Promise((resolve5) => setTimeout(resolve5, AUTH_POLL_INTERVAL_MS2));
57037
+ const sessionId = getSessionId();
57038
+ if (sessionId) {
57039
+ console.log(`
57040
+ ✅ Authentication detected. Resuming daemon initialization...`);
57041
+ return sessionId;
57042
+ }
57043
+ }
57044
+ console.error(`
57045
+ ❌ Authentication timeout (5 minutes). Exiting.`);
57046
+ releaseLock();
57047
+ process.exit(1);
57048
+ }
57049
+ async function validateAuthentication(convexUrl) {
56858
57050
  const sessionId = getSessionId();
56859
- if (!sessionId) {
56860
- const otherUrls = getOtherSessionUrls();
56861
- console.error(`❌ Not authenticated for: ${convexUrl}`);
56862
- if (otherUrls.length > 0) {
56863
- console.error(`
57051
+ if (sessionId) {
57052
+ return sessionId;
57053
+ }
57054
+ const otherUrls = getOtherSessionUrls();
57055
+ console.error(`❌ Not authenticated for: ${convexUrl}`);
57056
+ if (otherUrls.length > 0) {
57057
+ console.error(`
56864
57058
  \uD83D\uDCA1 You have sessions for other environments:`);
56865
- for (const url2 of otherUrls) {
56866
- console.error(` • ${url2}`);
56867
- }
57059
+ for (const url2 of otherUrls) {
57060
+ console.error(` • ${url2}`);
56868
57061
  }
56869
- console.error(`
56870
- Run: chatroom auth login`);
56871
- releaseLock();
56872
- process.exit(1);
56873
57062
  }
56874
- return sessionId;
57063
+ console.error(`
57064
+ Run: chatroom auth login`);
57065
+ console.log(`
57066
+ ⏳ Waiting for authentication (timeout: 5 minutes)...`);
57067
+ return waitForAuthentication(convexUrl);
56875
57068
  }
56876
57069
  async function validateSession(client2, sessionId, convexUrl) {
56877
57070
  const validation = await client2.query(api.cliAuth.validateSession, { sessionId });
56878
- if (!validation.valid) {
56879
- console.error(`❌ Session invalid: ${validation.reason}`);
56880
- console.error(`
57071
+ if (validation.valid) {
57072
+ return sessionId;
57073
+ }
57074
+ console.error(`❌ Session invalid: ${validation.reason}`);
57075
+ console.error(`
56881
57076
  Run: chatroom auth login`);
57077
+ console.log(`
57078
+ ⏳ Waiting for re-authentication (timeout: 5 minutes)...`);
57079
+ const newSessionId2 = await waitForAuthentication(convexUrl);
57080
+ const typedNewSession = newSessionId2;
57081
+ const revalidation = await client2.query(api.cliAuth.validateSession, { sessionId: typedNewSession });
57082
+ if (!revalidation.valid) {
57083
+ console.error(`❌ New session is also invalid: ${revalidation.reason}`);
56882
57084
  releaseLock();
56883
57085
  process.exit(1);
56884
57086
  }
57087
+ return typedNewSession;
56885
57088
  }
56886
57089
  function setupMachine() {
56887
57090
  ensureMachineRegistered();
@@ -56959,12 +57162,12 @@ async function initDaemon() {
56959
57162
  process.exit(1);
56960
57163
  }
56961
57164
  const convexUrl = getConvexUrl();
56962
- const sessionId = validateAuthentication(convexUrl);
57165
+ const sessionId = await validateAuthentication(convexUrl);
56963
57166
  const client2 = await getConvexClient();
56964
- const typedSessionId = sessionId;
57167
+ let typedSessionId = sessionId;
56965
57168
  while (true) {
56966
57169
  try {
56967
- await validateSession(client2, typedSessionId, convexUrl);
57170
+ typedSessionId = await validateSession(client2, typedSessionId, convexUrl);
56968
57171
  const config3 = setupMachine();
56969
57172
  const { machineId } = config3;
56970
57173
  initHarnessRegistry();
@@ -57016,7 +57219,7 @@ async function initDaemon() {
57016
57219
  }
57017
57220
  }
57018
57221
  }
57019
- var CONNECTION_RETRY_INTERVAL_MS = 1000;
57222
+ var AUTH_POLL_INTERVAL_MS2 = 2000, AUTH_WAIT_TIMEOUT_MS, CONNECTION_RETRY_INTERVAL_MS = 1000;
57020
57223
  var init_init2 = __esm(() => {
57021
57224
  init_state_recovery();
57022
57225
  init_api3();
@@ -57033,6 +57236,7 @@ var init_init2 = __esm(() => {
57033
57236
  init_convex_error();
57034
57237
  init_version();
57035
57238
  init_pid();
57239
+ AUTH_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
57036
57240
  });
57037
57241
 
57038
57242
  // src/events/lifecycle/on-daemon-shutdown.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.27.0",
3
+ "version": "1.29.2",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {