ai-project-manage-cli 7.0.8 → 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 +146 -45
  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"
@@ -3033,14 +3045,33 @@ async function runMailboxCursorAgentResume(push, options) {
3033
3045
  return;
3034
3046
  }
3035
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
+ }
3036
3063
  let detail;
3037
3064
  try {
3038
- detail = await api.cli.getMailboxMessageDetail({ id: push.anchorId });
3065
+ detail = await api.cli.getMailboxMessageDetail({ id: activePush.anchorId });
3039
3066
  } catch (err) {
3040
3067
  console.error(
3041
- `[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}:`,
3042
3069
  err instanceof Error ? err.message : err
3043
3070
  );
3071
+ await api.cli.completeCursorAgentResume({
3072
+ anchorId: activePush.anchorId,
3073
+ status: "FAILED"
3074
+ });
3044
3075
  return;
3045
3076
  }
3046
3077
  const {
@@ -3050,22 +3081,22 @@ async function runMailboxCursorAgentResume(push, options) {
3050
3081
  } = createMailReplyDraft({
3051
3082
  appendDraft: async (content) => {
3052
3083
  await api.cli.appendMailboxDraft({
3053
- id: push.draftReplyId,
3084
+ id: activePush.draftReplyId,
3054
3085
  content
3055
3086
  });
3056
3087
  }
3057
3088
  });
3058
- const cursorMode = push.mode;
3089
+ const cursorMode = activePush.mode;
3059
3090
  const submitQuestions = async (batch, ctx) => {
3060
3091
  await api.cli.createCursorAgentQuestions({
3061
3092
  anchorType: "mailbox",
3062
- anchorId: push.anchorId,
3063
- taskId: push.taskId,
3093
+ anchorId: activePush.anchorId,
3094
+ taskId: activePush.taskId,
3064
3095
  cursorAgentId: ctx.agentId,
3065
- draftReplyId: push.draftReplyId,
3066
- workdir: push.workdir,
3067
- model: push.model,
3068
- memberDisplayName: push.memberDisplayName,
3096
+ draftReplyId: activePush.draftReplyId,
3097
+ workdir: activePush.workdir,
3098
+ model: activePush.model,
3099
+ memberDisplayName: activePush.memberDisplayName,
3069
3100
  mode: cursorMode,
3070
3101
  batch
3071
3102
  });
@@ -3074,13 +3105,13 @@ async function runMailboxCursorAgentResume(push, options) {
3074
3105
  const result = await runCursorAgent(
3075
3106
  options.cfg,
3076
3107
  {
3077
- mailId: push.anchorId,
3078
- taskId: push.taskId,
3079
- prompt: push.prompt,
3080
- model: push.model,
3108
+ mailId: activePush.anchorId,
3109
+ taskId: activePush.taskId,
3110
+ prompt: activePush.prompt,
3111
+ model: activePush.model,
3081
3112
  apiKey: cursorApiKey,
3082
- workdir: push.workdir,
3083
- user: push.memberDisplayName,
3113
+ workdir: activePush.workdir,
3114
+ user: activePush.memberDisplayName,
3084
3115
  mode: cursorMode
3085
3116
  },
3086
3117
  {
@@ -3092,8 +3123,12 @@ async function runMailboxCursorAgentResume(push, options) {
3092
3123
  );
3093
3124
  if (result.hasPendingQuestions) {
3094
3125
  console.log(
3095
- `[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`
3096
3127
  );
3128
+ await api.cli.completeCursorAgentResume({
3129
+ anchorId: activePush.anchorId,
3130
+ status: "FAILED"
3131
+ });
3097
3132
  return;
3098
3133
  }
3099
3134
  const replyContent = (hasReplyContent() ? getReplyContent() : result.assistantText).trim();
@@ -3102,69 +3137,133 @@ async function runMailboxCursorAgentResume(push, options) {
3102
3137
  }
3103
3138
  if (cursorMode === "plan" && result.createPlanContent) {
3104
3139
  saveMemberPlanDocument({
3105
- workdir: push.workdir,
3106
- taskId: push.taskId,
3107
- memberDisplayName: push.memberDisplayName,
3140
+ workdir: activePush.workdir,
3141
+ taskId: activePush.taskId,
3142
+ memberDisplayName: activePush.memberDisplayName,
3108
3143
  content: result.createPlanContent
3109
3144
  });
3110
3145
  }
3111
3146
  await api.cli.completeMailboxMessage({
3112
- id: push.draftReplyId,
3147
+ id: activePush.draftReplyId,
3113
3148
  status: "SUCCEEDED",
3114
3149
  replyContent
3115
3150
  });
3116
- markMailReplied(push.anchorId);
3117
- await syncTaskDocuments(options.cfg, push.taskId, push.workdir, {
3118
- api,
3119
- remoteDocuments: detail.documents
3151
+ await api.cli.completeCursorAgentResume({
3152
+ anchorId: activePush.anchorId,
3153
+ status: "SUCCEEDED"
3120
3154
  });
3121
- 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}`);
3122
3166
  } catch (err) {
3123
3167
  const message = err instanceof Error ? err.message : String(err);
3124
3168
  console.error(
3125
- `[apm] Cursor Agent \u7EED\u804A\u5931\u8D25 mailId=${push.anchorId}: ${message}`
3169
+ `[apm] Cursor Agent \u7EED\u804A\u5931\u8D25 mailId=${activePush.anchorId}: ${message}`
3126
3170
  );
3127
3171
  try {
3172
+ await api.cli.completeCursorAgentResume({
3173
+ anchorId: activePush.anchorId,
3174
+ status: "FAILED"
3175
+ });
3128
3176
  await api.cli.completeMailboxMessage({
3129
- id: push.draftReplyId,
3177
+ id: activePush.draftReplyId,
3130
3178
  status: "FAILED",
3131
3179
  error: message
3132
3180
  });
3133
3181
  } catch (completeErr) {
3134
3182
  console.error(
3135
- `[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}:`,
3136
3184
  completeErr instanceof Error ? completeErr.message : completeErr
3137
3185
  );
3138
3186
  }
3139
- markMailReplied(push.anchorId);
3187
+ markMailReplied(activePush.anchorId);
3140
3188
  }
3141
3189
  }
3142
3190
  function createCursorAgentResumeHandler(options) {
3143
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
+ };
3144
3209
  return {
3145
- receive(push) {
3146
- if (options.signal.aborted) {
3210
+ syncPendingResumes(pushes) {
3211
+ if (pushes.length === 0) {
3147
3212
  return;
3148
3213
  }
3149
- if (running) {
3150
- console.warn(
3151
- `[apm] \u5DF2\u6709 Cursor Agent \u7EED\u804A\u4EFB\u52A1\u8FDB\u884C\u4E2D\uFF0C\u5FFD\u7565 mailId=${push.anchorId}`
3152
- );
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) {
3153
3220
  return;
3154
3221
  }
3155
- running = true;
3156
- void runMailboxCursorAgentResume(push, options).catch((err) => {
3157
- console.error(
3158
- `[apm] Cursor Agent \u7EED\u804A\u5F02\u5E38 mailId=${push.anchorId}:`,
3159
- err instanceof Error ? err.message : err
3160
- );
3161
- }).finally(() => {
3162
- running = false;
3163
- });
3222
+ queue.push(push);
3223
+ pump();
3164
3224
  }
3165
3225
  };
3166
3226
  }
3167
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
+
3168
3267
  // src/commands/connect/mail-sync.ts
3169
3268
  function parsePendingMail(value) {
3170
3269
  if (typeof value !== "object" || value === null) {
@@ -3299,6 +3398,8 @@ async function runConnect(options) {
3299
3398
  }
3300
3399
  const mails = await fetchPendingMails(cfg);
3301
3400
  mailProcessor.syncPendingMails(mails);
3401
+ const pendingResumes = await fetchPendingCursorAgentResumes(cfg);
3402
+ cursorAgentResumeHandler.syncPendingResumes(pendingResumes);
3302
3403
  } catch (err) {
3303
3404
  console.error(
3304
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.8",
3
+ "version": "7.0.9",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,