chatroom-cli 1.26.0 → 1.29.1

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 +99 -60
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -51816,23 +51816,13 @@ async function completeBacklog(chatroomId, options, deps) {
51816
51816
  return;
51817
51817
  }
51818
51818
  try {
51819
- const result = await d.backend.mutation(api.tasks.completeTaskById, {
51819
+ const result = await d.backend.mutation(api.backlog.completeBacklogItem, {
51820
51820
  sessionId,
51821
- taskId: options.backlogItemId,
51822
- force: options.force
51821
+ itemId: options.backlogItemId
51823
51822
  });
51824
51823
  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
- }
51824
+ console.log("✅ Backlog item completed");
51830
51825
  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
51826
  console.log("");
51837
51827
  } catch (error) {
51838
51828
  console.error(`❌ Failed to complete backlog item: ${getErrorMessage(error)}`);
@@ -54351,7 +54341,8 @@ async function getOriginRepoSlug(cwd) {
54351
54341
  async function getOpenPRsForBranch(cwd, branch) {
54352
54342
  const repoSlug = await getOriginRepoSlug(cwd);
54353
54343
  const repoFlag = repoSlug ? ` --repo ${JSON.stringify(repoSlug)}` : "";
54354
- const result = await runCommand(`gh pr list --head ${JSON.stringify(branch)} --state open --json number,title,url,headRefName,state --limit 5${repoFlag}`, cwd);
54344
+ const repoOwner = repoSlug?.split("/")[0] ?? null;
54345
+ const result = await runCommand(`gh pr list --head ${JSON.stringify(branch)} --state open --author @me --json number,title,url,headRefName,state,headRepositoryOwner --limit 5${repoFlag}`, cwd);
54355
54346
  if ("error" in result) {
54356
54347
  return [];
54357
54348
  }
@@ -54362,7 +54353,11 @@ async function getOpenPRsForBranch(cwd, branch) {
54362
54353
  const parsed = JSON.parse(output);
54363
54354
  if (!Array.isArray(parsed))
54364
54355
  return [];
54365
- return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.number === "number" && typeof item.title === "string" && typeof item.url === "string" && typeof item.headRefName === "string" && typeof item.state === "string").map((item) => ({
54356
+ return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.number === "number" && typeof item.title === "string" && typeof item.url === "string" && typeof item.headRefName === "string" && typeof item.state === "string").filter((item) => {
54357
+ if (!repoOwner || !item.headRepositoryOwner?.login)
54358
+ return true;
54359
+ return item.headRepositoryOwner.login === repoOwner;
54360
+ }).map((item) => ({
54366
54361
  number: item.number,
54367
54362
  title: item.title,
54368
54363
  url: item.url,
@@ -54525,6 +54520,7 @@ var init_git_reader = __esm(() => {
54525
54520
 
54526
54521
  // src/commands/machine/daemon-start/git-subscription.ts
54527
54522
  import { exec as exec3 } from "child_process";
54523
+ import { gzipSync } from "node:zlib";
54528
54524
  import { promisify as promisify3 } from "util";
54529
54525
  function startGitRequestSubscription(ctx, wsClient2) {
54530
54526
  const processedRequestIds = new Map;
@@ -54569,21 +54565,24 @@ async function processFullDiff(ctx, req) {
54569
54565
  if (result.status === "available" || result.status === "truncated") {
54570
54566
  const diffStatResult = await getDiffStat(req.workingDir);
54571
54567
  const diffStat = diffStatResult.status === "available" ? diffStatResult.diffStat : { filesChanged: 0, insertions: 0, deletions: 0 };
54572
- await ctx.deps.backend.mutation(api.workspaces.upsertFullDiff, {
54568
+ const compressed = gzipSync(Buffer.from(result.content));
54569
+ const diffContentCompressed = compressed.toString("base64");
54570
+ await ctx.deps.backend.mutation(api.workspaces.upsertFullDiffV2, {
54573
54571
  sessionId: ctx.sessionId,
54574
54572
  machineId: ctx.machineId,
54575
54573
  workingDir: req.workingDir,
54576
- diffContent: result.content,
54574
+ data: { compression: "gzip", content: diffContentCompressed },
54577
54575
  truncated: result.truncated,
54578
54576
  diffStat
54579
54577
  });
54580
- console.log(`[${formatTimestamp()}] \uD83D\uDCC4 Full diff pushed: ${req.workingDir} (${diffStat.filesChanged} files, ${result.truncated ? "truncated" : "complete"})`);
54578
+ console.log(`[${formatTimestamp()}] \uD83D\uDCC4 Full diff pushed: ${req.workingDir} (${diffStat.filesChanged} files, ${(Buffer.byteLength(result.content) / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB gzip, ${result.truncated ? "truncated" : "complete"})`);
54581
54579
  } else {
54582
- await ctx.deps.backend.mutation(api.workspaces.upsertFullDiff, {
54580
+ const emptyCompressed = gzipSync(Buffer.from("")).toString("base64");
54581
+ await ctx.deps.backend.mutation(api.workspaces.upsertFullDiffV2, {
54583
54582
  sessionId: ctx.sessionId,
54584
54583
  machineId: ctx.machineId,
54585
54584
  workingDir: req.workingDir,
54586
- diffContent: "",
54585
+ data: { compression: "gzip", content: emptyCompressed },
54587
54586
  truncated: false,
54588
54587
  diffStat: { filesChanged: 0, insertions: 0, deletions: 0 }
54589
54588
  });
@@ -54697,7 +54696,7 @@ async function processCommitDetail(ctx, req) {
54697
54696
  getCommitMetadata(req.workingDir, req.sha)
54698
54697
  ]);
54699
54698
  if (result.status === "not_found") {
54700
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54699
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54701
54700
  sessionId: ctx.sessionId,
54702
54701
  machineId: ctx.machineId,
54703
54702
  workingDir: req.workingDir,
@@ -54710,7 +54709,7 @@ async function processCommitDetail(ctx, req) {
54710
54709
  return;
54711
54710
  }
54712
54711
  if (result.status === "error") {
54713
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54712
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54714
54713
  sessionId: ctx.sessionId,
54715
54714
  machineId: ctx.machineId,
54716
54715
  workingDir: req.workingDir,
@@ -54724,20 +54723,22 @@ async function processCommitDetail(ctx, req) {
54724
54723
  return;
54725
54724
  }
54726
54725
  const diffStat = extractDiffStatFromShowOutput(result.content);
54727
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54726
+ const compressed = gzipSync(Buffer.from(result.content));
54727
+ const diffContentCompressed = compressed.toString("base64");
54728
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54728
54729
  sessionId: ctx.sessionId,
54729
54730
  machineId: ctx.machineId,
54730
54731
  workingDir: req.workingDir,
54731
54732
  sha: req.sha,
54732
54733
  status: "available",
54733
- diffContent: result.content,
54734
+ data: { compression: "gzip", content: diffContentCompressed },
54734
54735
  truncated: result.truncated,
54735
54736
  message: metadata?.message,
54736
54737
  author: metadata?.author,
54737
54738
  date: metadata?.date,
54738
54739
  diffStat
54739
54740
  });
54740
- console.log(`[${formatTimestamp()}] \uD83D\uDD0D Commit detail pushed: ${req.sha.slice(0, 7)} in ${req.workingDir}`);
54741
+ console.log(`[${formatTimestamp()}] \uD83D\uDD0D Commit detail pushed: ${req.sha.slice(0, 7)} in ${req.workingDir} (${(Buffer.byteLength(result.content) / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB gzip)`);
54741
54742
  }
54742
54743
  async function processMoreCommits(ctx, req) {
54743
54744
  const offset = req.offset ?? 0;
@@ -54913,7 +54914,7 @@ async function prefetchMissingCommitDetails(ctx, workingDir, commits) {
54913
54914
  if (commits.length === 0)
54914
54915
  return;
54915
54916
  const shas = commits.map((c) => c.sha);
54916
- const missingShas = await ctx.deps.backend.query(api.workspaces.getMissingCommitShas, {
54917
+ const missingShas = await ctx.deps.backend.query(api.workspaces.getMissingCommitShasV2, {
54917
54918
  sessionId: ctx.sessionId,
54918
54919
  machineId: ctx.machineId,
54919
54920
  workingDir,
@@ -54934,7 +54935,7 @@ async function prefetchSingleCommit(ctx, workingDir, sha, commits) {
54934
54935
  const metadata = commits.find((c) => c.sha === sha);
54935
54936
  const result = await getCommitDetail(workingDir, sha);
54936
54937
  if (result.status === "not_found") {
54937
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54938
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54938
54939
  sessionId: ctx.sessionId,
54939
54940
  machineId: ctx.machineId,
54940
54941
  workingDir,
@@ -54947,7 +54948,7 @@ async function prefetchSingleCommit(ctx, workingDir, sha, commits) {
54947
54948
  return;
54948
54949
  }
54949
54950
  if (result.status === "error") {
54950
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54951
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54951
54952
  sessionId: ctx.sessionId,
54952
54953
  machineId: ctx.machineId,
54953
54954
  workingDir,
@@ -54961,13 +54962,16 @@ async function prefetchSingleCommit(ctx, workingDir, sha, commits) {
54961
54962
  return;
54962
54963
  }
54963
54964
  const diffStat = extractDiffStatFromShowOutput(result.content);
54964
- await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetail, {
54965
+ const { gzipSync: gzipSync2 } = await import("node:zlib");
54966
+ const compressed = gzipSync2(Buffer.from(result.content));
54967
+ const diffContentCompressed = compressed.toString("base64");
54968
+ await ctx.deps.backend.mutation(api.workspaces.upsertCommitDetailV2, {
54965
54969
  sessionId: ctx.sessionId,
54966
54970
  machineId: ctx.machineId,
54967
54971
  workingDir,
54968
54972
  sha,
54969
54973
  status: "available",
54970
- diffContent: result.content,
54974
+ data: { compression: "gzip", content: diffContentCompressed },
54971
54975
  truncated: result.truncated,
54972
54976
  message: metadata?.message,
54973
54977
  author: metadata?.author,
@@ -55286,6 +55290,7 @@ var init_command_sync_heartbeat = __esm(() => {
55286
55290
  // src/commands/machine/daemon-start/file-content-fulfillment.ts
55287
55291
  import { readFile as readFile4 } from "node:fs/promises";
55288
55292
  import { resolve as resolve4 } from "node:path";
55293
+ import { gzipSync as gzipSync2 } from "node:zlib";
55289
55294
  function isBinaryFile(path3) {
55290
55295
  const lastDot = path3.lastIndexOf(".");
55291
55296
  if (lastDot === -1)
@@ -55326,12 +55331,13 @@ async function fulfillSingleRequest(ctx, request) {
55326
55331
  return;
55327
55332
  }
55328
55333
  if (isBinaryFile(filePath)) {
55329
- await ctx.deps.backend.mutation(api.workspaceFiles.fulfillFileContent, {
55334
+ const binaryCompressed = gzipSync2(Buffer.from("[Binary file]")).toString("base64");
55335
+ await ctx.deps.backend.mutation(api.workspaceFiles.fulfillFileContentV2, {
55330
55336
  sessionId: ctx.sessionId,
55331
55337
  machineId: ctx.machineId,
55332
55338
  workingDir,
55333
55339
  filePath,
55334
- content: "[Binary file]",
55340
+ data: { compression: "gzip", content: binaryCompressed },
55335
55341
  encoding: "utf8",
55336
55342
  truncated: false
55337
55343
  });
@@ -55353,17 +55359,19 @@ async function fulfillSingleRequest(ctx, request) {
55353
55359
  content = "[Error reading file]";
55354
55360
  truncated = false;
55355
55361
  }
55356
- await ctx.deps.backend.mutation(api.workspaceFiles.fulfillFileContent, {
55362
+ const compressed = gzipSync2(Buffer.from(content));
55363
+ const contentCompressed = compressed.toString("base64");
55364
+ await ctx.deps.backend.mutation(api.workspaceFiles.fulfillFileContentV2, {
55357
55365
  sessionId: ctx.sessionId,
55358
55366
  machineId: ctx.machineId,
55359
55367
  workingDir,
55360
55368
  filePath,
55361
- content,
55369
+ data: { compression: "gzip", content: contentCompressed },
55362
55370
  encoding: "utf8",
55363
55371
  truncated
55364
55372
  });
55365
55373
  const elapsed = Date.now() - startTime;
55366
- console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content synced to Convex: ${filePath} (${elapsed}ms)`);
55374
+ console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content synced to Convex: ${filePath} (${(Buffer.byteLength(content) / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB gzip, ${elapsed}ms)`);
55367
55375
  }
55368
55376
  var MAX_CONTENT_BYTES, BINARY_EXTENSIONS;
55369
55377
  var init_file_content_fulfillment = __esm(() => {
@@ -55535,6 +55543,7 @@ var init_file_tree_scanner = __esm(() => {
55535
55543
 
55536
55544
  // src/commands/machine/daemon-start/file-tree-subscription.ts
55537
55545
  import { createHash as createHash5 } from "node:crypto";
55546
+ import { gzipSync as gzipSync3 } from "node:zlib";
55538
55547
  function startFileTreeSubscription(ctx, wsClient2) {
55539
55548
  let processing = false;
55540
55549
  const unsubscribe = wsClient2.onUpdate(api.workspaceFiles.getPendingFileTreeRequests, {
@@ -55568,12 +55577,14 @@ async function fulfillFileTreeRequests(ctx, requests) {
55568
55577
  const tree = await scanFileTree(request.workingDir);
55569
55578
  const treeJson = JSON.stringify(tree);
55570
55579
  const treeHash = createHash5("md5").update(treeJson).digest("hex");
55571
- await ctx.deps.backend.mutation(api.workspaceFiles.syncFileTree, {
55580
+ const compressed = gzipSync3(Buffer.from(treeJson));
55581
+ const treeJsonCompressed = compressed.toString("base64");
55582
+ await ctx.deps.backend.mutation(api.workspaceFiles.syncFileTreeV2, {
55572
55583
  sessionId: ctx.sessionId,
55573
55584
  machineId: ctx.machineId,
55574
55585
  workingDir: request.workingDir,
55575
- treeJson,
55576
- treeHash,
55586
+ data: { compression: "gzip", content: treeJsonCompressed },
55587
+ dataHash: treeHash,
55577
55588
  scannedAt: tree.scannedAt
55578
55589
  });
55579
55590
  await ctx.deps.backend.mutation(api.workspaceFiles.fulfillFileTreeRequest, {
@@ -55581,7 +55592,7 @@ async function fulfillFileTreeRequests(ctx, requests) {
55581
55592
  machineId: ctx.machineId,
55582
55593
  workingDir: request.workingDir
55583
55594
  });
55584
- console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree fulfilled: ${request.workingDir} (${tree.entries.length} entries)`);
55595
+ console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree fulfilled: ${request.workingDir} (${tree.entries.length} entries, ${(Buffer.byteLength(treeJson) / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB gzip)`);
55585
55596
  } catch (err) {
55586
55597
  console.warn(`[${formatTimestamp()}] ⚠️ File tree fulfillment failed for ${request.workingDir}: ${getErrorMessage(err)}`);
55587
55598
  }
@@ -56833,34 +56844,61 @@ function createDefaultDeps21() {
56833
56844
  agentProcessManager: null
56834
56845
  };
56835
56846
  }
56836
- function validateAuthentication(convexUrl) {
56847
+ async function waitForAuthentication(convexUrl) {
56848
+ const startTime = Date.now();
56849
+ while (Date.now() - startTime < AUTH_WAIT_TIMEOUT_MS) {
56850
+ await new Promise((resolve5) => setTimeout(resolve5, AUTH_POLL_INTERVAL_MS2));
56851
+ const sessionId = getSessionId();
56852
+ if (sessionId) {
56853
+ console.log(`
56854
+ ✅ Authentication detected. Resuming daemon initialization...`);
56855
+ return sessionId;
56856
+ }
56857
+ }
56858
+ console.error(`
56859
+ ❌ Authentication timeout (5 minutes). Exiting.`);
56860
+ releaseLock();
56861
+ process.exit(1);
56862
+ }
56863
+ async function validateAuthentication(convexUrl) {
56837
56864
  const sessionId = getSessionId();
56838
- if (!sessionId) {
56839
- const otherUrls = getOtherSessionUrls();
56840
- console.error(`❌ Not authenticated for: ${convexUrl}`);
56841
- if (otherUrls.length > 0) {
56842
- console.error(`
56865
+ if (sessionId) {
56866
+ return sessionId;
56867
+ }
56868
+ const otherUrls = getOtherSessionUrls();
56869
+ console.error(`❌ Not authenticated for: ${convexUrl}`);
56870
+ if (otherUrls.length > 0) {
56871
+ console.error(`
56843
56872
  \uD83D\uDCA1 You have sessions for other environments:`);
56844
- for (const url2 of otherUrls) {
56845
- console.error(` • ${url2}`);
56846
- }
56873
+ for (const url2 of otherUrls) {
56874
+ console.error(` • ${url2}`);
56847
56875
  }
56848
- console.error(`
56849
- Run: chatroom auth login`);
56850
- releaseLock();
56851
- process.exit(1);
56852
56876
  }
56853
- return sessionId;
56877
+ console.error(`
56878
+ Run: chatroom auth login`);
56879
+ console.log(`
56880
+ ⏳ Waiting for authentication (timeout: 5 minutes)...`);
56881
+ return waitForAuthentication(convexUrl);
56854
56882
  }
56855
56883
  async function validateSession(client2, sessionId, convexUrl) {
56856
56884
  const validation = await client2.query(api.cliAuth.validateSession, { sessionId });
56857
- if (!validation.valid) {
56858
- console.error(`❌ Session invalid: ${validation.reason}`);
56859
- console.error(`
56885
+ if (validation.valid) {
56886
+ return sessionId;
56887
+ }
56888
+ console.error(`❌ Session invalid: ${validation.reason}`);
56889
+ console.error(`
56860
56890
  Run: chatroom auth login`);
56891
+ console.log(`
56892
+ ⏳ Waiting for re-authentication (timeout: 5 minutes)...`);
56893
+ const newSessionId2 = await waitForAuthentication(convexUrl);
56894
+ const typedNewSession = newSessionId2;
56895
+ const revalidation = await client2.query(api.cliAuth.validateSession, { sessionId: typedNewSession });
56896
+ if (!revalidation.valid) {
56897
+ console.error(`❌ New session is also invalid: ${revalidation.reason}`);
56861
56898
  releaseLock();
56862
56899
  process.exit(1);
56863
56900
  }
56901
+ return typedNewSession;
56864
56902
  }
56865
56903
  function setupMachine() {
56866
56904
  ensureMachineRegistered();
@@ -56938,12 +56976,12 @@ async function initDaemon() {
56938
56976
  process.exit(1);
56939
56977
  }
56940
56978
  const convexUrl = getConvexUrl();
56941
- const sessionId = validateAuthentication(convexUrl);
56979
+ const sessionId = await validateAuthentication(convexUrl);
56942
56980
  const client2 = await getConvexClient();
56943
- const typedSessionId = sessionId;
56981
+ let typedSessionId = sessionId;
56944
56982
  while (true) {
56945
56983
  try {
56946
- await validateSession(client2, typedSessionId, convexUrl);
56984
+ typedSessionId = await validateSession(client2, typedSessionId, convexUrl);
56947
56985
  const config3 = setupMachine();
56948
56986
  const { machineId } = config3;
56949
56987
  initHarnessRegistry();
@@ -56995,7 +57033,7 @@ async function initDaemon() {
56995
57033
  }
56996
57034
  }
56997
57035
  }
56998
- var CONNECTION_RETRY_INTERVAL_MS = 1000;
57036
+ var AUTH_POLL_INTERVAL_MS2 = 2000, AUTH_WAIT_TIMEOUT_MS, CONNECTION_RETRY_INTERVAL_MS = 1000;
56999
57037
  var init_init2 = __esm(() => {
57000
57038
  init_state_recovery();
57001
57039
  init_api3();
@@ -57012,6 +57050,7 @@ var init_init2 = __esm(() => {
57012
57050
  init_convex_error();
57013
57051
  init_version();
57014
57052
  init_pid();
57053
+ AUTH_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
57015
57054
  });
57016
57055
 
57017
57056
  // 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.26.0",
3
+ "version": "1.29.1",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {