Compare commits

..

2 Commits

Author SHA1 Message Date
Colin McDonnell df72988aab Silently return if no issue_number 2025-12-02 21:20:14 -08:00
Colin McDonnell 6ce1d9773c Improve cursor logging 2025-12-02 20:48:07 -08:00
5 changed files with 42 additions and 25 deletions
+24 -11
View File
@@ -94,11 +94,10 @@ export const cursor = agent({
run: async ({ payload, apiKey, cliPath, mcpServers }) => { run: async ({ payload, apiKey, cliPath, mcpServers }) => {
configureCursorMcpServers({ mcpServers, cliPath }); configureCursorMcpServers({ mcpServers, cliPath });
// track logged messages to avoid duplicates // track logged model_call_ids to avoid duplicates
const loggedAssistantMessages = new Set<string>(); // cursor emits each assistant message twice: once without model_call_id, then again with it
const loggedModelCallIds = new Set<string>();
// moved into `run` because it is stateful
// it tracks logged assistant messages to avoid duplicates
const messageHandlers = { const messageHandlers = {
system: (_event: CursorSystemEvent) => { system: (_event: CursorSystemEvent) => {
// system init events - no logging needed // system init events - no logging needed
@@ -111,8 +110,22 @@ export const cursor = agent({
}, },
assistant: (event: CursorAssistantEvent) => { assistant: (event: CursorAssistantEvent) => {
const text = event.message?.content?.[0]?.text?.trim(); const text = event.message?.content?.[0]?.text?.trim();
if (text && !loggedAssistantMessages.has(text)) { if (!text) return;
loggedAssistantMessages.add(text);
if (event.model_call_id) {
// complete message with model_call_id - log it if we haven't seen this id before
// cursor emits each message twice: first without model_call_id, then with it
// we deduplicate by model_call_id to avoid logging the same message twice
if (!loggedModelCallIds.has(event.model_call_id)) {
loggedModelCallIds.add(event.model_call_id);
log.box(text, { title: "Cursor" });
}
} else {
// message without model_call_id - log it immediately
// this handles cases where:
// 1. the final summary message might only be emitted without model_call_id
// 2. messages that don't get re-emitted with model_call_id
// without this, the final comprehensive summary wouldn't print (as we discovered)
log.box(text, { title: "Cursor" }); log.box(text, { title: "Cursor" });
} }
}, },
@@ -144,6 +157,9 @@ export const cursor = agent({
if (event.subtype === "success" && event.duration_ms) { if (event.subtype === "success" && event.duration_ms) {
const durationSec = (event.duration_ms / 1000).toFixed(1); const durationSec = (event.duration_ms / 1000).toFixed(1);
log.debug(`Cursor completed in ${durationSec}s`); log.debug(`Cursor completed in ${durationSec}s`);
// note: we don't log event.result here because it contains the full conversation
// concatenated together, which would duplicate all the individual assistant
// messages we've already logged. the individual assistant events are sufficient.
} }
}, },
}; };
@@ -163,7 +179,7 @@ export const cursor = agent({
fullPrompt, fullPrompt,
"--output-format", "--output-format",
"stream-json", "stream-json",
"--stream-partial-output", // "--stream-partial-output",
"--approve-mcps", "--approve-mcps",
"--force", "--force",
], ],
@@ -190,7 +206,7 @@ export const cursor = agent({
try { try {
const event = JSON.parse(text) as CursorEvent; const event = JSON.parse(text) as CursorEvent;
// skip debug logging for empty thinking deltas // skip empty thinking deltas
if (event.type === "thinking" && event.subtype === "delta" && !event.text) { if (event.type === "thinking" && event.subtype === "delta" && !event.text) {
return; return;
} }
@@ -200,9 +216,6 @@ export const cursor = agent({
if (handler) { if (handler) {
await handler(event as never); await handler(event as never);
} }
// debug: log all events
log.debug(`[cursor event] ${JSON.stringify(event, null, 2)}`);
} catch { } catch {
// ignore parse errors - might be formatted tool call logs from cursor cli // ignore parse errors - might be formatted tool call logs from cursor cli
// our handlers log tool calls instead, so we don't need to display these // our handlers log tool calls instead, so we don't need to display these
+11 -9
View File
@@ -83859,7 +83859,7 @@ function query({
// package.json // package.json
var package_default = { var package_default = {
name: "@pullfrog/action", name: "@pullfrog/action",
version: "0.0.119", version: "0.0.121",
type: "module", type: "module",
files: [ files: [
"index.js", "index.js",
@@ -93400,7 +93400,7 @@ var cursor = agent({
}, },
run: async ({ payload, apiKey, cliPath, mcpServers }) => { run: async ({ payload, apiKey, cliPath, mcpServers }) => {
configureCursorMcpServers({ mcpServers, cliPath }); configureCursorMcpServers({ mcpServers, cliPath });
const loggedAssistantMessages = /* @__PURE__ */ new Set(); const loggedModelCallIds = /* @__PURE__ */ new Set();
const messageHandlers4 = { const messageHandlers4 = {
system: (_event) => { system: (_event) => {
}, },
@@ -93410,8 +93410,13 @@ var cursor = agent({
}, },
assistant: (event) => { assistant: (event) => {
const text = event.message?.content?.[0]?.text?.trim(); const text = event.message?.content?.[0]?.text?.trim();
if (text && !loggedAssistantMessages.has(text)) { if (!text) return;
loggedAssistantMessages.add(text); if (event.model_call_id) {
if (!loggedModelCallIds.has(event.model_call_id)) {
loggedModelCallIds.add(event.model_call_id);
log.box(text, { title: "Cursor" });
}
} else {
log.box(text, { title: "Cursor" }); log.box(text, { title: "Cursor" });
} }
}, },
@@ -93456,7 +93461,7 @@ var cursor = agent({
fullPrompt, fullPrompt,
"--output-format", "--output-format",
"stream-json", "stream-json",
"--stream-partial-output", // "--stream-partial-output",
"--approve-mcps", "--approve-mcps",
"--force" "--force"
], ],
@@ -93486,7 +93491,6 @@ var cursor = agent({
if (handler2) { if (handler2) {
await handler2(event); await handler2(event);
} }
log.debug(`[cursor event] ${JSON.stringify(event, null, 2)}`);
} catch { } catch {
} }
}); });
@@ -121796,9 +121800,7 @@ var ReportProgressTool = tool({
} }
const issueNumber = ctx.payload.event.issue_number; const issueNumber = ctx.payload.event.issue_number;
if (issueNumber === void 0) { if (issueNumber === void 0) {
throw new Error( return { suggess: true };
"cannot create progress comment: no issue_number found in the payload event"
);
} }
const result = await ctx.octokit.rest.issues.createComment({ const result = await ctx.octokit.rest.issues.createComment({
owner: ctx.owner, owner: ctx.owner,
+1 -1
View File
@@ -1 +1 @@
Tell me a joke summarize https://github.com/pullfrogai/scratch/issues/56, its status, and pertinent discussion on the issue
+5 -3
View File
@@ -166,9 +166,11 @@ export const ReportProgressTool = tool({
// no existing comment - create one // no existing comment - create one
const issueNumber = ctx.payload.event.issue_number; const issueNumber = ctx.payload.event.issue_number;
if (issueNumber === undefined) { if (issueNumber === undefined) {
throw new Error( // fail silently
"cannot create progress comment: no issue_number found in the payload event" return { suggess: true };
); // throw new Error(
// "cannot create progress comment: no issue_number found in the payload event"
// );
} }
const result = await ctx.octokit.rest.issues.createComment({ const result = await ctx.octokit.rest.issues.createComment({
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@pullfrog/action", "name": "@pullfrog/action",
"version": "0.0.119", "version": "0.0.121",
"type": "module", "type": "module",
"files": [ "files": [
"index.js", "index.js",