@groupchatai/claude-runner 0.4.9 → 0.4.11

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 +100 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -79,6 +79,39 @@ var GroupChatAgentClient = class {
79
79
  return this.request("POST", `/runs/${runId}/comment`, { body });
80
80
  }
81
81
  };
82
+ function buildResumedPrompt(detail, agentUserId) {
83
+ const comments = detail.activity.filter(
84
+ (a) => a.type === "comment" && a.body && a.body.trim().length > 0
85
+ );
86
+ let lastAgentCommentIdx = -1;
87
+ for (let i = comments.length - 1; i >= 0; i--) {
88
+ if (comments[i].userId === agentUserId) {
89
+ lastAgentCommentIdx = i;
90
+ break;
91
+ }
92
+ }
93
+ const newComments = comments.slice(lastAgentCommentIdx + 1).filter((c) => c.userId !== agentUserId);
94
+ const parts = [];
95
+ if (newComments.length > 0) {
96
+ parts.push("New comments since your last response:");
97
+ for (const c of newComments) {
98
+ const author = c.userName ?? "Someone";
99
+ parts.push(`
100
+ **${author}**:
101
+ ${c.body}`);
102
+ }
103
+ }
104
+ if (detail.lastFollowUpMessage && detail.lastFollowUpMessage !== "Continue working on this task.") {
105
+ parts.push(`
106
+ Follow-up request: ${detail.lastFollowUpMessage}`);
107
+ }
108
+ if (parts.length === 0) {
109
+ parts.push(
110
+ "The user has asked you to continue working on this task. Check the conversation history and address any outstanding requests."
111
+ );
112
+ }
113
+ return parts.join("\n");
114
+ }
82
115
  function buildClaudePrompt(detail, repoResolved) {
83
116
  const parts = [];
84
117
  parts.push(`# Task: ${detail.task.title}`);
@@ -127,6 +160,14 @@ ${comment.body}`
127
160
  );
128
161
  }
129
162
  }
163
+ if (detail.lastFollowUpMessage) {
164
+ parts.push(
165
+ `
166
+ ## Latest Follow-up Request
167
+ The user has sent a follow-up message. Address this:
168
+ ${detail.lastFollowUpMessage}`
169
+ );
170
+ }
130
171
  const existingPrUrl = detail.pullRequestUrl ?? detail.task.pullRequestUrl;
131
172
  if (existingPrUrl) {
132
173
  parts.push(`
@@ -613,6 +654,7 @@ function runShellCommand(cmd, args, cwd) {
613
654
  });
614
655
  }
615
656
  var sessionCache = /* @__PURE__ */ new Map();
657
+ var currentAgentUserId = "";
616
658
  var activeProcesses = /* @__PURE__ */ new Map();
617
659
  var stoppedRunIds = /* @__PURE__ */ new Set();
618
660
  function stopActiveProcess(runId) {
@@ -932,6 +974,23 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
932
974
  const logGreen = (msg) => console.log(`${runTag} ${C.green}${msg}${C.reset}`);
933
975
  const ownerName = run.owner?.name ?? detail.owner?.name ?? "unknown";
934
976
  log(`\u{1F4CB} "${run.taskTitle}" \u2014 delegated by ${ownerName}`);
977
+ if (config.verbose) {
978
+ log(`\u{1F4CE} Run ID: ${run.id} | Task ID: ${run.taskId}`);
979
+ log(
980
+ `\u{1F4CE} Detail status: ${detail.status} | Has lastFollowUpMessage: ${!!detail.lastFollowUpMessage} | Has lastSessionId: ${!!detail.lastSessionId}`
981
+ );
982
+ log(
983
+ `\u{1F4CE} In-memory session cache hit: ${sessionCache.has(run.taskId)} | Activity items: ${detail.activity.length}`
984
+ );
985
+ if (detail.lastFollowUpMessage) {
986
+ log(
987
+ `\u{1F4CE} lastFollowUpMessage: "${detail.lastFollowUpMessage.slice(0, 150)}${detail.lastFollowUpMessage.length > 150 ? "\u2026" : ""}"`
988
+ );
989
+ }
990
+ if (detail.lastSessionId) {
991
+ log(`\u{1F4CE} Server lastSessionId: ${detail.lastSessionId.slice(0, 12)}\u2026`);
992
+ }
993
+ }
935
994
  if (detail.status !== "PENDING") {
936
995
  log(`\u23ED Run is no longer PENDING (now ${detail.status}), skipping.`);
937
996
  return;
@@ -975,16 +1034,41 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
975
1034
  });
976
1035
  await new Promise((resolve) => git.on("close", () => resolve()));
977
1036
  }
978
- const cachedSessionId = sessionCache.get(run.taskId);
1037
+ const cachedSessionId = sessionCache.get(run.taskId) ?? detail.lastSessionId;
979
1038
  const isFollowUp = cachedSessionId !== void 0;
980
- const effectivePrompt = isFollowUp ? detail.prompt : prompt;
1039
+ let effectivePrompt;
1040
+ if (isFollowUp && cachedSessionId) {
1041
+ effectivePrompt = buildResumedPrompt(detail, currentAgentUserId);
1042
+ } else {
1043
+ effectivePrompt = prompt;
1044
+ }
981
1045
  const resumeSession = isFollowUp ? cachedSessionId : void 0;
982
1046
  if (config.verbose) {
983
1047
  if (isFollowUp) {
984
- log(`\u{1F504} Resuming session ${cachedSessionId.slice(0, 12)}\u2026`);
1048
+ const sessionSource = sessionCache.has(run.taskId) ? "in-memory cache" : "server (lastSessionId)";
1049
+ log(`\u{1F504} Resuming session ${cachedSessionId.slice(0, 12)}\u2026 (source: ${sessionSource})`);
1050
+ if (detail.lastFollowUpMessage) {
1051
+ log(
1052
+ `\u{1F4AC} Follow-up message: "${detail.lastFollowUpMessage.slice(0, 200)}${detail.lastFollowUpMessage.length > 200 ? "\u2026" : ""}"`
1053
+ );
1054
+ } else {
1055
+ log(`\u26A0 No lastFollowUpMessage found \u2014 using full prompt for resumed session`);
1056
+ }
1057
+ } else {
1058
+ log(`\u{1F195} Initial run (no session to resume)`);
985
1059
  }
986
- log(`\u{1F4DD} Prompt (${effectivePrompt.length} chars)`);
1060
+ log(
1061
+ `\u{1F4DD} Prompt (${effectivePrompt.length} chars)${isFollowUp ? " [follow-up]" : " [initial]"}`
1062
+ );
1063
+ const previewLen = 500;
1064
+ log(
1065
+ `\u{1F4DD} Prompt preview:
1066
+ ${effectivePrompt.slice(0, previewLen)}${effectivePrompt.length > previewLen ? "\n... (truncated)" : ""}`
1067
+ );
987
1068
  if (effectiveModel) log(`\u{1F9E0} Model: ${effectiveModel}`);
1069
+ log(
1070
+ `\u{1F4CA} Activity items: ${detail.activity.length}, Comments: ${detail.activity.filter((a) => a.type === "comment").length}`
1071
+ );
988
1072
  }
989
1073
  const { process: child, output } = spawnClaudeCode(
990
1074
  effectivePrompt,
@@ -1017,6 +1101,9 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
1017
1101
  }
1018
1102
  if (sessionId) {
1019
1103
  sessionCache.set(run.taskId, sessionId);
1104
+ if (config.verbose) {
1105
+ log(`\u{1F4BE} Session ${sessionId.slice(0, 12)}\u2026 cached for task ${run.taskId}`);
1106
+ }
1020
1107
  }
1021
1108
  const pullRequestUrl = streamPrUrl ?? await detectPullRequestUrl(effectiveCwd) ?? extractPullRequestUrlFromOutput(stdout) ?? extractPullRequestUrlFromOutput(rawOutput);
1022
1109
  const streamEvents = parseClaudeNdjsonEvents(rawOutput);
@@ -1051,7 +1138,8 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
1051
1138
  await client.errorRun(run.id, errorMsg, {
1052
1139
  pullRequestUrl,
1053
1140
  errorType: retryInfo?.errorType,
1054
- retryAfter: retryInfo?.retryAfterMs
1141
+ retryAfter: retryInfo?.retryAfterMs,
1142
+ sessionId: lastClaude.sessionId
1055
1143
  });
1056
1144
  if (retryInfo) {
1057
1145
  const retryAt = new Date(retryInfo.retryAfterMs).toLocaleString(void 0, {
@@ -1082,7 +1170,11 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
1082
1170
  }
1083
1171
  const resultText = extractResultText(stdout);
1084
1172
  const cost = extractCost(stdout);
1085
- await client.completeRun(run.id, resultText, { ...cost, pullRequestUrl });
1173
+ await client.completeRun(run.id, resultText, {
1174
+ ...cost,
1175
+ pullRequestUrl,
1176
+ sessionId: lastClaude.sessionId
1177
+ });
1086
1178
  if (pullRequestUrl) logGreen(`\u{1F517} PR: ${pullRequestUrl}`);
1087
1179
  logGreen(`\u2705 Run completed`);
1088
1180
  } catch (err) {
@@ -1114,7 +1206,7 @@ async function processRun(client, run, config, worktreeDir, detail, runBaseDir,
1114
1206
  ${message.slice(0, 2e3)}
1115
1207
  \`\`\``;
1116
1208
  try {
1117
- await client.errorRun(run.id, errorBody);
1209
+ await client.errorRun(run.id, errorBody, { sessionId: lastClaude.sessionId });
1118
1210
  } catch {
1119
1211
  log(`${C.dim}\u26A0 Failed to report error to API${C.reset}`);
1120
1212
  }
@@ -1610,6 +1702,7 @@ async function main() {
1610
1702
  console.error("Failed to authenticate:", errMsg(err));
1611
1703
  process.exit(1);
1612
1704
  }
1705
+ currentAgentUserId = me.agentUserId;
1613
1706
  console.log(`
1614
1707
  \u{1F916} Agent Runner \u2014 ${me.name}`);
1615
1708
  console.log(` Owner: ${me.ownerName}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groupchatai/claude-runner",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "Run GroupChat AI agent tasks locally with Claude Code",
5
5
  "type": "module",
6
6
  "bin": {