ai-project-manage-cli 7.0.7 → 7.0.9

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 +158 -46
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -451,6 +451,18 @@ var requestConfig = {
451
451
  method: "PUT",
452
452
  path: "/cli/cursor-agent/questions"
453
453
  }),
454
+ listPendingCursorAgentResumes: defineEndpoint({
455
+ method: "GET",
456
+ path: "/cli/cursor-agent/resumes/pending"
457
+ }),
458
+ claimCursorAgentResume: defineEndpoint({
459
+ method: "PUT",
460
+ path: "/cli/cursor-agent/resumes/claim"
461
+ }),
462
+ completeCursorAgentResume: defineEndpoint({
463
+ method: "PUT",
464
+ path: "/cli/cursor-agent/resumes/complete"
465
+ }),
454
466
  upsertCursorLog: defineEndpoint({
455
467
  method: "PUT",
456
468
  path: "/cli/cursor-logs"
@@ -2276,8 +2288,19 @@ function createAskQuestionTool(handlers) {
2276
2288
  batchId: randomUUID(),
2277
2289
  ...validated.input
2278
2290
  };
2291
+ try {
2292
+ await handlers.onAskQuestion(batch);
2293
+ } catch (err) {
2294
+ const message = err instanceof Error ? err.message : String(err);
2295
+ console.error(
2296
+ `[apm] AskQuestion \u63D0\u4EA4\u5931\u8D25 batchId=${batch.batchId}: ${message}`
2297
+ );
2298
+ return {
2299
+ content: [{ type: "text", text: `\u63D0\u4EA4\u95EE\u9898\u5931\u8D25: ${message}` }],
2300
+ isError: true
2301
+ };
2302
+ }
2279
2303
  batches.push(batch);
2280
- await handlers.onAskQuestion(batch);
2281
2304
  console.log(
2282
2305
  `[apm] AskQuestion \u5DF2\u63D0\u4EA4 batchId=${batch.batchId} questions=${batch.questions.length}`
2283
2306
  );
@@ -3022,14 +3045,33 @@ async function runMailboxCursorAgentResume(push, options) {
3022
3045
  return;
3023
3046
  }
3024
3047
  const api = createApmApiClient(options.cfg);
3048
+ let activePush = push;
3049
+ try {
3050
+ const claimed = await api.cli.claimCursorAgentResume({
3051
+ anchorId: push.anchorId
3052
+ });
3053
+ if (claimed) {
3054
+ activePush = claimed;
3055
+ }
3056
+ } catch (err) {
3057
+ console.error(
3058
+ `[apm] \u8BA4\u9886\u7EED\u804A\u5931\u8D25 mailId=${push.anchorId}:`,
3059
+ err instanceof Error ? err.message : err
3060
+ );
3061
+ return;
3062
+ }
3025
3063
  let detail;
3026
3064
  try {
3027
- detail = await api.cli.getMailboxMessageDetail({ id: push.anchorId });
3065
+ detail = await api.cli.getMailboxMessageDetail({ id: activePush.anchorId });
3028
3066
  } catch (err) {
3029
3067
  console.error(
3030
- `[apm] \u7EED\u804A\u83B7\u53D6\u4FE1\u4EF6\u8BE6\u60C5\u5931\u8D25 id=${push.anchorId}:`,
3068
+ `[apm] \u7EED\u804A\u83B7\u53D6\u4FE1\u4EF6\u8BE6\u60C5\u5931\u8D25 id=${activePush.anchorId}:`,
3031
3069
  err instanceof Error ? err.message : err
3032
3070
  );
3071
+ await api.cli.completeCursorAgentResume({
3072
+ anchorId: activePush.anchorId,
3073
+ status: "FAILED"
3074
+ });
3033
3075
  return;
3034
3076
  }
3035
3077
  const {
@@ -3039,22 +3081,22 @@ async function runMailboxCursorAgentResume(push, options) {
3039
3081
  } = createMailReplyDraft({
3040
3082
  appendDraft: async (content) => {
3041
3083
  await api.cli.appendMailboxDraft({
3042
- id: push.draftReplyId,
3084
+ id: activePush.draftReplyId,
3043
3085
  content
3044
3086
  });
3045
3087
  }
3046
3088
  });
3047
- const cursorMode = push.mode;
3089
+ const cursorMode = activePush.mode;
3048
3090
  const submitQuestions = async (batch, ctx) => {
3049
3091
  await api.cli.createCursorAgentQuestions({
3050
3092
  anchorType: "mailbox",
3051
- anchorId: push.anchorId,
3052
- taskId: push.taskId,
3093
+ anchorId: activePush.anchorId,
3094
+ taskId: activePush.taskId,
3053
3095
  cursorAgentId: ctx.agentId,
3054
- draftReplyId: push.draftReplyId,
3055
- workdir: push.workdir,
3056
- model: push.model,
3057
- memberDisplayName: push.memberDisplayName,
3096
+ draftReplyId: activePush.draftReplyId,
3097
+ workdir: activePush.workdir,
3098
+ model: activePush.model,
3099
+ memberDisplayName: activePush.memberDisplayName,
3058
3100
  mode: cursorMode,
3059
3101
  batch
3060
3102
  });
@@ -3063,13 +3105,13 @@ async function runMailboxCursorAgentResume(push, options) {
3063
3105
  const result = await runCursorAgent(
3064
3106
  options.cfg,
3065
3107
  {
3066
- mailId: push.anchorId,
3067
- taskId: push.taskId,
3068
- prompt: push.prompt,
3069
- model: push.model,
3108
+ mailId: activePush.anchorId,
3109
+ taskId: activePush.taskId,
3110
+ prompt: activePush.prompt,
3111
+ model: activePush.model,
3070
3112
  apiKey: cursorApiKey,
3071
- workdir: push.workdir,
3072
- user: push.memberDisplayName,
3113
+ workdir: activePush.workdir,
3114
+ user: activePush.memberDisplayName,
3073
3115
  mode: cursorMode
3074
3116
  },
3075
3117
  {
@@ -3081,8 +3123,12 @@ async function runMailboxCursorAgentResume(push, options) {
3081
3123
  );
3082
3124
  if (result.hasPendingQuestions) {
3083
3125
  console.log(
3084
- `[apm] \u7EED\u804A\u540E\u4ECD\u6709\u5F85\u7B54 AskQuestion mailId=${push.anchorId}\uFF0C\u7B49\u5F85\u7528\u6237\u7B54\u9898`
3126
+ `[apm] \u7EED\u804A\u540E\u4ECD\u6709\u5F85\u7B54 AskQuestion mailId=${activePush.anchorId}\uFF0C\u7B49\u5F85\u7528\u6237\u7B54\u9898`
3085
3127
  );
3128
+ await api.cli.completeCursorAgentResume({
3129
+ anchorId: activePush.anchorId,
3130
+ status: "FAILED"
3131
+ });
3086
3132
  return;
3087
3133
  }
3088
3134
  const replyContent = (hasReplyContent() ? getReplyContent() : result.assistantText).trim();
@@ -3091,69 +3137,133 @@ async function runMailboxCursorAgentResume(push, options) {
3091
3137
  }
3092
3138
  if (cursorMode === "plan" && result.createPlanContent) {
3093
3139
  saveMemberPlanDocument({
3094
- workdir: push.workdir,
3095
- taskId: push.taskId,
3096
- memberDisplayName: push.memberDisplayName,
3140
+ workdir: activePush.workdir,
3141
+ taskId: activePush.taskId,
3142
+ memberDisplayName: activePush.memberDisplayName,
3097
3143
  content: result.createPlanContent
3098
3144
  });
3099
3145
  }
3100
3146
  await api.cli.completeMailboxMessage({
3101
- id: push.draftReplyId,
3147
+ id: activePush.draftReplyId,
3102
3148
  status: "SUCCEEDED",
3103
3149
  replyContent
3104
3150
  });
3105
- markMailReplied(push.anchorId);
3106
- await syncTaskDocuments(options.cfg, push.taskId, push.workdir, {
3107
- api,
3108
- remoteDocuments: detail.documents
3151
+ await api.cli.completeCursorAgentResume({
3152
+ anchorId: activePush.anchorId,
3153
+ status: "SUCCEEDED"
3109
3154
  });
3110
- console.log(`[apm] Cursor Agent \u7EED\u804A\u5B8C\u6210 mailId=${push.anchorId}`);
3155
+ markMailReplied(activePush.anchorId);
3156
+ await syncTaskDocuments(
3157
+ options.cfg,
3158
+ activePush.taskId,
3159
+ activePush.workdir,
3160
+ {
3161
+ api,
3162
+ remoteDocuments: detail.documents
3163
+ }
3164
+ );
3165
+ console.log(`[apm] Cursor Agent \u7EED\u804A\u5B8C\u6210 mailId=${activePush.anchorId}`);
3111
3166
  } catch (err) {
3112
3167
  const message = err instanceof Error ? err.message : String(err);
3113
3168
  console.error(
3114
- `[apm] Cursor Agent \u7EED\u804A\u5931\u8D25 mailId=${push.anchorId}: ${message}`
3169
+ `[apm] Cursor Agent \u7EED\u804A\u5931\u8D25 mailId=${activePush.anchorId}: ${message}`
3115
3170
  );
3116
3171
  try {
3172
+ await api.cli.completeCursorAgentResume({
3173
+ anchorId: activePush.anchorId,
3174
+ status: "FAILED"
3175
+ });
3117
3176
  await api.cli.completeMailboxMessage({
3118
- id: push.draftReplyId,
3177
+ id: activePush.draftReplyId,
3119
3178
  status: "FAILED",
3120
3179
  error: message
3121
3180
  });
3122
3181
  } catch (completeErr) {
3123
3182
  console.error(
3124
- `[apm] \u6807\u8BB0\u7EED\u804A\u5931\u8D25\u72B6\u6001\u65F6\u51FA\u9519 mailId=${push.anchorId}:`,
3183
+ `[apm] \u6807\u8BB0\u7EED\u804A\u5931\u8D25\u72B6\u6001\u65F6\u51FA\u9519 mailId=${activePush.anchorId}:`,
3125
3184
  completeErr instanceof Error ? completeErr.message : completeErr
3126
3185
  );
3127
3186
  }
3128
- markMailReplied(push.anchorId);
3187
+ markMailReplied(activePush.anchorId);
3129
3188
  }
3130
3189
  }
3131
3190
  function createCursorAgentResumeHandler(options) {
3132
3191
  let running = false;
3192
+ const queue = [];
3193
+ const pump = () => {
3194
+ if (running || options.signal.aborted || queue.length === 0) {
3195
+ return;
3196
+ }
3197
+ const push = queue.shift();
3198
+ running = true;
3199
+ void runMailboxCursorAgentResume(push, options).catch((err) => {
3200
+ console.error(
3201
+ `[apm] Cursor Agent \u7EED\u804A\u5F02\u5E38 mailId=${push.anchorId}:`,
3202
+ err instanceof Error ? err.message : err
3203
+ );
3204
+ }).finally(() => {
3205
+ running = false;
3206
+ pump();
3207
+ });
3208
+ };
3133
3209
  return {
3134
- receive(push) {
3135
- if (options.signal.aborted) {
3210
+ syncPendingResumes(pushes) {
3211
+ if (pushes.length === 0) {
3136
3212
  return;
3137
3213
  }
3138
- if (running) {
3139
- console.warn(
3140
- `[apm] \u5DF2\u6709 Cursor Agent \u7EED\u804A\u4EFB\u52A1\u8FDB\u884C\u4E2D\uFF0C\u5FFD\u7565 mailId=${push.anchorId}`
3141
- );
3214
+ console.log(`[apm] \u540C\u6B65\u5F85\u7EED\u804A Cursor Agent ${pushes.length} \u4E2A`);
3215
+ queue.push(...pushes);
3216
+ pump();
3217
+ },
3218
+ receive(push) {
3219
+ if (options.signal.aborted) {
3142
3220
  return;
3143
3221
  }
3144
- running = true;
3145
- void runMailboxCursorAgentResume(push, options).catch((err) => {
3146
- console.error(
3147
- `[apm] Cursor Agent \u7EED\u804A\u5F02\u5E38 mailId=${push.anchorId}:`,
3148
- err instanceof Error ? err.message : err
3149
- );
3150
- }).finally(() => {
3151
- running = false;
3152
- });
3222
+ queue.push(push);
3223
+ pump();
3153
3224
  }
3154
3225
  };
3155
3226
  }
3156
3227
 
3228
+ // src/commands/connect/cursor-agent-resume-sync.ts
3229
+ function parsePendingResume(value) {
3230
+ if (typeof value !== "object" || value === null) {
3231
+ return null;
3232
+ }
3233
+ const row = value;
3234
+ if (row.type !== "cursor_agent_resume" || row.anchorType !== "mailbox" || typeof row.anchorId !== "string" || typeof row.taskId !== "string" || typeof row.cursorAgentId !== "string" || typeof row.draftReplyId !== "string" || typeof row.workdir !== "string" || typeof row.model !== "string" || typeof row.memberDisplayName !== "string" || typeof row.prompt !== "string") {
3235
+ return null;
3236
+ }
3237
+ const mode = row.mode;
3238
+ if (mode !== "plan" && mode !== "agent") {
3239
+ return null;
3240
+ }
3241
+ return {
3242
+ type: "cursor_agent_resume",
3243
+ anchorType: "mailbox",
3244
+ anchorId: row.anchorId,
3245
+ taskId: row.taskId,
3246
+ cursorAgentId: row.cursorAgentId,
3247
+ draftReplyId: row.draftReplyId,
3248
+ workdir: row.workdir,
3249
+ model: row.model,
3250
+ memberDisplayName: row.memberDisplayName,
3251
+ mode,
3252
+ prompt: row.prompt
3253
+ };
3254
+ }
3255
+ async function fetchPendingCursorAgentResumes(cfg) {
3256
+ const api = createApmApiClient(cfg);
3257
+ const list = await api.cli.listPendingCursorAgentResumes({});
3258
+ if (!Array.isArray(list)) {
3259
+ return [];
3260
+ }
3261
+ return list.flatMap((item) => {
3262
+ const resume = parsePendingResume(item);
3263
+ return resume ? [resume] : [];
3264
+ });
3265
+ }
3266
+
3157
3267
  // src/commands/connect/mail-sync.ts
3158
3268
  function parsePendingMail(value) {
3159
3269
  if (typeof value !== "object" || value === null) {
@@ -3288,6 +3398,8 @@ async function runConnect(options) {
3288
3398
  }
3289
3399
  const mails = await fetchPendingMails(cfg);
3290
3400
  mailProcessor.syncPendingMails(mails);
3401
+ const pendingResumes = await fetchPendingCursorAgentResumes(cfg);
3402
+ cursorAgentResumeHandler.syncPendingResumes(pendingResumes);
3291
3403
  } catch (err) {
3292
3404
  console.error(
3293
3405
  "[apm] \u8FDE\u63A5\u540E\u521D\u59CB\u5316\u5931\u8D25:",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "7.0.7",
3
+ "version": "7.0.9",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,