@arcships/morula-runtime 0.1.0-alpha.16 → 0.1.0-alpha.17

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.
package/dist/index.js CHANGED
@@ -740,7 +740,7 @@ var BUILD_ID, BUILD_CONTEXTS, BUILD_DEFAULT_CONTEXT;
740
740
  var init_build_env = __esm({
741
741
  "../morula-cli-core/dist/build-env.js"() {
742
742
  "use strict";
743
- BUILD_ID = "20260929103157.019b0b1c";
743
+ BUILD_ID = "20260930065011.80ac5142";
744
744
  BUILD_CONTEXTS = {
745
745
  "local": "http://localhost:8080/api",
746
746
  "test": "https://morula.basecastle.com/api",
@@ -841,13 +841,6 @@ var init_attachment = __esm({
841
841
  getDownloadUrl(id) {
842
842
  return this.client.get(`/attachments/${encodeURIComponent(id)}/download-url`);
843
843
  }
844
- /**
845
- * 读取附件的解析产物全文(MinerU markdown)。
846
- * 未解析/解析中/解析失败由服务端在返回体里说明,不当作 HTTP 错误。
847
- */
848
- content(id, maxChars) {
849
- return this.client.get(`/attachments/${encodeURIComponent(id)}/content`, { maxChars });
850
- }
851
844
  /** 更新附件关联的资源 ID */
852
845
  updateResourceId(id, resourceId) {
853
846
  return this.client.patch(`/attachments/${encodeURIComponent(id)}`, { resourceId });
@@ -4430,7 +4423,7 @@ init_dist2();
4430
4423
  init_dist2();
4431
4424
 
4432
4425
  // src/build-env.ts
4433
- var BUILD_VERSION2 = "0.1.0-alpha.16";
4426
+ var BUILD_VERSION2 = "0.1.0-alpha.17";
4434
4427
 
4435
4428
  // src/commands/daemon.ts
4436
4429
  init_dist();
@@ -5258,8 +5251,9 @@ var COLLABORATION_SKILL_BODY = `# Working on Morula issues\uFF08\u534F\u4F5C\u59
5258
5251
  morula repo checkout <taskId> <repoFullName> [--ref <branch|sha>] # \u62C9\u53D6/\u5207\u6362\u4ED3\u5E93\uFF08\u8FD4\u56DE\u7269\u5316\u8DEF\u5F84\uFF0C\u89C1 0.5\uFF09
5259
5252
  morula repo prepare <taskId> <repoFullName> # \u591A\u4ED3\u5E93\u4EFB\u52A1\uFF1A\u7269\u5316\u5176\u4ED6\u4ED3\u5E93\u5230\u4EFB\u52A1\u5DE5\u4F5C\u533A\u6839\u4E0B\uFF08\u89C1 0.5\uFF09
5260
5253
  morula comment list --object <objectId> # \u8BFB\u8BC4\u8BBA\uFF08\u4EFB\u52A1=objectId\uFF09
5254
+ morula comment add --object <objectId> --content <\u6587\u672C> # \u53D1\u8BC4\u8BBA\uFF08\u6700\u7EC8\u603B\u7ED3\u52A0 --final\uFF0C\u89C1\u7B2C 5 \u6761\uFF09
5261
5255
  morula task inbox [--peek] # \u8FD0\u884C\u4E2D\u68C0\u67E5\u70B9\uFF1A\u53D6\u672C\u7EBF\u7A0B\u672A\u6D88\u8D39\u6D88\u606F\uFF0C\u7EB3\u5165\u672C\u56DE\u5408\uFF08\u89C1 1.3\uFF09
5262
- # \u6CE8\uFF1A\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\u7531\u670D\u52A1\u7AEF\u7EDF\u4E00\u53D1\u9001\uFF08\u4F5C\u8005=\u667A\u80FD\u4F53\uFF09\uFF0C\u4E0D\u8981\u8C03\u7528 comment add \u81EA\u884C\u7F6E\u8BC4\u3002
5256
+ # \u6CE8\uFF1A\u4EFB\u52A1\u6536\u5C3E\u5148\u53D1 final \u603B\u7ED3\u8BC4\u8BBA\uFF08morula comment add --final\uFF09\uFF0C\u518D\u4E0A\u62A5\u7ED3\u679C\uFF1B\u670D\u52A1\u7AEF\u53EA\u5728\u4F60\u6CA1\u53D1\u65F6\u515C\u5E95\u4EE3\u53D1\u4E00\u6761\u3002
5263
5257
  \`\`\`
5264
5258
  - **\u53EF\u7528\u4ED3\u5E93\u6E05\u5355**\uFF1A\u7CFB\u7EDF\u63D0\u793A**\u4E0D\u518D\u5217\u51FA**\u4ED3\u5E93\u2014\u2014\u9700\u8981\u679A\u4E3E\u7A7A\u95F4\u7ED1\u5B9A\u7684\u4ED3\u5E93\u65F6\u7528
5265
5259
  \`morula repo list --space <spaceId>\`\uFF08\`<spaceId>\` \u89C1\u7CFB\u7EDF\u63D0\u793A\u300C\u57FA\u672C\u4FE1\u606F\u300D\u6BB5\uFF0C\u6216 \`morula task get\` \u8FD4\u56DE\u7684 \`contextSnapshot.spaceId\`\uFF09\u3002
@@ -5389,26 +5383,34 @@ morula task inbox --peek # \u53EA\u770B\u4E0D\u53D6\uFF08\u786E\u8BA4\u6709\
5389
5383
  - PR \u521B\u5EFA\u88AB\u963B\u585E\uFF08\u6743\u9650/\u6D4B\u8BD5\u5931\u8D25/\u8FDC\u7AEF\u72B6\u6001\u5F02\u5E38\uFF09\u2192 \u5728\u6700\u7EC8\u603B\u7ED3\u4E2D**\u62A5\u544A\u963B\u585E\u539F\u56E0**\uFF0C\u4E0D\u8981\u5047\u88C5\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF1B
5390
5384
  - **\u4E0D\u8981**\u5207\u56DE \`main\` \u6216 \`master\` \u76F4\u63A5\u63D0\u4EA4\u3002
5391
5385
 
5392
- ## 4. \u72B6\u6001\u53D8\u66F4\u7531\u670D\u52A1\u7AEF\u9A71\u52A8\uFF0C\u4E0D\u8981\u624B\u52A8\u7FFB\u72B6\u6001
5386
+ ## 4. \u72B6\u6001\u4E0E\u4EFB\u52A1\u64CD\u4F5C\uFF1A\u7ED3\u8BBA\u4F18\u5148\uFF0C\u52A8\u4F5C\u4E3A\u8F85
5393
5387
 
5394
- - \u4EFB\u52A1\u72B6\u6001\u63A8\u8FDB\uFF08\u5982\u5B8C\u6210\uFF09\u7531 PR merge \u4E8B\u4EF6\u81EA\u52A8\u89E6\u53D1\uFF08\u914D\u5408\u7B2C 2 \u6761\u7684\u5173\u5355\u5199\u6CD5\uFF09\u3002
5395
- - \u4E0D\u8981\u76F4\u63A5\u8C03 CLI \u6539\u4EFB\u52A1\u72B6\u6001\uFF1B\u628A\u72B6\u6001\u6D41\u8F6C\u4EA4\u7ED9\u670D\u52A1\u7AEF\u3002
5388
+ - **\u72B6\u6001\u63A8\u8FDB\u7531\u7ED3\u8BBA\u534F\u8BAE\u4E0E\u4E8B\u5B9E\u4E8B\u4EF6\u9A71\u52A8**\uFF1A\u5206\u6790\u4EFB\u52A1\u4E0A\u62A5 \`analysis-verdict\`\u3001\u8BC4\u5BA1\u4EFB\u52A1\u7528 \`morula review submit\`\u3001\u5408\u5E76/\u53D1\u5E03\u7531 PR \u4E8B\u4EF6\u9A71\u52A8\u2014\u2014**\u4E0D\u8981**\u7528\u72B6\u6001\u52A8\u4F5C\u66FF\u4EE3\u7ED3\u8BBA\u534F\u8BAE\u3002
5389
+ - **\u4F60\u53EF\u4EE5\u5728\u4EFB\u52A1\u4E0A\u505A\u57FA\u7840\u64CD\u4F5C**\uFF08\u50CF\u4EBA\u4E00\u6837\uFF0C\u4F5C\u7528\u57DF\u4EC5\u9650\u672C\u4EFB\u52A1\uFF09\uFF1A
5390
+ - \`morula task state <taskId> --state <in_progress|review> [--reason <\u6587\u672C>]\`\uFF1A\u5728\u300C\u5F00\u53D1\u4E2D / \u5F85\u8BC4\u5BA1\u300D\u8303\u56F4\u5185\u81EA\u63A8\u72B6\u6001\uFF1B**\u5F85\u8BC4\u5BA1 \u2192 \u5F00\u53D1\u4E2D = \u9000\u56DE\u5F00\u53D1**\u2014\u2014\u5E73\u53F0\u4F1A\u81EA\u52A8\u56DE\u9000\u72B6\u6001\u3001\u8BB0\u8BC4\u5BA1\u8F6E\u6B21\u5E76\u6D3E\u53D1\u4FEE\u590D\u4EFB\u52A1\uFF08\u540C\u4E00 PR \u8FED\u4EE3\uFF09\uFF0C**\u4E0D\u9700\u8981\u3001\u4E5F\u4E0D\u5E94\u8BE5**\u518D\u81EA\u5DF1 @ \u5F00\u53D1\u6267\u884C\u5668\uFF1B\`--reason\` \u5199\u660E\u9000\u56DE\u539F\u56E0\uFF08\u4F1A\u8FDB\u4FEE\u590D\u4EFB\u52A1 prompt\uFF09\u3002
5391
+ - \`morula comment add\`\uFF1A\u89C1\u7B2C 5 \u6761\u8BC4\u8BBA\u7EAA\u5F8B\u3002
5392
+ - \`morula task assign <taskId> --to <principalId>\`\uFF1A\u6307\u6D3E\u672C\u4EFB\u52A1\u8D1F\u8D23\u4EBA\uFF08\u672C\u7A7A\u95F4\u6210\u5458\u6216\u9636\u6BB5\u6267\u884C\u5668\uFF1B\u76EE\u6807\u4E0D\u5B58\u5728\u4F1A\u663E\u5F0F\u62A5\u9519\uFF09\u3002
5393
+ - **\u7EC8\u6001\uFF08\u5DF2\u5408\u5E76/\u5DF2\u53D1\u5E03/\u5DF2\u5173\u95ED\uFF09\u4E0E\u9700\u6C42\u6C60\u72B6\u6001\u4E0D\u7531\u4F60\u58F0\u660E**\uFF1B\u540C\u6001\u91CD\u590D\u63A8\u9001\u662F\u5E42\u7B49\u7684\uFF08\u65E0\u5BB3\uFF09\u3002
5396
5394
 
5397
5395
  ## 4.1 \u5206\u6790\u4EFB\u52A1\uFF1A\u5FC5\u987B\u4E0A\u62A5\u5206\u6790\u7ED3\u8BBA\uFF08verdict\uFF09
5398
5396
 
5399
5397
  > **\u4EC5\u5F53\u672C\u4EFB\u52A1\u662F\u300C\u5F85\u5206\u6790\u300D\u4EFB\u52A1\u65F6\u9002\u7528**\uFF08\u4EFB\u52A1\u505C\u5728\u300C\u5F85\u5206\u6790\u300D\u9636\u6BB5\u3001\u8981\u6C42\u505A\u9700\u6C42\u5206\u6790\u4E0E\u65B9\u6848\u62C6\u89E3\u3001\u4E0D\u5199\u4EE3\u7801\uFF09\u3002
5400
5398
  > \u5176\u4F59\u4EFB\u52A1\uFF08\u5F00\u53D1 / \u8BC4\u5BA1 / \u8C03\u7814 / \u95EE\u7B54\uFF09\u8DF3\u8FC7\u672C\u8282\uFF0C\u4E0D\u8981\u8C03\u7528\u8BE5\u547D\u4EE4\u3002
5401
5399
 
5402
- - \u5206\u6790\u7ED3\u8BBA\u5206\u4E24\u90E8\u5206\uFF0C**\u90FD\u8981\u7ED9**\uFF1A
5403
- 1. **\u4EBA\u770B\u7684**\uFF1A\u5206\u6790\u7ED3\u8BBA\u5199\u8FDB\u6700\u7EC8\u8F93\u51FA\uFF08\u9700\u6C42\u662F\u5426\u6E05\u6670\u3001\u600E\u4E48\u505A\u3001\u8303\u56F4\u4E0E\u98CE\u9669\u3001\u9A8C\u6536\u70B9\uFF09\u2014\u2014\u670D\u52A1\u7AEF\u4F5C\u4E3A\u4EFB\u52A1\u8BC4\u8BBA\u53D1\u5E03\uFF1B
5404
- 2. **\u673A\u5668\u5224\u5B9A\u7684**\uFF1A\u6267\u884C \`morula task analysis-verdict <taskId> --verdict ready|blocked [--reason "\u2026"]\` \u4E0A\u62A5\u7ED3\u8BBA\u3002
5400
+ - \u5206\u6790\u7ED3\u8BBA\u5206\u4E24\u90E8\u5206\uFF0C**\u90FD\u8981\u7ED9**\uFF08\u987A\u5E8F\uFF1A\u5148\u53D1\u8BC4\u8BBA\uFF0C\u518D\u4E0A\u62A5 verdict\uFF09\uFF1A
5401
+ 1. **\u4EBA\u770B\u7684**\uFF1A\u7528**\u4F60\u81EA\u5DF1\u7684\u8BDD**\u628A\u5206\u6790\u7ED3\u8BBA\u53D1\u6210\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\u2014\u2014\u9700\u6C42\u662F\u5426\u6E05\u6670\u3001\u600E\u4E48\u505A\u3001\u8303\u56F4\u4E0E\u98CE\u9669\u3001\u9A8C\u6536\u70B9\uFF1A
5402
+ \`\`\`bash
5403
+ morula comment add --object <objectId> --final --content <\u4F60\u7684\u5206\u6790\u7ED3\u8BBA>
5404
+ \`\`\`
5405
+ \u8FD9\u662F\u7528\u6237\u770B\u5230\u7684\u5206\u6790\u4EA4\u4ED8\uFF1A\u7528\u81EA\u5DF1\u7684\u8BDD\u5199\uFF0C\u4E0D\u8981\u5957\u56FA\u5B9A\u683C\u5F0F\uFF0C\u66F4\u4E0D\u8981\u590D\u8FF0\u4EFB\u52A1\u63CF\u8FF0\uFF1B\u7ED3\u8BBA\u5148\u8BF4\u3001\u7406\u7531\u8DDF\u4E0A\u3002
5406
+ 2. **\u673A\u5668\u5224\u5B9A\u7684**\uFF1A\u6267\u884C \`morula task analysis-verdict <taskId> --verdict ready|blocked [--reason "\u2026"]\` \u4E0A\u62A5\u7ED3\u8BBA\uFF08\`--reason\` \u53EA\u9700\u4E00\u53E5\u8BDD\uFF0C\u8BE6\u7EC6\u5185\u5BB9\u5728\u8BC4\u8BBA\u91CC\uFF09\u3002
5405
5407
  - \`<taskId>\` = \`morula task get\`\uFF08\u65E0\u53C2\uFF09\u8FD4\u56DE\u7684 \`id\`\uFF08\u672C\u4EFB\u52A1 AgentTask UUID\uFF09\u3002
5406
5408
  - **\`ready\`** = \u9700\u6C42\u6E05\u6670\u3001\u53EF\u76F4\u63A5\u5F00\u53D1\uFF08\`--reason\` \u53EF\u5199\u4E00\u53E5\u8BDD\u8303\u56F4\u6458\u8981\uFF09\uFF1B
5407
5409
  **\`blocked\`** = \u4E0D\u53EF\u505A / \u9700\u6F84\u6E05\uFF08**\u5FC5\u987B**\u5728 \`--reason\` \u6216\u6700\u7EC8\u8F93\u51FA\u91CC\u5199\u6E05\u963B\u585E\u70B9\u4E0E\u9700\u8981\u6F84\u6E05\u7684\u95EE\u9898\uFF09\u3002
5408
5410
  - **\u670D\u52A1\u7AEF\u636E\u6B64\u81EA\u52A8\u63A8\u8FDB\uFF0C\u4E0D\u9700\u8981\u4EFB\u4F55\u4EBA\u70B9\u786E\u8BA4**\uFF1A\`ready\` \u2192 \u4EFB\u52A1\u81EA\u52A8\u8FDB\u5165\u300C\u5F00\u53D1\u4E2D\u300D\u5E76\u6D3E\u53D1\u5F00\u53D1\u4EFB\u52A1\uFF1B
5409
5411
  \`blocked\` / \u672A\u4E0A\u62A5 \u2192 \u4EFB\u52A1**\u505C\u5728\u300C\u5F85\u5206\u6790\u300D**\uFF0C\u7531\u7528\u6237\u8865\u5145\u9700\u6C42\u540E\u91CD\u6D3E\u5206\u6790\u3002
5410
5412
  - **\u5FC5\u987B\u4E0A\u62A5**\uFF1A\u6F0F\u62A5\u4F1A\u8BA9\u4EFB\u52A1\u9759\u9ED8\u505C\u5728\u300C\u5F85\u5206\u6790\u300D\uFF1B\u540C\u4E00\u4EFB\u52A1\u53EA\u9700\u4E0A\u62A5\u4E00\u6B21\uFF08\u91CD\u590D\u4E0A\u62A5\u4EE5\u9996\u6B21\u4E3A\u51C6\uFF0C\u4E0D\u4F1A\u6539\u5199\uFF09\u3002
5411
- - **\u4E0D\u8981\u624B\u52A8\u6D41\u8F6C\u672C\u4EFB\u52A1\u72B6\u6001**\uFF08\u4E0D\u8981\u8C03 \`morula task state\`\uFF09\uFF1A\u5206\u6790\u4EFB\u52A1\u7684\u63A8\u8FDB\u7531\u670D\u52A1\u7AEF\u6309 verdict \u51B3\u5B9A\u3002
5413
+ - \u5206\u6790\u4EFB\u52A1\u7684\u63A8\u8FDB\u7531\u670D\u52A1\u7AEF\u6309 verdict \u51B3\u5B9A\u2014\u2014**\u4E0D\u8981\u7528\u72B6\u6001\u52A8\u4F5C\u66FF\u4EE3\u5206\u6790\u7ED3\u8BBA**\uFF08\u4E0D\u8981\u8C03 \`morula task state\`\uFF09\u3002
5412
5414
 
5413
5415
  ## 4.2 \u8BC4\u5BA1\u4EFB\u52A1\uFF1A\u53EA\u8BFB\u8BC4\u5BA1 + \u5FC5\u987B\u56DE\u4F20\u7ED3\u8BBA\uFF08verdict\uFF09
5414
5416
 
@@ -5429,9 +5431,11 @@ morula task inbox --peek # \u53EA\u770B\u4E0D\u53D6\uFF08\u786E\u8BA4\u6709\
5429
5431
  - \`<objectId>\` = \`morula task get\`\uFF08\u65E0\u53C2\uFF09\u8FD4\u56DE\u7684 \`objectId\`\uFF1B
5430
5432
  - \`--verdict\`\uFF1A\`approved\`\uFF08\u901A\u8FC7\uFF09/ \`changes_requested\`\uFF08\u4E0D\u901A\u8FC7\uFF0C**\u5FC5\u987B**\u5728 \`--details\` \u5199\u660E\u5177\u4F53\u610F\u89C1\uFF1A\u6587\u4EF6/\u884C/\u95EE\u9898/\u5EFA\u8BAE\uFF0C\u5426\u5219\u5F00\u53D1\u65E0\u6CD5\u4FEE\u590D\uFF09/ \`commented\`\uFF08\u6709\u610F\u89C1\u4F46\u4E0D\u963B\u585E\uFF09\uFF1B
5431
5433
  - \`--pr-number\`\uFF1A\u8BC4\u5BA1\u5BF9\u8C61\u7684 PR \u7F16\u53F7\uFF08\u6709\u5219\u586B\uFF09\u3002
5434
+ - **\u8BC4\u5BA1\u4EFB\u52A1\u7684\u4EA4\u4ED8\u5C31\u662F\u8FD9\u4EFD\u7ED3\u8BBA**\uFF1A\u5E73\u53F0\u4F1A\u6309\u7ED3\u8BBA\u5199\u6743\u5A01\u8BC4\u8BBA\uFF08\u2705/\u{1F4AC}/\u{1F501}\uFF09\u2014\u2014**\u4E0D\u8981**\u518D\u53D1\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\uFF08\`--final\` \u4F1A\u88AB\u670D\u52A1\u7AEF\u62D2\u7EDD\uFF09\uFF0C\u4E5F\u4E0D\u8981\u5728\u8BC4\u8BBA\u533A\u590D\u8FF0\u7ED3\u8BBA\u3002
5435
+ - **\u7ED3\u8BBA\u65B0\u9C9C\u5EA6\uFF08\u65E0\u65B0\u63D0\u4EA4\u4E0D\u91CD\u590D\u6295 \`approved\`\uFF09**\uFF1A\u63D0\u4EA4\u7ED3\u8BBA\u524D\u5148\u6838\u5BF9\u88AB\u8BC4\u5BA1 MR \u7684 head commit \u4E0E\u4E0A\u4E00\u8F6E\u7ED3\u8BBA\u65F6\u662F\u5426\u76F8\u540C\uFF08\`morula repo mr list\` / \`mr-detail\`\uFF1B\u8BC4\u8BBA\u533A\u4E5F\u6709\u4E0A\u4E00\u8F6E\u7ED3\u8BBA\uFF09\u3002**\u76F8\u540C\u4E14\u65E0\u65B0\u63D0\u4EA4\u65F6\u4E0D\u8981\u91CD\u590D\u6295 \`approved\`**\uFF1A\u672C\u8F6E\u4EFB\u52A1\u4E0A\u4E0B\u6587\u91CC\u6709\u4EBA\u7684\u65B0\u8981\u6C42\uFF08\u5982\u8981\u6C42\u4FEE\u590D\u4E0A\u4E00\u8F6E\u610F\u89C1\uFF09\u2192 \u6309\u4EBA\u7684\u8981\u6C42\u5904\u7406\uFF08\u610F\u89C1\u672A\u4FEE\u590D\u5C31\u6295 \`changes_requested\`\uFF09\uFF1B\u786E\u5B9E\u65E0\u53EF\u8BC4\u5BA1\u5185\u5BB9 \u2192 \u6295 \`commented\` \u8BF4\u660E\u300C\u65E0\u65B0\u63D0\u4EA4\u300D\u5373\u53EF\u3002\u590D\u8FF0\u4E0A\u4E00\u8F6E\u7ED3\u8BBA\u5BF9\u4EFB\u52A1\u6CA1\u6709\u4EFB\u4F55\u63A8\u8FDB\u3002
5432
5436
  - **\u7981\u6B62\u8BC4\u5BA1\u81EA\u5DF1\u5F00\u53D1\u7684\u4EFB\u52A1**\uFF1A\u82E5\u5F85\u8BC4\u5BA1\u6539\u52A8\u7531\u4F60\u81EA\u5DF1\u63D0\u4EA4\uFF08\u540C\u4E00\u667A\u80FD\u4F53\u65E2\u5F00\u53D1\u53C8\u8BC4\u5BA1\uFF09\uFF0C\u4E0D\u4E0B\u7ED3\u8BBA\uFF0C\u76F4\u63A5\u62A5\u544A\u8BE5\u914D\u7F6E\u95EE\u9898\u3002
5433
- - **\u4E0D\u8981\u624B\u52A8\u6D41\u8F6C\u672C\u4EFB\u52A1\u72B6\u6001**\uFF08\u4E0D\u8981\u8C03 \`morula task state\`\uFF09\uFF1A\u8BC4\u5BA1\u7ED3\u8BBA\u7531\u670D\u52A1\u7AEF\u636E\u6B64\u63A8\u8FDB\u3002
5434
5437
  - **\u5FC5\u987B\u4E0A\u62A5**\uFF1A\u6F0F\u62A5\u4F1A\u8BA9\u4EFB\u52A1\u505C\u5728\u300C\u5F85\u8BC4\u5BA1\u300D\uFF0C\u5F00\u53D1\u65E0\u6CD5\u8FDB\u5165\u4E0B\u4E00\u8F6E\u3002
5438
+ - \u9000\u56DE\u5F00\u53D1**\u9996\u9009\u7ED3\u8BBA\u534F\u8BAE**\uFF1A\`--verdict changes_requested\`\uFF08\u5E26\u5177\u4F53\u610F\u89C1\uFF09\u4E0E\u670D\u52A1\u7AEF\u7ED3\u8BBA\u94FE\u8DEF\u5B8C\u5168\u7B49\u4EF7\uFF1B\`morula task state --state in_progress\` \u662F\u7B49\u4EF7\u7684\u66FF\u4EE3\u5165\u53E3\uFF08\u89C1\u7B2C 4 \u6761\uFF09\uFF0C\u4E0D\u662F\u7ED5\u8FC7\u3002
5435
5439
 
5436
5440
  ## 4.3 \u5728 MR/PR \u4E0A\u7559\u8BC4\u5BA1\u610F\u89C1\uFF08\u5DE1\u68C0/\u5BA1\u67E5\u7C7B\u4EFB\u52A1\uFF0C\u975E\u8BC4\u5BA1\u4EFB\u52A1\u65F6\uFF09
5437
5441
 
@@ -5447,36 +5451,30 @@ morula task inbox --peek # \u53EA\u770B\u4E0D\u53D6\uFF08\u786E\u8BA4\u6709\
5447
5451
  - \u82E5\u672C\u81EA\u52A8\u5316\u5DF2\u5C31\u540C\u4E00\u95EE\u9898\u7559\u8FC7\u8BC4\u8BBA\u3001\u7ED3\u8BBA\u4E0E\u8FD9\u6B21\u4E00\u81F4 \u2192 **\u4E0D\u8981\u91CD\u590D\u8BC4\u8BBA**\uFF1B
5448
5452
  - \u26D4 **\u4E0D\u8981\u7528 \`morula review submit\`**\uFF08\u90A3\u662F\u8BC4\u5BA1\u4EFB\u52A1\u7684\u673A\u5668\u534F\u8BAE\uFF0C\u4F1A\u9A71\u52A8\u4E1A\u52A1\u4EFB\u52A1\u72B6\u6001\u56DE\u9000\uFF09\u3002
5449
5453
 
5450
- ## 5. \u8BC4\u8BBA\u4EA4\u4ED8\u7EAA\u5F8B
5451
-
5452
- - **\u4F55\u65F6\u53D1\u8BC4\u8BBA**\uFF1A**\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\u7531\u670D\u52A1\u7AEF\u7EDF\u4E00\u4EE5\u667A\u80FD\u4F53\u8EAB\u4EFD\u53D1\u9001**\uFF08\u4EFB\u52A1\u5B8C\u6210\u65F6\u81EA\u52A8\u53D1\u5E03\u5230\u4EFB\u52A1\u5BF9\u8C61\uFF0C\u4F5C\u8005=\u5F53\u524D\u667A\u80FD\u4F53\uFF09\u3002**\u4F60\u4E0D\u9700\u8981\u3001\u4E5F\u4E0D\u5E94\u8C03\u7528 \`morula comment add\`**\u2014\u2014\u53EA\u8981\u5728\u6700\u7EC8\u8F93\u51FA\u91CC\u7ED9\u51FA\u7528\u6237\u5173\u5FC3\u7684\u7ED3\u8BBA\u5373\u53EF\uFF0C\u670D\u52A1\u7AEF\u4F1A\u4F5C\u4E3A\u8BE5\u667A\u80FD\u4F53\u7684\u5B8C\u6210\u8BC4\u8BBA\u53D1\u5E03\u3002chat \u4F1A\u8BDD\u65E0 objectId \u7684\u4EFB\u52A1\uFF08\u7EAF\u5BF9\u8BDD\u6D3E\u53D1\uFF09\u4E0D\u56DE\u8BC4\u8BBA\u2014\u2014\u6700\u7EC8\u4EA4\u4ED8\u7531 daemon \u56DE\u586B assistant \u6D88\u606F\u3002
5453
- - **\u7EC8\u7AEF\u8F93\u51FA\u3001\u601D\u8003\u8FC7\u7A0B\u3001\u5DE5\u5177\u65E5\u5FD7\u7528\u6237\u90FD\u770B\u4E0D\u5230**\u2014\u2014\u7528\u6237\u770B\u5230\u7684\u53EA\u6709\u670D\u52A1\u7AEF\u6574\u5408\u540E\u53D1\u5E03\u7684\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\u3002
5454
- - **\u8BC4\u8BBA @\u89E6\u53D1\u4EFB\u52A1\uFF08\u672C\u4EFB\u52A1\u7531\u8BC4\u8BBA\u89E6\u53D1\uFF09**\uFF1A\u670D\u52A1\u7AEF\u4F1A\u628A\u6700\u7EC8\u603B\u7ED3\u81EA\u52A8\u4F5C\u4E3A**\u8BE5\u89E6\u53D1\u8BC4\u8BBA\u7684\u56DE\u590D**\u53D1\u51FA\uFF08\u6302\u5728\u88AB @ \u7684\u8BC4\u8BBA\u4E0B\uFF09\u3002\u4F60\u65E0\u9700\u3001\u4E5F\u4E0D\u8981\u81EA\u5DF1\u8C03\u7528 \`morula comment add\`/add_comment\u3002
5455
- - **\u9632\u91CD\u590D\uFF08\u670D\u52A1\u7AEF\u4FDD\u8BC1\uFF09**\uFF1A\u670D\u52A1\u7AEF\u5BF9\u300C\u540C\u4E00\u4E2A\u4EFB\u52A1\u53EA\u53D1\u4E00\u6761\u5B8C\u6210\u8BC4\u8BBA\u300D\u505A\u5E42\u7B49\uFF0C\u4E0D\u4F1A\u91CD\u590D\u5237\u5C4F\u3002\u4F60\u4E0D\u9700\u8981\u3001\u4E5F\u4E0D\u8981\u53BB\u67E5/\u53D1\u591A\u6761\u3002
5456
- - **\u6700\u7EC8\u8F93\u51FA = \u53EA\u7559\u7ED3\u8BBA**\uFF08\u4E0D\u8BBE\u5B57\u6570\u4E0A\u9650\u3001\u4E0D\u8981\u6C42\u56FA\u5B9A\u683C\u5F0F\uFF0C\u81EA\u7136\u7EC4\u7EC7\u5373\u53EF\uFF09\uFF1A
5457
- - \u5FC5\u7B54\uFF1A**\u505A\u4E86\u4EC0\u4E48\u3001\u7ED3\u679C\u5982\u4F55\u3001\u7528\u6237\u9700\u8981\u77E5\u9053\u7684\u540E\u7EED**\u3002
5458
- - **PR \u6C47\u62A5\u4EC5\u5F53\u300C\u4EFB\u52A1\u6D89\u53CA\u4EE3\u7801\u6539\u52A8\u300D\u6216\u300C\u7528\u6237\u660E\u786E\u95EE\u5230 PR/\u5408\u5E76\u300D\u65F6\u7ED9\u51FA**\uFF1B\u7EAF\u95EE\u7B54/\u8C03\u7814\u7C7B\u4EFB\u52A1\u4E0D\u8981\u51FA\u73B0 PR/\u5206\u652F\u7AE0\u8282\uFF0C\u76F4\u63A5\u56DE\u7B54\u95EE\u9898\u3002
5459
- - **\u4E0D\u8981\u5199**\uFF1A\u601D\u8003\u8FC7\u7A0B\u3001\u63A2\u7D22\u6B65\u9AA4\u3001\u5DE5\u5177\u65E5\u5FD7\u3001\u7EC8\u7AEF\u8F93\u51FA\u3001\u82F1\u6587\u8FC7\u7A0B\u6027\u53D9\u8FF0\u2014\u2014\u7528\u6237\u53EA\u5173\u5FC3\u300C\u505A\u4E86\u4EC0\u4E48\u3001\u7ED3\u679C\u600E\u6837\u300D\uFF0C\u4E0D\u5173\u5FC3\u300C\u600E\u4E48\u505A\u7684\u300D\u3002
5460
- - \u5185\u5BB9\u8F83\u591A\u65F6\u7528\u5C0F\u6807\u9898/\u5217\u8868\u7EC4\u7EC7\uFF0C\u8BA9\u7ED3\u8BBA\u5148\u7F6E\u9876\u3002
5461
- - **\u8FC7\u7A0B\u6587\u672C\u5FC5\u987B\u52A0\u5206\u9694\u7B26**\uFF1A\u670D\u52A1\u7AEF\u53D6\u4F60\u7684\u6700\u7EC8\u8F93\u51FA\u65F6\u6309\u4F18\u5148\u7EA7\u622A\u53D6\u300C\u603B\u7ED3\u6BB5\u300D\uFF0C**\u6700\u9AD8\u4F18\u5148\u7EA7\u662F\u5206\u9694\u7B26 \`---FINAL---\`**\uFF08\u72EC\u5360\u4E00\u884C\u3001\u524D\u540E\u5404\u7A7A\u4E00\u884C\uFF09\u3002\u82E5\u4F60\u7684\u8F93\u51FA\u91CC\u6DF7\u5165\u4E86\u4E2D\u95F4\u8FC7\u7A0B\uFF08\u82F1\u6587\u63A2\u7D22\u53D9\u8FF0\u3001\u5DE5\u5177\u5C1D\u8BD5\u8BB0\u5F55\u3001\u601D\u8003\u7247\u6BB5\uFF09\uFF0C**\u5FC5\u987B**\u5728\u771F\u6B63\u7684\u603B\u7ED3\u4E4B\u524D\u63D2\u5165\u8BE5\u5206\u9694\u7B26\u2014\u2014\u670D\u52A1\u7AEF\u53EA\u4FDD\u7559\u5B83\u4E4B\u540E\u7684\u5185\u5BB9\uFF1A
5454
+ ## 5. \u8BC4\u8BBA\u4EA4\u4ED8\u7EAA\u5F8B\uFF08\u6700\u7EC8\u603B\u7ED3\u7531\u4F60\u81EA\u5DF1\u53D1\u5E03\uFF09
5462
5455
 
5456
+ - **\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\u7531\u4F60\u81EA\u5DF1\u53D1\u5E03**\uFF1A\u4EFB\u52A1\u6536\u5C3E\u65F6\u6267\u884C
5457
+ \`\`\`bash
5458
+ morula comment add --object <objectId> --final --content <\u7ED3\u8BBA>
5463
5459
  \`\`\`
5464
- ...\uFF08\u524D\u9762\u7684\u8FC7\u7A0B\u6587\u672C\uFF0C\u4F1A\u88AB\u670D\u52A1\u7AEF\u81EA\u52A8\u622A\u6389\uFF09...
5465
-
5466
- ---FINAL---
5467
-
5468
- ## \u603B\u7ED3
5469
-
5470
- ...\uFF08\u771F\u6B63\u7684\u603B\u7ED3\u5185\u5BB9\uFF0C\u4F1A\u5C55\u793A\u7ED9\u7528\u6237\uFF09...
5460
+ \u4F5C\u8005=\u4F60\uFF08\u667A\u80FD\u4F53\u8EAB\u4EFD\uFF09\uFF1B\u8BC4\u8BBA\u89E6\u53D1\u4EFB\u52A1\u65F6\u670D\u52A1\u7AEF\u4F1A**\u81EA\u52A8\u628A\u5B83\u6302\u5230\u89E6\u53D1\u8BC4\u8BBA\u4E0B**\u4F5C\u4E3A\u56DE\u590D\uFF08\u65E0\u9700\u81EA\u5DF1\u67E5\u8BC4\u8BBA ID\uFF09\u3002
5461
+ **\u5148\u53D1 final \u8BC4\u8BBA\u3001\u518D\u4E0A\u62A5\u4EFB\u52A1\u7ED3\u679C**\u2014\u2014\u670D\u52A1\u7AEF\u5728\u4F60\u5B8C\u6210\u65F6\u68C0\u67E5\uFF1A\u6CA1\u53D1\u8FC7 final \u624D\u4F1A\u515C\u5E95\u4EE3\u53D1\u4E00\u6761\uFF08\u540C\u4E00\u4EFB\u52A1\u53EA\u4F1A\u4FDD\u7559\u4E00\u6761\u6700\u7EC8\u603B\u7ED3\uFF0C\u91CD\u590D\u53D1\u9001\u4F1A\u88AB\u670D\u52A1\u7AEF\u62D2\u7EDD\uFF0C\u8FD9\u662F\u9884\u671F\u5185\u7684\u5E42\u7B49\u4FDD\u62A4\uFF09\u3002
5462
+ - **\u4F8B\u5916\uFF1A\u8BC4\u5BA1\u4EFB\u52A1\u4E0D\u9700\u8981\uFF08\u4E5F\u4E0D\u5E94\uFF09\u53D1 final**\u2014\u2014\u4F60\u7684\u7ED3\u8BBA\u5DF2\u7ECF\u901A\u8FC7 \`morula review submit\` \u673A\u5668\u534F\u8BAE\u4E0A\u62A5\uFF0C\u5E73\u53F0\u4F1A\u636E\u6B64\u5199\u6743\u5A01\u7ED3\u8BBA\u8BC4\u8BBA\uFF08\u2705 \u901A\u8FC7 / \u{1F4AC} \u975E\u963B\u585E / \u{1F501} \u672A\u901A\u8FC7\uFF09\uFF1B\u518D\u53D1\u4E00\u6761 final \u603B\u7ED3\u4F1A\u8BA9\u540C\u4E00\u7ED3\u8BBA\u5728\u8BC4\u8BBA\u533A**\u8BF4\u4E24\u904D**\uFF08\u670D\u52A1\u7AEF\u4E5F\u4F1A\u62D2\u7EDD\u8BC4\u5BA1\u4EFB\u52A1\u7684 final\uFF09\u3002\u9700\u8981\u53D1 final \u7684\u662F\u5F00\u53D1 / \u4FEE\u590D / \u5206\u6790 / \u95EE\u7B54 / \u8BC4\u8BBA\u89E6\u53D1\u7C7B\u4EFB\u52A1\u2014\u2014\u5185\u5BB9**\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u5199**\uFF0C\u4E0D\u8981\u5957\u6A21\u677F\u3002
5463
+ - **\u666E\u901A\u8BC4\u8BBA**\uFF08\u8BF4\u660E\u8FDB\u5C55\u3001@ \u5176\u4ED6\u4EBA\u6216\u8FD0\u884C\u65F6\uFF09\u968F\u65F6\u53EF\u53D1\uFF1A
5464
+ \`\`\`bash
5465
+ morula comment add --object <objectId> --content <\u6587\u672C>
5466
+ morula comment add --object <objectId> --content <\u6587\u672C> --mention-agent <stageExecutorId> # @ \u9636\u6BB5\u8FD0\u884C\u65F6\uFF08\u89E6\u53D1\u8BE5\u6267\u884C\u5668\u5728\u672C\u4EFB\u52A1\u4E0A\u5E72\u6D3B\uFF09
5471
5467
  \`\`\`
5472
-
5473
- \u670D\u52A1\u7AEF\u540C\u65F6\u517C\u5BB9 \`---SUMMARY---\`\u3002**\u4E0D\u5199\u5206\u9694\u7B26\u65F6**\uFF0C\u670D\u52A1\u7AEF\u53EA\u80FD\u9000\u56DE\u300C\u6309\u603B\u7ED3\u7C7B\u6807\u9898 / \u6C34\u5E73\u7EBF\u731C\u6D4B\u300D\uFF0C\u731C\u4E0D\u4E2D\u5C31\u4F1A\u628A\u4F60\u7684\u8FC7\u7A0B\u6587\u672C\u4E00\u8D77\u53D1\u7ED9\u7528\u6237\u2014\u2014\u6240\u4EE5\u6DF7\u4E86\u8FC7\u7A0B\u5C31\u4E00\u5B9A\u8981\u52A0\u3002
5474
- - \u4E0D\u8981\u5305\u542B\u5DE5\u5177\u8C03\u8BD5\u8FC7\u7A0B\u3001\u5185\u90E8\u65E5\u5FD7\u3001\u4EFB\u4F55\u51ED\u636E\u6216 token \u4FE1\u606F\u3002
5468
+ chat \u4F1A\u8BDD\u65E0 objectId \u7684\u4EFB\u52A1\uFF08\u7EAF\u5BF9\u8BDD\u6D3E\u53D1\uFF09\u4E0D\u53D1\u8BC4\u8BBA\u2014\u2014\u6700\u7EC8\u4EA4\u4ED8\u7531 daemon \u56DE\u586B assistant \u6D88\u606F\u3002
5469
+ - **\u8BC4\u8BBA\u7EAA\u5F8B\uFF1A\u53EA\u5199\u7ED3\u8BBA\u4E0E\u4E8B\u5B9E**\u2014\u2014\u505A\u4E86\u4EC0\u4E48\u3001\u7ED3\u679C\u5982\u4F55\u3001\u7528\u6237\u9700\u8981\u77E5\u9053\u7684\u540E\u7EED\uFF1B**\u4E0D\u5199**\u601D\u8003\u8FC7\u7A0B\u3001\u63A2\u7D22\u6B65\u9AA4\u3001\u5DE5\u5177\u65E5\u5FD7\u3001\u7EC8\u7AEF\u8F93\u51FA\u3001\u547D\u4EE4\u56DE\u663E\u3002\u7528\u6237\u53EA\u5173\u5FC3\u300C\u505A\u4E86\u4EC0\u4E48\u3001\u7ED3\u679C\u600E\u6837\u300D\uFF0C\u4E0D\u5173\u5FC3\u300C\u600E\u4E48\u505A\u7684\u300D\u3002\u5185\u5BB9\u8F83\u591A\u65F6\u7528\u5C0F\u6807\u9898/\u5217\u8868\u7EC4\u7EC7\uFF0C\u7ED3\u8BBA\u5148\u7F6E\u9876\u3002
5470
+ - **PR \u6C47\u62A5\u4EC5\u5F53\u300C\u4EFB\u52A1\u6D89\u53CA\u4EE3\u7801\u6539\u52A8\u300D\u6216\u300C\u7528\u6237\u660E\u786E\u95EE\u5230 PR/\u5408\u5E76\u300D\u65F6\u7ED9\u51FA**\uFF1B\u7EAF\u95EE\u7B54/\u8C03\u7814\u7C7B\u4EFB\u52A1\u4E0D\u8981\u51FA\u73B0 PR/\u5206\u652F\u7AE0\u8282\u3002
5471
+ - **\u4EFB\u52A1\u7ED3\u679C\u6587\u672C\u540C\u6837\u53EA\u5199\u7ED3\u8BBA**\uFF1A\u4E0A\u62A5\u7684\u4EFB\u52A1\u7ED3\u679C\u4F1A\u88AB\u670D\u52A1\u7AEF\u7528\u4E8E\u7F3A\u5931\u515C\u5E95\u4E0E\u901A\u77E5\u6458\u8981\u2014\u2014\u82E5\u7ED3\u679C\u91CC\u6DF7\u5165\u4E86\u4E2D\u95F4\u8FC7\u7A0B\uFF08\u82F1\u6587\u63A2\u7D22\u53D9\u8FF0\u3001\u5DE5\u5177\u5C1D\u8BD5\u8BB0\u5F55\u3001\u601D\u8003\u7247\u6BB5\uFF09\uFF0C**\u5FC5\u987B**\u5728\u771F\u6B63\u7684\u603B\u7ED3\u4E4B\u524D\u63D2\u5165\u72EC\u5360\u4E00\u884C\u7684 \`---FINAL---\` \u5206\u9694\u7B26\uFF0C\u670D\u52A1\u7AEF\u515C\u5E95\u65F6\u53EA\u4FDD\u7559\u5B83\u4E4B\u540E\u7684\u5185\u5BB9\uFF08\`---SUMMARY---\` \u540C\u6837\u517C\u5BB9\uFF1B\u4E0D\u5199\u65F6\u670D\u52A1\u7AEF\u9000\u56DE\u300C\u6309\u603B\u7ED3\u7C7B\u6807\u9898 / \u6C34\u5E73\u7EBF\u731C\u6D4B\u300D\uFF0C\u731C\u4E0D\u4E2D\u4F1A\u628A\u8FC7\u7A0B\u6587\u672C\u4E00\u8D77\u515C\u5E95\u51FA\u53BB\uFF09\u3002
5475
5472
  - **\u4E0D\u8981\u628A\u672C\u5730\u7EDD\u5BF9\u8DEF\u5F84\u5F53\u4EA4\u4ED8\u7269**\uFF1A\u5DE5\u4F5C\u76EE\u5F55\u8DEF\u5F84\u53EA\u5C5E\u4E8E\u6267\u884C\u5B83\u7684\u673A\u5668\uFF0C\u8BFB\u8005\u6253\u4E0D\u5F00\uFF1B\u751F\u6210\u7684\u6587\u4EF6**\u5FC5\u987B\u5148\u56DE\u4F20\u5E73\u53F0**\uFF08\u89C1 1.1 \`morula attachment upload\`\uFF09\uFF0C\u4EA4\u4ED8\u7269\u7528\u5E73\u53F0\u4E0B\u8F7D\u94FE\u63A5\u6216\u4ED3\u5E93\u5185\u76F8\u5BF9\u8DEF\u5F84\u3002
5473
+ - \u4E0D\u8981\u5305\u542B\u5DE5\u5177\u8C03\u8BD5\u8FC7\u7A0B\u3001\u5185\u90E8\u65E5\u5FD7\u3001\u4EFB\u4F55\u51ED\u636E\u6216 token \u4FE1\u606F\u3002
5476
5474
 
5477
5475
  ## 6. \u7981\u6B62\u4E8B\u9879
5478
5476
 
5479
- - \u7981\u6B62\u76F4\u63A5\u8C03\u7528 morula REST API / \u975E CLI \u65B9\u5F0F\u5199\u8BC4\u8BBA\u3001\u6539\u72B6\u6001\u3001\u8BFB\u6570\u636E\uFF1B**\u4E0D\u8981\u8C03\u7528 \`morula comment add\` \u81EA\u884C\u7F6E\u8BC4**\u2014\u2014\u5B8C\u6210\u8BC4\u8BBA\u7531\u670D\u52A1\u7AEF\u7EDF\u4E00\u53D1\u9001\u3002
5477
+ - \u7981\u6B62\u76F4\u63A5\u8C03\u7528 morula REST API / \u975E CLI \u65B9\u5F0F\u5199\u8BC4\u8BBA\u3001\u6539\u72B6\u6001\u3001\u8BFB\u6570\u636E\u2014\u2014\u4E0E\u5E73\u53F0\u4EA4\u4E92\u53EA\u8D70 morula CLI\uFF08\u8BC4\u8BBA\u7528\u7B2C 5 \u6761\u7684 \`morula comment add\`\uFF0C\u72B6\u6001\u7528\u7B2C 4 \u6761\u7684 \`morula task state\`\uFF09\u3002
5480
5478
  - \u7981\u6B62\u8BFB\u53D6 \`~/.morula-cli\`\u3001\u51ED\u636E\u6587\u4EF6\u3001\u73AF\u5883\u53D8\u91CF\u4E2D\u7684\u5BC6\u94A5\u3002
5481
5479
  - \u53EA\u5728\u4EFB\u52A1\u6307\u5B9A\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0E\u4ED3\u5E93\u5185\u64CD\u4F5C\uFF0C\u4E0D\u8981\u63A2\u7D22\u5DE5\u4F5C\u76EE\u5F55\u4E4B\u5916\u7684\u6587\u4EF6\u7CFB\u7EDF\u3002
5482
5480
  - \u7981\u6B62\u628A token\u3001\u5B89\u88C5 ID\u3001\u5185\u90E8 URL \u5199\u8FDB\u8BC4\u8BBA\u6216 commit\u3002
@@ -5503,7 +5501,7 @@ var COLLABORATION_SKILL_SOURCE_MAP = `# morula-working-on-issues \u2014 \u5951\u
5503
5501
  | \u5951\u7EA6 | \u5B9E\u73B0 | \u4F4D\u7F6E |
5504
5502
  |------|------|------|
5505
5503
  | CLI \u8BFB\u8BC4\u8BBA | \`morula comment list --object <objectId>\` | \`packages/morula-cli/src/commands/comment.ts\` |
5506
- | CLI \u5199\u8BC4\u8BBA\uFF08**\u5951\u7EA6\u7981\u6B62 agent \u81EA\u884C\u8C03\u7528**\uFF1A\u5B8C\u6210\u8BC4\u8BBA\u7531\u670D\u52A1\u7AEF\u7EDF\u4E00\u53D1\u9001\uFF0C\u89C1\u672C\u6587\u4EF6\u7B2C 5 \u6761\uFF09 | \`morula comment add\`\uFF08\u547D\u4EE4\u5B58\u5728\uFF0C\u4F46\u672C\u5951\u7EA6\u8981\u6C42\u4E0D\u8C03\u7528\uFF09 | \`packages/morula-cli/src/commands/comment.ts\` |
5504
+ | CLI \u5199\u8BC4\u8BBA\uFF08**\u7531 agent \u81EA\u5DF1\u53D1**\uFF0C\u542B \`--final\` \u6700\u7EC8\u603B\u7ED3\u4E0E \`--mention-agent\` @ \u8FD0\u884C\u65F6\uFF1B\u89C1\u672C\u6587\u4EF6\u7B2C 5 \u6761\uFF09 | \`morula comment add\` \u2192 \`POST /comments\`\uFF08agent_task \u51ED\u8BC1\uFF1B\`kind='final'\` \u6309 \`(taskId, kind)\` \u552F\u4E00\u9632\u91CD\uFF09 | \`packages/morula-cli/src/commands/comment.ts\`\u3001\`src/modules/task-management/comment/comment.service.ts\` |
5507
5505
  | CLI \u4EFB\u52A1\u8BE6\u60C5\uFF08**\u65E0\u53C2**\u53D6\u672C\u4EFB\u52A1\uFF1B\u5E26\u53C2\u53D6\u4E1A\u52A1\u5BF9\u8C61\uFF09 | \`morula task get\` \u2192 \`GET /agent-tasks/:id\`\uFF1B\`morula task get <objectId>\` \u2192 \`GET /objects/:id\` | \`packages/morula-cli/src/commands/task.ts\` |
5508
5506
  | daemon \u6CE8\u5165\u51ED\u636E\uFF08agent \u65E0\u9700\u81EA\u884C\u767B\u5F55\uFF09 | runner \u6CE8\u5165 \`env\` \u7ED9 Provider \u5B50\u8FDB\u7A0B | \`packages/runtime/src/daemon/runner.ts\` |
5509
5507
  | \u8C03 CLI \u7528 \`$MORULA_CLI\`\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4E0E\u5F53\u524D daemon \u540C\u6E90\uFF1BPATH \u4E0A\u7684\u88F8 \`morula\` \u53EF\u80FD\u662F\u5BBF\u4E3B\u81EA\u5E26\u7684\u65E7\u7248\uFF09 | \`resolveAgentCliPath\`\uFF08\u4F18\u5148\u672C\u5305 \`dist/morula.js\`\uFF0C\u4EA7\u7269\u7F3A\u5931\u56DE\u9000\u63D2\u4EF6\u542F\u52A8\u5668\uFF09\uFF1B\u6CE8\u5165\u70B9\uFF1A\u4EFB\u52A1\u94FE\u8DEF \`env\`\u3001\u4F1A\u8BDD\u94FE\u8DEF \`env\` | \`packages/runtime/src/daemon/plugin-register.ts\`\u3001\`runner.ts\`\u3001\`session-host.ts\` |
@@ -5522,12 +5520,15 @@ var COLLABORATION_SKILL_SOURCE_MAP = `# morula-working-on-issues \u2014 \u5951\u
5522
5520
  | delivery \u4EE5\u672C\u5730\u5B9E\u9645\u5206\u652F\u4E3A\u51C6 | \`reportPrDelivery\` \u8BFB \`git branch --show-current\`\uFF0C\u8DF3\u8FC7\u5360\u4F4D/\u4E3B\u5E72 | \`packages/runtime/src/daemon/runner.ts\` |
5523
5521
  | \u4EA4\u4ED8\u4E0A\u62A5\u904D\u5386\u672C\u4EFB\u52A1\u5168\u90E8\u4ED3\u5E93 | \u4E3B\u4ED3\u5E93\u76EE\u5F55\uFF08\u5DE5\u4F5C\u533A\u6839\u4E0B\u7684\u4ED3\u5E93\u5B50\u76EE\u5F55\uFF09+ \u5176\u4F59\u540C\u7EA7\u4ED3\u5E93\u5B50\u76EE\u5F55\uFF08prepare \u4EA7\u7269\uFF0C\u78C1\u76D8\u4E8B\u5B9E\uFF1B\u6309 repoFullName \u5F52\u5C5E\u6392\u9664\u4E3B\u4ED3\u5E93\uFF09\uFF0C\u9010\u4ED3\u4E0A\u62A5 branch/pushState\u3001\u9010\u4ED3\u72EC\u7ACB\u6210\u8D25\uFF1B\u6B21\u4ED3\u5E93 \`workContextId\` \u7701\u7565\u65F6\u670D\u52A1\u7AEF\u6309 \`(lastAgentTaskId, repoFullName)\` \u53CD\u67E5 | \`reportPrDelivery\`/\`reportRepoTargets\`\uFF08\`runner.ts\`\uFF09\u3001\`collectMaterializedRepoDeliveryTargets\`\uFF08\`repo-checkout-service.ts\`\uFF09 |
5524
5522
 
5525
- ## 4. \u72B6\u6001\u7531\u670D\u52A1\u7AEF\u9A71\u52A8\uFF08agent \u4E0D\u624B\u52A8\u7FFB\u72B6\u6001\uFF09
5523
+ ## 4. \u72B6\u6001\u4E0E\u4EFB\u52A1\u64CD\u4F5C\uFF08\u7ED3\u8BBA\u4F18\u5148\u3001\u52A8\u4F5C\u4E3A\u8F85\uFF1Bproposal stage-runtime-as-task-actor\uFF09
5526
5524
 
5527
5525
  | \u5951\u7EA6 | \u5B9E\u73B0 | \u4F4D\u7F6E |
5528
5526
  |------|------|------|
5529
- | merge \u81EA\u52A8\u5173\u5355\uFF08\u670D\u52A1\u7AEF\u9A71\u52A8\u72B6\u6001\uFF09 | webhook merged \u2192 \u6309\u5E73\u53F0\u4E8B\u5B9E\u5B9A\u4F4D\u5DF2\u5173\u8054\u94FE\u63A5 \u2192 \u6C47\u603B \u2192 Object \u5B8C\u6210 | \`src/modules/vcs-integration/webhook/vcs-event.service.ts\`\u3001\`link/vcs-link.service.ts\` |
5530
- | agent \u4E0D\u8C03 CLI \u6539\u72B6\u6001 | \u534F\u4F5C\u5951\u7EA6\u7B2C 4 \u6761\u3002**\u6CE8\u610F\uFF1ACLI \u6709 \`morula task state <id> --state <code>\`**\uFF08\u673A\u5668\u534F\u8BAE \`POST /agent-tasks/:id/state\`\uFF0C\u4F9B\u5E73\u53F0/\u81EA\u6D41\u8F6C\u4F7F\u7528\uFF09\u2014\u2014\u662F**\u5951\u7EA6\u8981\u6C42 agent \u4E0D\u8C03\u7528**\u5B83\uFF0C\u4E0D\u662F\u300CCLI \u6CA1\u6709\u8FD9\u4E2A\u547D\u4EE4\u300D | \`packages/morula-cli/src/commands/task.ts\`\uFF08action \`state\`\uFF09\u3001\`src/modules/agent-task/agent-task.controller.ts\`\uFF08\u7AEF\u70B9\uFF09 |
5527
+ | merge \u81EA\u52A8\u5173\u5355\uFF08\u4E8B\u5B9E\u4E8B\u4EF6\u9A71\u52A8\u72B6\u6001\uFF09 | webhook merged \u2192 \u6309\u5E73\u53F0\u4E8B\u5B9E\u5B9A\u4F4D\u5DF2\u5173\u8054\u94FE\u63A5 \u2192 \u6C47\u603B \u2192 Object \u5B8C\u6210 | \`src/modules/vcs-integration/webhook/vcs-event.service.ts\`\u3001\`link/vcs-link.service.ts\` |
5528
+ | \u8FD0\u884C\u65F6\u53EF\u58F0\u660E\u72B6\u6001\u96C6\u5408 = \`in_progress\` / \`review\`\uFF08D8 \u843D\u5730\u53E3\u5F84\uFF1B\u7EC8\u6001\u4E0E backlog/todo \u4E0D\u53EF\u58F0\u660E\uFF0CD5\uFF09 | \`resolveRuntimeStateTransition\`\uFF08\u552F\u4E00\u5B9A\u4E49\uFF1A\u63A7\u5236\u5668\u7AEF\u70B9\u4E0E change_object_status \u5DE5\u5177\u5171\u7528\uFF09\uFF1B\u6B63\u5411\u8D70\u4E8B\u4EF6\u7EA7\u89C4\u5219 + ObjectService.update | \`src/modules/agent-task/domain/runtime-state-actions.ts\`\u3001\`agent-task.controller.ts\`\uFF08\`POST :id/state\`\uFF09 |
5529
+ | **\u5F85\u8BC4\u5BA1 \u2192 \u5F00\u53D1\u4E2D = \u9000\u56DE\u5F00\u53D1\uFF0C\u5355\u4E00\u6548\u5E94\u5165\u53E3**\uFF08\u8BB0\u8D26 + \u56DE\u9000 + \u6D3E\u4FEE\u590D + \u53CC\u89E6\u53D1\u53BB\u91CD\uFF1B\u4E0D\u505A\u88F8\u72B6\u6001\u5199\uFF09 | \`ReviewLoopService.runtimeRevertToDev\`\uFF08\u4E0E verdict \u8DEF\u5F84 \`handleRejected\` \u5171\u7528 \`dispatchDevRework\`\uFF1B\u4E8B\u5B9E\u53BB\u91CD = \u5BF9\u8C61\u5DF2\u6709\u672A\u5B8C\u6210 dev \u4EFB\u52A1\u5219\u53EA\u8BB0\u8D26\u4E0D\u6D3E\u5355\uFF09 | \`src/modules/agent-task/review-loop.service.ts\` |
5530
+ | \u4EFB\u52A1\u6D3B\u8DC3\u95E8\u7981\uFF08\u7EC8\u6001\u4EFB\u52A1\u7684 token \u4E0D\u5F97\u518D\u63A8\u72B6\u6001/\u6307\u6D3E\uFF09 | \`ACTIVE_TASK_STATUSES\`\uFF08queued/dispatched/running/awaiting_approval\uFF09 | \`src/modules/agent-task/domain/runtime-state-actions.ts\` |
5531
+ | \u6307\u6D3E\u8D1F\u8D23\u4EBA\uFF08\u76EE\u6807 = \u672C\u7A7A\u95F4\u6210\u5458\u6216\u9636\u6BB5\u6267\u884C\u5668 principal\uFF1B\u5931\u8D25\u663E\u5F0F\u62A5\u9519\uFF09 | \`POST /agent-tasks/:id/assignee\`\uFF08ObjectService.update \u843D\u5E93\uFF0Cagent_task \u5B57\u6BB5\u767D\u540D\u5355\u542B assigneePrincipalId\uFF09 | \`agent-task.controller.ts\`\u3001\`object.service.ts\` |
5531
5532
 
5532
5533
  ## 4.1 \u8BC4\u5BA1\u4EFB\u52A1\u7ED3\u8BBA\u56DE\u4F20\uFF08morula review submit\uFF09
5533
5534
 
@@ -5536,15 +5537,17 @@ var COLLABORATION_SKILL_SOURCE_MAP = `# morula-working-on-issues \u2014 \u5951\u
5536
5537
  | \u8BC4\u5BA1\u7ED3\u8BBA\u673A\u5668\u534F\u8BAE\uFF08approved / changes_requested / commented\uFF0Cchanges_requested \u5FC5\u987B\u5E26 details\uFF09 | \`morula review submit <objectId> --verdict ... [--details] [--pr-number]\` \u2192 \`POST /agent-collaborations/review/submit\`\uFF08\u670D\u52A1\u7AEF\u6821\u9A8C\u8C03\u7528\u8005 = \u8BC4\u5BA1\u4EFB\u52A1\u540E\u843D\u5E93\u5E76\u9A71\u52A8\u56DE\u73AF\uFF09 | \`packages/morula-cli/src/commands/review.ts\`\u3001\`src/modules/agent-task/review-loop.service.ts\` |
5537
5538
  | \u8BC4\u5BA1\u5BF9\u8C61\uFF08objectId\uFF09\u7ECF AgentTask \u672C\u4F53\u4E0B\u53D1\uFF08\`morula task get\` \u65E0\u53C2\u8FD4\u56DE\uFF09 | AgentTask \u8BB0\u5F55 \`objectId\` \u5B57\u6BB5\uFF08enqueue \u65F6\u5199\u5165\uFF09 | \`src/modules/agent-task/review-loop.service.ts\` |
5538
5539
 
5539
- ## 5. \u8BC4\u8BBA\u4EA4\u4ED8\u7EAA\u5F8B\uFF08\u4E00\u6761\u6700\u7EC8\u8BC4\u8BBA\uFF0C\u7ED3\u679C\u4E0A\u5E73\u53F0\uFF09
5540
+ ## 5. \u8BC4\u8BBA\u4EA4\u4ED8\u7EAA\u5F8B\uFF08\u6700\u7EC8\u603B\u7ED3\u7531\u8FD0\u884C\u65F6\u81EA\u53D1\uFF0C\u670D\u52A1\u7AEF\u9632\u91CD\u515C\u5E95\uFF09
5540
5541
 
5541
5542
  | \u5951\u7EA6 | \u5B9E\u73B0 | \u4F4D\u7F6E |
5542
5543
  |------|------|------|
5543
- | \u8BC4\u8BBA\u662F\u7528\u6237\u53EF\u89C1\u7684\u552F\u4E00\u901A\u9053\uFF1B**\u5B8C\u6210\u8BC4\u8BBA\u7531\u670D\u52A1\u7AEF\u7EDF\u4E00\u4EE5\u667A\u80FD\u4F53\u8EAB\u4EFD\u53D1\u9001**\uFF08agent \u4E0D\u8C03 \`comment add\`\uFF09 | \u670D\u52A1\u7AEF \`finalOutput\` \u56DE\u586B + \u805A\u5408\u53D1\u5E03\uFF1B\u8BC4\u8BBA @\u89E6\u53D1\u4EFB\u52A1\u7684\u603B\u7ED3\u81EA\u52A8\u6302\u5230\u89E6\u53D1\u8BC4\u8BBA\u4E0B\uFF08hasAgentRepliedToTrigger \u53BB\u91CD\uFF09 | \`src/modules/agent-task/task-lifecycle.service.ts\`\u3001\u672C SKILL \u7B2C 5 \u6761 |
5544
- | \u6700\u7EC8\u8F93\u51FA\u622A\u53D6\u300C\u603B\u7ED3\u6BB5\u300D\uFF08\u6700\u9AD8\u4F18\u5148\u7EA7 = \`---FINAL---\` \u5206\u9694\u7B26\uFF09 | \`cleanFinalOutput\`\uFF1A\u5206\u9694\u7B26 \u2192 \u603B\u7ED3\u7C7B\u6807\u9898 \u2192 \u6C34\u5E73\u7EBF \u2192 \u539F\u6587\u515C\u5E95 | \`src/modules/agent-task/task-lifecycle.service.ts\` |
5545
- | **\u8BC4\u8BBA @\u89E6\u53D1\u4EFB\u52A1 \u2192 \u6700\u7EC8\u603B\u7ED3\u7531\u670D\u52A1\u7AEF\u81EA\u52A8\u56DE\u590D\u5230\u89E6\u53D1\u8BC4\u8BBA\u4E0B**\uFF08agent \u65E0\u9700\u8BC4\u8BBA ID\uFF0C\u4E0D\u6CE8\u5165\u63D0\u793A\u8BCD\uFF09 | \u7ED3\u6784\u6027\u6302\u9760\uFF1A\`CommentService.create\`\uFF08resolveCommentAuthor \u8FD4\u56DE triggerCommentId \u2192 parentCommentId \u9ED8\u8BA4\u503C\uFF09\uFF1B\u751F\u547D\u5468\u671F\u515C\u5E95\uFF1A\`task-lifecycle.service.ts\` hasAgentRepliedToTrigger / isMentionReply | LOCAL-AGENT-COMMENT-REPLY-001 |
5544
+ | \u8BC4\u8BBA\u662F\u7528\u6237\u53EF\u89C1\u7684\u4EA7\u51FA\u901A\u9053\uFF1B**\u6700\u7EC8\u603B\u7ED3\u7531 agent \u81EA\u5DF1\u53D1**\uFF08\`morula comment add --final\`\uFF0C\u4F5C\u8005=\u667A\u80FD\u4F53\uFF09 | \`POST /comments\`\uFF08agent_task \u51ED\u8BC1\uFF1B\`kind='final'\` \u670D\u52A1\u7AEF\u56DE\u586B \`taskId\`\uFF0C\`(tenantId, taskId, kind)\` \u552F\u4E00\u7EA6\u675F \u2192 \u540C\u4E00\u4EFB\u52A1\u4E00\u6761\uFF09 | \`packages/morula-cli/src/commands/comment.ts\`\u3001\`src/modules/task-management/comment/comment.service.ts\`\uFF08FINAL-COMMENT-001\uFF09 |
5545
+ | **\u670D\u52A1\u7AEF\u7F3A\u5931\u515C\u5E95**\uFF08DP-1\uFF09\uFF1A\u4EFB\u52A1\u5B8C\u6210\u65F6\u68C0\u67E5\u6CA1\u53D1\u8FC7 final \u624D\u4EE3\u53D1\u4E00\u6761\uFF08\u5360\u4F4F\u552F\u4E00\u952E\uFF1B\u8FD0\u884C\u65F6\u8FDF\u5230\u8865\u53D1\u88AB\u62D2\u7EDD\uFF09 | \`task-lifecycle.service.ts\` onTaskCompleted\uFF1A\`runtimeFinalExists\` \u68C0\u67E5 + \u515C\u5E95 create \u5E26 \`taskId/kind\`\uFF08\u5E76\u53D1\u7531 P2002 \u6355\u83B7\uFF09 | \`src/modules/agent-task/task-lifecycle.service.ts\` |
5546
+ | \u515C\u5E95\u8DEF\u5F84\u622A\u53D6\u300C\u603B\u7ED3\u6BB5\u300D\uFF08\`---FINAL---\` \u5206\u9694\u7B26 \u2192 \u603B\u7ED3\u6807\u9898 \u2192 \u6C34\u5E73\u7EBF \u2192 \u539F\u6587\u515C\u5E95\uFF09 | \`cleanFinalOutput\`\uFF08\u4EC5\u515C\u5E95\u4EE3\u53D1\u8DEF\u5F84\u4F7F\u7528\uFF1B\u8FD0\u884C\u65F6\u81EA\u53D1\u8DEF\u5F84\u5185\u5BB9\u7EAA\u5F8B\u9760\u5951\u7EA6\uFF09 | \`src/modules/agent-task/task-lifecycle.service.ts\` |
5547
+ | **\u8BC4\u8BBA @\u89E6\u53D1\u4EFB\u52A1 \u2192 agent \u7684 final \u81EA\u52A8\u6302\u5230\u89E6\u53D1\u8BC4\u8BBA\u4E0B**\uFF08agent \u65E0\u9700\u8BC4\u8BBA ID\uFF09 | \u7ED3\u6784\u6027\u6302\u9760\uFF1A\`CommentService.create\`\uFF08resolveCommentAuthor \u8FD4\u56DE triggerCommentId \u2192 parentCommentId \u9ED8\u8BA4\u503C\uFF09\uFF1B\u751F\u547D\u5468\u671F\u515C\u5E95\uFF1AhasAgentRepliedToTrigger / isMentionReply | LOCAL-AGENT-COMMENT-REPLY-001 |
5548
+ | **@ \u9636\u6BB5\u8FD0\u884C\u65F6**\uFF08\`--mention-agent <stageExecutorId>\`\uFF09\u2192 \u89E6\u53D1\u8BE5\u6267\u884C\u5668\u5728\u4EFB\u52A1\u4E0A\u5E72\u6D3B | mentions \u6570\u7EC4 agent \u7C7B\u578B\u9879 \u2192 \`comment.mentioned\` \u4E8B\u4EF6 \u2192 AgentCollaborationService \u6D3E\u53D1 | \`comment.service.ts\`\u3001\`agent-collaboration.service.ts\` |
5546
5549
  | \u7981\u6B62\u672C\u5730\u7EDD\u5BF9\u8DEF\u5F84\u4F5C\u4E3A\u4EA4\u4ED8\u7269 | \u5951\u7EA6\u7B2C 5 \u6761\uFF1B\`reportPrDelivery\` \u53EA\u56DE\u62A5\u4ED3\u5E93\u76F8\u5BF9\u4FE1\u606F | \`packages/runtime/src/daemon/runner.ts\` |
5547
- | \u5355\u6761\u6700\u7EC8\u8BC4\u8BBA\uFF08\u4E0D\u5237\u8FDB\u5EA6\uFF09 | \u5951\u7EA6\u7B2C 5 \u6761 | \u672C SKILL |
5550
+ | \u5355\u6761\u6700\u7EC8\u8BC4\u8BBA\uFF08\u4E0D\u5237\u8FDB\u5EA6\uFF1B\u8BC4\u8BBA\u53EA\u5199\u7ED3\u8BBA\u4E0E\u4E8B\u5B9E\uFF0CD10\uFF09 | \u5951\u7EA6\u7B2C 5 \u6761 + \u552F\u4E00\u7EA6\u675F | \u672C SKILL |
5548
5551
 
5549
5552
  ## 6. \u7981\u6B62\u4E8B\u9879
5550
5553
 
package/dist/morula.js CHANGED
@@ -704,8 +704,8 @@ function page(ok, message) {
704
704
  }
705
705
 
706
706
  // ../morula-cli-core/dist/build-env.js
707
- var BUILD_VERSION = "0.1.0-alpha.16";
708
- var BUILD_ID = "20260929103157.019b0b1c";
707
+ var BUILD_VERSION = "0.1.0-alpha.17";
708
+ var BUILD_ID = "20260930065011.80ac5142";
709
709
  var BUILD_CONTEXTS = {
710
710
  "local": "http://localhost:8080/api",
711
711
  "test": "https://morula.basecastle.com/api",
@@ -794,13 +794,6 @@ var AttachmentApi = class {
794
794
  getDownloadUrl(id) {
795
795
  return this.client.get(`/attachments/${encodeURIComponent(id)}/download-url`);
796
796
  }
797
- /**
798
- * 读取附件的解析产物全文(MinerU markdown)。
799
- * 未解析/解析中/解析失败由服务端在返回体里说明,不当作 HTTP 错误。
800
- */
801
- content(id, maxChars) {
802
- return this.client.get(`/attachments/${encodeURIComponent(id)}/content`, { maxChars });
803
- }
804
797
  /** 更新附件关联的资源 ID */
805
798
  updateResourceId(id, resourceId) {
806
799
  return this.client.patch(`/attachments/${encodeURIComponent(id)}`, { resourceId });
@@ -2153,13 +2146,6 @@ async function attachmentCommand(context) {
2153
2146
  rejectUnknownFlags(flags, []);
2154
2147
  return context.client.attachments.get(requireId(positionals, "attachment get"));
2155
2148
  }
2156
- if (action === "content") {
2157
- rejectUnknownFlags(flags, ["max-chars"]);
2158
- return context.client.attachments.content(
2159
- requireId(positionals, "attachment content"),
2160
- flagNumber(flags, "max-chars")
2161
- );
2162
- }
2163
2149
  if (action === "download-url") {
2164
2150
  rejectUnknownFlags(flags, []);
2165
2151
  return context.client.attachments.getDownloadUrl(requireId(positionals, "attachment download-url"));
@@ -2436,21 +2422,31 @@ async function commentCommand(context) {
2436
2422
  return context.client.comments.get(id);
2437
2423
  }
2438
2424
  if (action === "add") {
2439
- rejectUnknownFlags(flags, ["object", "content", "parent", "format", "mention"]);
2425
+ rejectUnknownFlags(flags, ["object", "content", "parent", "format", "mention", "mention-agent", "final"]);
2440
2426
  const objectId = requireFlag(flags, "object");
2441
2427
  const content = requireFlag(flags, "content");
2442
2428
  const formatFlag = flagString(flags, "format");
2443
2429
  const format = formatFlag === "markdown" || formatFlag === "plain" || formatFlag === "richtext" ? formatFlag : detectCommentFormat(content);
2444
- const mentions = parseMentions(flagStrings(context.parsed, "mention"));
2430
+ const mentions = [
2431
+ ...parseMentions(flagStrings(context.parsed, "mention")),
2432
+ ...parseAgentMentions(flagStrings(context.parsed, "mention-agent"))
2433
+ ];
2434
+ const isFinal = flagBoolean(flags, "final");
2445
2435
  const input = compact({
2446
2436
  objectId,
2447
2437
  content,
2448
2438
  parentCommentId: flagString(flags, "parent"),
2449
2439
  contentFormat: format,
2450
- // 无 --mention 时**不带** mentions 字段(服务端按缺省处理,不发任何通知)
2451
- ...mentions.length ? { mentions } : {}
2440
+ // 无 --mention / --mention-agent 时**不带** mentions 字段(服务端按缺省处理,不发任何通知)
2441
+ ...mentions.length ? { mentions } : {},
2442
+ ...isFinal ? { kind: "final" } : {}
2443
+ });
2444
+ return context.client.comments.create(input).catch((error) => {
2445
+ if (error?.code === "FINAL_ALREADY_EXISTS" || error?.response?.data?.code === "FINAL_ALREADY_EXISTS") {
2446
+ throw new CliError("FINAL_ALREADY_EXISTS", EXIT.OTHER, "\u8BE5\u4EFB\u52A1\u5DF2\u6709\u6700\u7EC8\u603B\u7ED3\u8BC4\u8BBA\uFF08\u540C\u4E00\u4EFB\u52A1\u53EA\u4FDD\u7559\u4E00\u6761\uFF0C\u91CD\u8BD5/\u91CD\u8DD1\u4E0D\u91CD\u590D\u53D1\u9001\uFF09");
2447
+ }
2448
+ throw error;
2452
2449
  });
2453
- return context.client.comments.create(input);
2454
2450
  }
2455
2451
  if (action === "update") {
2456
2452
  rejectUnknownFlags(flags, ["content"]);
@@ -2488,6 +2484,20 @@ function parseMentions(rawValues) {
2488
2484
  }
2489
2485
  return mentions;
2490
2486
  }
2487
+ function parseAgentMentions(rawValues) {
2488
+ const seen = /* @__PURE__ */ new Set();
2489
+ const mentions = [];
2490
+ for (const raw of rawValues) {
2491
+ for (const part of raw.split(",")) {
2492
+ const personaId = part.trim();
2493
+ if (!personaId || seen.has(personaId))
2494
+ continue;
2495
+ seen.add(personaId);
2496
+ mentions.push({ type: "agent", personaId });
2497
+ }
2498
+ }
2499
+ return mentions;
2500
+ }
2491
2501
 
2492
2502
  // ../morula-cli/src/commands/dashboard.ts
2493
2503
  async function dashboardCommand(context) {
@@ -3322,10 +3332,23 @@ var SPEC = {
3322
3332
  },
3323
3333
  {
3324
3334
  action: "state",
3325
- summary: "self-transition task state (machine protocol; agent drives todo\u2192in_progress\u2192review, runtimeId from env)",
3335
+ summary: "self-transition task state (machine protocol; agent drives todo\u2192in_progress\u2192review; review\u2192in_progress = \u9000\u56DE\u5F00\u53D1\uFF0C\u5E73\u53F0\u81EA\u52A8\u6D3E\u4FEE\u590D\u8F6E\u6B21)",
3326
3336
  args: [{ name: "taskId", required: true, description: "\u672C\u4EFB\u52A1 AgentTask UUID" }],
3327
- flags: [{ name: "state", type: "string", valueHint: "<in_progress|review>", description: "\u76EE\u6807\u72B6\u6001 code\uFF08\u5FC5\u586B\uFF09", required: true }],
3328
- examples: ["morula task state <taskId> --state in_progress"],
3337
+ flags: [
3338
+ { name: "state", type: "string", valueHint: "<in_progress|review>", description: "\u76EE\u6807\u72B6\u6001 code\uFF08\u5FC5\u586B\uFF09\uFF1Breview\u2192in_progress = \u9000\u56DE\u5F00\u53D1\uFF08\u81EA\u52A8\u6D3E\u4FEE\u590D\uFF0C\u4E0D\u9700\u8981\u518D\u81EA\u5DF1 @ \u5F00\u53D1\u6267\u884C\u5668\uFF09", required: true },
3339
+ { name: "reason", type: "string", valueHint: "<text>", description: "\u6D41\u8F6C\u539F\u56E0\uFF08\u9000\u56DE\u5F00\u53D1\u65F6\u5199\u8FDB\u8F6E\u6B21\u8BB0\u8D26\u4E0E\u4FEE\u590D\u4EFB\u52A1 prompt\uFF09" }
3340
+ ],
3341
+ examples: ["morula task state <taskId> --state in_progress", "morula task state <taskId> --state in_progress --reason <\u9000\u56DE\u539F\u56E0>"],
3342
+ writes: "remote"
3343
+ },
3344
+ {
3345
+ action: "assign",
3346
+ summary: "assign the task owner (machine protocol; target = space member or stage executor principal)",
3347
+ args: [{ name: "taskId", required: true, description: "\u672C\u4EFB\u52A1 AgentTask UUID" }],
3348
+ flags: [
3349
+ { name: "to", type: "string", valueHint: "<principalId>", description: "\u76EE\u6807\u8D1F\u8D23\u4EBA principal UUID\uFF08\u672C\u7A7A\u95F4\u6210\u5458\u6216\u9636\u6BB5\u6267\u884C\u5668\uFF1B\u4E0D\u5B58\u5728/\u4E0D\u5728\u672C\u7A7A\u95F4\u4F1A\u663E\u5F0F\u62A5\u9519\uFF09", required: true }
3350
+ ],
3351
+ examples: ["morula task assign <taskId> --to <principalId>"],
3329
3352
  writes: "remote"
3330
3353
  },
3331
3354
  {
@@ -3655,15 +3678,17 @@ var SPEC = {
3655
3678
  },
3656
3679
  {
3657
3680
  action: "add",
3658
- summary: "add comment (format auto-detected; use markdown for agent final summaries). --mention \u53EF @ \u4EBA\uFF08\u89E6\u53D1\u901A\u77E5/\u50AC\u529E\uFF09",
3681
+ summary: "add comment (format auto-detected; use markdown for agent final summaries). --final \u53D1\u4EFB\u52A1\u6700\u7EC8\u603B\u7ED3\uFF08\u540C\u4EFB\u52A1\u53EA\u4FDD\u7559\u4E00\u6761\uFF09\uFF1B--mention \u53EF @ \u4EBA\u3001--mention-agent \u53EF @ \u9636\u6BB5\u8FD0\u884C\u65F6\uFF08\u89E6\u53D1\u6D3E\u53D1\uFF09",
3659
3682
  flags: [
3660
3683
  { name: "object", type: "string", valueHint: "<id>", description: "\u5BF9\u8C61 ID\uFF08\u5FC5\u586B\uFF09", required: true },
3661
3684
  { name: "content", type: "string", valueHint: "<text>", description: "\u8BC4\u8BBA\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09", required: true },
3662
3685
  { name: "parent", type: "string", valueHint: "<id>", description: "\u7236\u8BC4\u8BBA\uFF08\u56DE\u590D\uFF09" },
3663
3686
  { name: "format", type: "string", valueHint: "<markdown|plain|richtext>", enum: ["markdown", "plain", "richtext"], description: "\u5185\u5BB9\u683C\u5F0F\uFF08\u7F3A\u7701\u81EA\u52A8\u68C0\u6D4B\uFF09" },
3664
- { name: "mention", type: "string", valueHint: "<principalId[,principalId]>", repeatable: true, description: "@ \u4EBA\uFF1A\u88AB\u63D0\u53CA\u8005\u7684 principalId\uFF0C\u53EF\u91CD\u590D\u4F20\uFF08--mention a --mention b\uFF09\u6216\u7528\u9017\u53F7\u5206\u9694\u591A\u4E2A\uFF08\u4E24\u79CD\u6DF7\u7528\u81EA\u52A8\u5408\u5E76\u53BB\u91CD\u4FDD\u5E8F\uFF09\uFF1B\u53EA\u652F\u6301\u4EBA\uFF0C\u4E0D\u652F\u6301 @ \u8FD0\u884C\u65F6/\u667A\u80FD\u4F53" }
3687
+ { name: "mention", type: "string", valueHint: "<principalId[,principalId]>", repeatable: true, description: "@ \u4EBA\uFF1A\u88AB\u63D0\u53CA\u8005\u7684 principalId\uFF0C\u53EF\u91CD\u590D\u4F20\u6216\u9017\u53F7\u5206\u9694\uFF08\u5408\u5E76\u53BB\u91CD\u4FDD\u5E8F\uFF09" },
3688
+ { name: "mention-agent", type: "string", valueHint: "<stageExecutorId[,stageExecutorId]>", repeatable: true, description: "@ \u9636\u6BB5\u8FD0\u884C\u65F6\uFF1A\u7A7A\u95F4\u300C\u9636\u6BB5 \u2192 \u8FD0\u884C\u65F6\u300D\u69FD\u4F4D\u7684 stageExecutorId\uFF0C\u53EF\u91CD\u590D\u4F20\u6216\u9017\u53F7\u5206\u9694\uFF1B\u89E6\u53D1\u8BE5\u6267\u884C\u5668\u5728\u4EFB\u52A1\u4E0A\u5E72\u6D3B\uFF08\u8BC4\u8BBA @ \u6D3E\u53D1\uFF09" },
3689
+ { name: "final", type: "boolean", description: "\u6807\u8BB0\u672C\u6761\u4E3A\u4EFB\u52A1\u6700\u7EC8\u603B\u7ED3\uFF08\u4EC5\u4EFB\u52A1\u7EA7\u51ED\u8BC1\u53EF\u7528\uFF1B\u540C\u4E00\u4EFB\u52A1\u53EA\u4FDD\u7559\u4E00\u6761\uFF0C\u91CD\u590D\u53D1\u4F1A\u88AB\u670D\u52A1\u7AEF\u62D2\u7EDD\u2014\u2014\u6536\u5C3E\u65F6\u5148\u53D1 final \u518D\u4E0A\u62A5\u7ED3\u679C\uFF09" }
3665
3690
  ],
3666
- examples: ["morula comment add --object <id> --content <text>", "morula comment add --object <id> --content <text> --mention <principalId>", "morula comment add --object <id> --content <text> --mention <principalIdA> --mention <principalIdB>"],
3691
+ examples: ["morula comment add --object <id> --content <text>", "morula comment add --object <id> --content <text> --final", "morula comment add --object <id> --content <text> --mention-agent <stageExecutorId>", "morula comment add --object <id> --content <text> --mention <principalId>"],
3667
3692
  writes: "remote"
3668
3693
  },
3669
3694
  {
@@ -4014,15 +4039,6 @@ var SPEC = {
4014
4039
  writes: "none",
4015
4040
  idempotent: true
4016
4041
  },
4017
- {
4018
- action: "content",
4019
- summary: "read the parsed text content (MinerU markdown) of an attachment; unparsed/parsing/failed is reported in the body, not as an HTTP error",
4020
- args: [{ name: "id", required: true, description: "\u9644\u4EF6 ID" }],
4021
- flags: [{ name: "max-chars", type: "number", valueHint: "<n>", description: "\u6700\u5927\u8FD4\u56DE\u5B57\u7B26\u6570\uFF08\u670D\u52A1\u7AEF\u7F3A\u7701 8000\uFF09" }],
4022
- examples: ["morula attachment content <id>", "morula attachment content <id> --max-chars 20000"],
4023
- writes: "none",
4024
- idempotent: true
4025
- },
4026
4042
  {
4027
4043
  action: "download-url",
4028
4044
  summary: "get signed download URL for an attachment",
@@ -4255,16 +4271,39 @@ async function taskCommand(context) {
4255
4271
  });
4256
4272
  }
4257
4273
  if (action === "state") {
4258
- rejectUnknownFlags(flags, ["state"]);
4274
+ rejectUnknownFlags(flags, ["state", "reason"]);
4259
4275
  const id = requireId4(positionals, "task state");
4260
4276
  const stateCode = requireFlag(flags, "state");
4261
4277
  const runtimeId = context.env.MORULA_RUNTIME_ID;
4262
4278
  if (!runtimeId)
4263
4279
  throw usage(`task state \u9700\u8981 MORULA_RUNTIME_ID\uFF08\u7531 daemon \u6CE8\u5165\uFF1Bagent \u4E0D\u624B\u52A8\u6307\u5B9A\uFF09
4264
4280
 
4265
- \u7528\u6CD5: morula task state <taskId> --state <in_progress|review>
4266
- \u8BF4\u660E: \u4EFB\u52A1\u72B6\u6001\u63A8\u8FDB\u7531\u670D\u52A1\u7AEF\u9A71\u52A8\uFF08\u6D3E\u5355\u65F6\u6309\u9636\u6BB5\u5BF9\u9F50\u3001PR \u4E8B\u4EF6\u81EA\u52A8\u6D41\u8F6C\uFF09\uFF1B\u4EC5\u5E73\u53F0\u660E\u786E\u8981\u6C42 agent \u81EA\u63A8\u72B6\u6001\u65F6\u4F7F\u7528\u3002`);
4267
- return context.client.http.post(`/agent-tasks/${id}/state`, { stateCode, runtimeId });
4281
+ \u7528\u6CD5: morula task state <taskId> --state <in_progress|review> [--reason <\u6587\u672C>]
4282
+ \u8BF4\u660E: \u6B63\u5411\u63A8\u8FDB\uFF08\u5F85\u5206\u6790\u2192\u5F00\u53D1\u4E2D\u3001\u5F00\u53D1\u4E2D\u2192\u5F85\u8BC4\u5BA1\uFF09\u4F18\u5148\u7531\u7ED3\u8BBA\u534F\u8BAE\u9A71\u52A8\uFF08analysis-verdict / review submit / PR \u4E8B\u4EF6\uFF09\uFF1B
4283
+ \u4EC5\u5E73\u53F0\u660E\u786E\u8981\u6C42 agent \u81EA\u63A8\u72B6\u6001\u65F6\u4F7F\u7528\u3002review\u2192in_progress = \u9000\u56DE\u5F00\u53D1\uFF1A\u4F1A\u81EA\u52A8\u6D3E\u4FEE\u590D\u8F6E\u6B21\uFF08\u540C PR\uFF09\uFF0C--reason \u5199\u660E\u9000\u56DE\u539F\u56E0\u3002`);
4284
+ const body = { stateCode, runtimeId };
4285
+ const reason = flagString(flags, "reason");
4286
+ if (reason?.trim())
4287
+ body.reason = reason.trim();
4288
+ const result = await context.client.http.post(`/agent-tasks/${id}/state`, body);
4289
+ if (result?.ok === false)
4290
+ throw new CliError(result.code ?? "STATE_FAILED", EXIT.OTHER, `\u72B6\u6001\u6D41\u8F6C\u5931\u8D25: ${result.message ?? "\u672A\u77E5\u539F\u56E0"}`);
4291
+ return result;
4292
+ }
4293
+ if (action === "assign") {
4294
+ rejectUnknownFlags(flags, ["to"]);
4295
+ const id = requireId4(positionals, "task assign");
4296
+ const targetPrincipalId = requireFlag(flags, "to");
4297
+ const runtimeId = context.env.MORULA_RUNTIME_ID;
4298
+ if (!runtimeId)
4299
+ throw usage(`task assign \u9700\u8981 MORULA_RUNTIME_ID\uFF08\u7531 daemon \u6CE8\u5165\uFF1Bagent \u4E0D\u624B\u52A8\u6307\u5B9A\uFF09
4300
+
4301
+ \u7528\u6CD5: morula task assign <taskId> --to <principalId>
4302
+ \u8BF4\u660E: \u628A\u672C\u4EFB\u52A1\u5173\u8054\u7684\u4E1A\u52A1\u4EFB\u52A1\u8D1F\u8D23\u4EBA\u6307\u6D3E\u7ED9\u672C\u7A7A\u95F4\u7684\u6210\u5458\u6216\u9636\u6BB5\u6267\u884C\u5668\uFF08principal UUID\uFF09\u3002`);
4303
+ const result = await context.client.http.post(`/agent-tasks/${id}/assignee`, { targetPrincipalId, runtimeId });
4304
+ if (result?.ok === false)
4305
+ throw new CliError(result.code ?? "ASSIGN_FAILED", EXIT.OTHER, `\u6307\u6D3E\u5931\u8D25: ${result.message ?? "\u672A\u77E5\u539F\u56E0"}`);
4306
+ return result;
4268
4307
  }
4269
4308
  if (action === "analysis-verdict") {
4270
4309
  rejectUnknownFlags(flags, ["verdict", "reason"]);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morula-cli",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.17",
4
4
  "description": "Use Morula CLI task management from DimCode.",
5
5
  "interface": {
6
6
  "displayName": "Morula CLI",
@@ -269,9 +269,9 @@ morula task branch <taskId> --name <type>/<slug>
269
269
 
270
270
  ### `morula task state`
271
271
 
272
- **用法**:`morula task state <taskId> [--state <in_progress|review>]`
272
+ **用法**:`morula task state <taskId> [--state <in_progress|review>] [--reason <text>]`
273
273
 
274
- self-transition task state (machine protocol; agent drives todo→in_progress→review, runtimeId from env)
274
+ self-transition task state (machine protocol; agent drives todo→in_progress→review; review→in_progress = 退回开发,平台自动派修复轮次)
275
275
 
276
276
  | 位置参数 | 必填 | 说明 |
277
277
  |---|---|---|
@@ -279,12 +279,36 @@ self-transition task state (machine protocol; agent drives todo→in_progress→
279
279
 
280
280
  | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
281
281
  |---|---|---|---|---|---|
282
- | `--state <in_progress\|review>` | string | 是 | `in_progress` `review` | - | 目标状态 code(必填) |
282
+ | `--state <in_progress\|review>` | string | 是 | `in_progress` `review` | - | 目标状态 code(必填);review→in_progress = 退回开发(自动派修复,不需要再自己 @ 开发执行器) |
283
+ | `--reason <text>` | string | - | - | - | 流转原因(退回开发时写进轮次记账与修复任务 prompt) |
283
284
 
284
285
  **示例**
285
286
 
286
287
  ```bash
287
288
  morula task state <taskId> --state in_progress
289
+ morula task state <taskId> --state in_progress --reason <退回原因>
290
+ ```
291
+
292
+ > `writes: remote` · `interactive: no` · `idempotent: no`
293
+
294
+ ### `morula task assign`
295
+
296
+ **用法**:`morula task assign <taskId> [--to <principalId>]`
297
+
298
+ assign the task owner (machine protocol; target = space member or stage executor principal)
299
+
300
+ | 位置参数 | 必填 | 说明 |
301
+ |---|---|---|
302
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
303
+
304
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
305
+ |---|---|---|---|---|---|
306
+ | `--to <principalId>` | string | 是 | - | - | 目标负责人 principal UUID(本空间成员或阶段执行器;不存在/不在本空间会显式报错) |
307
+
308
+ **示例**
309
+
310
+ ```bash
311
+ morula task assign <taskId> --to <principalId>
288
312
  ```
289
313
 
290
314
  > `writes: remote` · `interactive: no` · `idempotent: no`
@@ -971,9 +995,9 @@ morula comment get <id>
971
995
 
972
996
  ### `morula comment add`
973
997
 
974
- **用法**:`morula comment add [--object <id>] [--content <text>] [--parent <id>] [--format <markdown|plain|richtext>] [--mention <principalId[,principalId]>]`
998
+ **用法**:`morula comment add [--object <id>] [--content <text>] [--parent <id>] [--format <markdown|plain|richtext>] [--mention <principalId[,principalId]>] [--mention-agent <stageExecutorId[,stageExecutorId]>] [--final]`
975
999
 
976
- add comment (format auto-detected; use markdown for agent final summaries). --mention 可 @ 人(触发通知/催办)
1000
+ add comment (format auto-detected; use markdown for agent final summaries). --final 发任务最终总结(同任务只保留一条);--mention 可 @ 人、--mention-agent 可 @ 阶段运行时(触发派发)
977
1001
 
978
1002
  | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
979
1003
  |---|---|---|---|---|---|
@@ -981,14 +1005,17 @@ add comment (format auto-detected; use markdown for agent final summaries). --me
981
1005
  | `--content <text>` | string | 是 | - | - | 评论内容(必填) |
982
1006
  | `--parent <id>` | string | - | - | - | 父评论(回复) |
983
1007
  | `--format <markdown\|plain\|richtext>` | string | - | `markdown` `plain` `richtext` | - | 内容格式(缺省自动检测) |
984
- | `--mention <principalId[,principalId]>` | string | - | - | - | @ 人:被提及者的 principalId,可重复传(--mention a --mention b)或用逗号分隔多个(两种混用自动合并去重保序);只支持人,不支持 @ 运行时/智能体 |
1008
+ | `--mention <principalId[,principalId]>` | string | - | - | - | @ 人:被提及者的 principalId,可重复传或逗号分隔(合并去重保序) |
1009
+ | `--mention-agent <stageExecutorId[,stageExecutorId]>` | string | - | - | - | @ 阶段运行时:空间「阶段 → 运行时」槽位的 stageExecutorId,可重复传或逗号分隔;触发该执行器在任务上干活(评论 @ 派发) |
1010
+ | `--final` | boolean | - | - | - | 标记本条为任务最终总结(仅任务级凭证可用;同一任务只保留一条,重复发会被服务端拒绝——收尾时先发 final 再上报结果) |
985
1011
 
986
1012
  **示例**
987
1013
 
988
1014
  ```bash
989
1015
  morula comment add --object <id> --content <text>
1016
+ morula comment add --object <id> --content <text> --final
1017
+ morula comment add --object <id> --content <text> --mention-agent <stageExecutorId>
990
1018
  morula comment add --object <id> --content <text> --mention <principalId>
991
- morula comment add --object <id> --content <text> --mention <principalIdA> --mention <principalIdB>
992
1019
  ```
993
1020
 
994
1021
  > `writes: remote` · `interactive: no` · `idempotent: no`
@@ -1632,29 +1659,6 @@ morula attachment get <id>
1632
1659
 
1633
1660
  > `writes: none` · `interactive: no` · `idempotent: yes`
1634
1661
 
1635
- ### `morula attachment content`
1636
-
1637
- **用法**:`morula attachment content <id> [--max-chars <n>]`
1638
-
1639
- read the parsed text content (MinerU markdown) of an attachment; unparsed/parsing/failed is reported in the body, not as an HTTP error
1640
-
1641
- | 位置参数 | 必填 | 说明 |
1642
- |---|---|---|
1643
- | `<id>` | 是 | 附件 ID |
1644
-
1645
- | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1646
- |---|---|---|---|---|---|
1647
- | `--max-chars <n>` | number | - | - | - | 最大返回字符数(服务端缺省 8000) |
1648
-
1649
- **示例**
1650
-
1651
- ```bash
1652
- morula attachment content <id>
1653
- morula attachment content <id> --max-chars 20000
1654
- ```
1655
-
1656
- > `writes: none` · `interactive: no` · `idempotent: yes`
1657
-
1658
1662
  ### `morula attachment download-url`
1659
1663
 
1660
1664
  **用法**:`morula attachment download-url <id>`
@@ -172,8 +172,9 @@ allowed-tools: Bash(morula *), Bash(git *), Bash(gh *)
172
172
  morula repo checkout <taskId> <repoFullName> [--ref <branch|sha>] # 拉取/切换仓库(返回物化路径,见 0.5)
173
173
  morula repo prepare <taskId> <repoFullName> # 多仓库任务:物化其他仓库到任务工作区根下(见 0.5)
174
174
  morula comment list --object <objectId> # 读评论(任务=objectId)
175
+ morula comment add --object <objectId> --content <文本> # 发评论(最终总结加 --final,见第 5 条)
175
176
  morula task inbox [--peek] # 运行中检查点:取本线程未消费消息,纳入本回合(见 1.3)
176
- # 注:最终总结评论由服务端统一发送(作者=智能体),不要调用 comment add 自行置评。
177
+ # 注:任务收尾先发 final 总结评论(morula comment add --final),再上报结果;服务端只在你没发时兜底代发一条。
177
178
  ```
178
179
  - **可用仓库清单**:系统提示**不再列出**仓库——需要枚举空间绑定的仓库时用
179
180
  `morula repo list --space <spaceId>`(`<spaceId>` 见系统提示「基本信息」段,或 `morula task get` 返回的 `contextSnapshot.spaceId`)。
@@ -303,26 +304,34 @@ morula task inbox --peek # 只看不取(确认有没有新意见,不标
303
304
  - PR 创建被阻塞(权限/测试失败/远端状态异常)→ 在最终总结中**报告阻塞原因**,不要假装任务已完成;
304
305
  - **不要**切回 `main` 或 `master` 直接提交。
305
306
 
306
- ## 4. 状态变更由服务端驱动,不要手动翻状态
307
+ ## 4. 状态与任务操作:结论优先,动作为辅
307
308
 
308
- - 任务状态推进(如完成)由 PR merge 事件自动触发(配合第 2 条的关单写法)。
309
- - 不要直接调 CLI 改任务状态;把状态流转交给服务端。
309
+ - **状态推进由结论协议与事实事件驱动**:分析任务上报 `analysis-verdict`、评审任务用 `morula review submit`、合并/发布由 PR 事件驱动——**不要**用状态动作替代结论协议。
310
+ - **你可以在任务上做基础操作**(像人一样,作用域仅限本任务):
311
+ - `morula task state <taskId> --state <in_progress|review> [--reason <文本>]`:在「开发中 / 待评审」范围内自推状态;**待评审 → 开发中 = 退回开发**——平台会自动回退状态、记评审轮次并派发修复任务(同一 PR 迭代),**不需要、也不应该**再自己 @ 开发执行器;`--reason` 写明退回原因(会进修复任务 prompt)。
312
+ - `morula comment add`:见第 5 条评论纪律。
313
+ - `morula task assign <taskId> --to <principalId>`:指派本任务负责人(本空间成员或阶段执行器;目标不存在会显式报错)。
314
+ - **终态(已合并/已发布/已关闭)与需求池状态不由你声明**;同态重复推送是幂等的(无害)。
310
315
 
311
316
  ## 4.1 分析任务:必须上报分析结论(verdict)
312
317
 
313
318
  > **仅当本任务是「待分析」任务时适用**(任务停在「待分析」阶段、要求做需求分析与方案拆解、不写代码)。
314
319
  > 其余任务(开发 / 评审 / 调研 / 问答)跳过本节,不要调用该命令。
315
320
 
316
- - 分析结论分两部分,**都要给**:
317
- 1. **人看的**:分析结论写进最终输出(需求是否清晰、怎么做、范围与风险、验收点)——服务端作为任务评论发布;
318
- 2. **机器判定的**:执行 `morula task analysis-verdict <taskId> --verdict ready|blocked [--reason "…"]` 上报结论。
321
+ - 分析结论分两部分,**都要给**(顺序:先发评论,再上报 verdict):
322
+ 1. **人看的**:用**你自己的话**把分析结论发成最终总结评论——需求是否清晰、怎么做、范围与风险、验收点:
323
+ ```bash
324
+ morula comment add --object <objectId> --final --content <你的分析结论>
325
+ ```
326
+ 这是用户看到的分析交付:用自己的话写,不要套固定格式,更不要复述任务描述;结论先说、理由跟上。
327
+ 2. **机器判定的**:执行 `morula task analysis-verdict <taskId> --verdict ready|blocked [--reason "…"]` 上报结论(`--reason` 只需一句话,详细内容在评论里)。
319
328
  - `<taskId>` = `morula task get`(无参)返回的 `id`(本任务 AgentTask UUID)。
320
329
  - **`ready`** = 需求清晰、可直接开发(`--reason` 可写一句话范围摘要);
321
330
  **`blocked`** = 不可做 / 需澄清(**必须**在 `--reason` 或最终输出里写清阻塞点与需要澄清的问题)。
322
331
  - **服务端据此自动推进,不需要任何人点确认**:`ready` → 任务自动进入「开发中」并派发开发任务;
323
332
  `blocked` / 未上报 → 任务**停在「待分析」**,由用户补充需求后重派分析。
324
333
  - **必须上报**:漏报会让任务静默停在「待分析」;同一任务只需上报一次(重复上报以首次为准,不会改写)。
325
- - **不要手动流转本任务状态**(不要调 `morula task state`):分析任务的推进由服务端按 verdict 决定。
334
+ - 分析任务的推进由服务端按 verdict 决定——**不要用状态动作替代分析结论**(不要调 `morula task state`)。
326
335
 
327
336
  ## 4.2 评审任务:只读评审 + 必须回传结论(verdict)
328
337
 
@@ -343,9 +352,11 @@ morula task inbox --peek # 只看不取(确认有没有新意见,不标
343
352
  - `<objectId>` = `morula task get`(无参)返回的 `objectId`;
344
353
  - `--verdict`:`approved`(通过)/ `changes_requested`(不通过,**必须**在 `--details` 写明具体意见:文件/行/问题/建议,否则开发无法修复)/ `commented`(有意见但不阻塞);
345
354
  - `--pr-number`:评审对象的 PR 编号(有则填)。
355
+ - **评审任务的交付就是这份结论**:平台会按结论写权威评论(✅/💬/🔁)——**不要**再发最终总结评论(`--final` 会被服务端拒绝),也不要在评论区复述结论。
356
+ - **结论新鲜度(无新提交不重复投 `approved`)**:提交结论前先核对被评审 MR 的 head commit 与上一轮结论时是否相同(`morula repo mr list` / `mr-detail`;评论区也有上一轮结论)。**相同且无新提交时不要重复投 `approved`**:本轮任务上下文里有人的新要求(如要求修复上一轮意见)→ 按人的要求处理(意见未修复就投 `changes_requested`);确实无可评审内容 → 投 `commented` 说明「无新提交」即可。复述上一轮结论对任务没有任何推进。
346
357
  - **禁止评审自己开发的任务**:若待评审改动由你自己提交(同一智能体既开发又评审),不下结论,直接报告该配置问题。
347
- - **不要手动流转本任务状态**(不要调 `morula task state`):评审结论由服务端据此推进。
348
358
  - **必须上报**:漏报会让任务停在「待评审」,开发无法进入下一轮。
359
+ - 退回开发**首选结论协议**:`--verdict changes_requested`(带具体意见)与服务端结论链路完全等价;`morula task state --state in_progress` 是等价的替代入口(见第 4 条),不是绕过。
349
360
 
350
361
  ## 4.3 在 MR/PR 上留评审意见(巡检/审查类任务,非评审任务时)
351
362
 
@@ -361,36 +372,30 @@ morula task inbox --peek # 只看不取(确认有没有新意见,不标
361
372
  - 若本自动化已就同一问题留过评论、结论与这次一致 → **不要重复评论**;
362
373
  - ⛔ **不要用 `morula review submit`**(那是评审任务的机器协议,会驱动业务任务状态回退)。
363
374
 
364
- ## 5. 评论交付纪律
365
-
366
- - **何时发评论**:**最终总结评论由服务端统一以智能体身份发送**(任务完成时自动发布到任务对象,作者=当前智能体)。**你不需要、也不应调用 `morula comment add`**——只要在最终输出里给出用户关心的结论即可,服务端会作为该智能体的完成评论发布。chat 会话无 objectId 的任务(纯对话派发)不回评论——最终交付由 daemon 回填 assistant 消息。
367
- - **终端输出、思考过程、工具日志用户都看不到**——用户看到的只有服务端整合后发布的最终总结评论。
368
- - **评论 @触发任务(本任务由评论触发)**:服务端会把最终总结自动作为**该触发评论的回复**发出(挂在被 @ 的评论下)。你无需、也不要自己调用 `morula comment add`/add_comment。
369
- - **防重复(服务端保证)**:服务端对「同一个任务只发一条完成评论」做幂等,不会重复刷屏。你不需要、也不要去查/发多条。
370
- - **最终输出 = 只留结论**(不设字数上限、不要求固定格式,自然组织即可):
371
- - 必答:**做了什么、结果如何、用户需要知道的后续**。
372
- - **PR 汇报仅当「任务涉及代码改动」或「用户明确问到 PR/合并」时给出**;纯问答/调研类任务不要出现 PR/分支章节,直接回答问题。
373
- - **不要写**:思考过程、探索步骤、工具日志、终端输出、英文过程性叙述——用户只关心「做了什么、结果怎样」,不关心「怎么做的」。
374
- - 内容较多时用小标题/列表组织,让结论先置顶。
375
- - **过程文本必须加分隔符**:服务端取你的最终输出时按优先级截取「总结段」,**最高优先级是分隔符 `---FINAL---`**(独占一行、前后各空一行)。若你的输出里混入了中间过程(英文探索叙述、工具尝试记录、思考片段),**必须**在真正的总结之前插入该分隔符——服务端只保留它之后的内容:
375
+ ## 5. 评论交付纪律(最终总结由你自己发布)
376
376
 
377
+ - **最终总结评论由你自己发布**:任务收尾时执行
378
+ ```bash
379
+ morula comment add --object <objectId> --final --content <结论>
377
380
  ```
378
- ...(前面的过程文本,会被服务端自动截掉)...
379
-
380
- ---FINAL---
381
-
382
- ## 总结
383
-
384
- ...(真正的总结内容,会展示给用户)...
381
+ 作者=你(智能体身份);评论触发任务时服务端会**自动把它挂到触发评论下**作为回复(无需自己查评论 ID)。
382
+ **先发 final 评论、再上报任务结果**——服务端在你完成时检查:没发过 final 才会兜底代发一条(同一任务只会保留一条最终总结,重复发送会被服务端拒绝,这是预期内的幂等保护)。
383
+ - **例外:评审任务不需要(也不应)发 final**——你的结论已经通过 `morula review submit` 机器协议上报,平台会据此写权威结论评论(✅ 通过 / 💬 非阻塞 / 🔁 未通过);再发一条 final 总结会让同一结论在评论区**说两遍**(服务端也会拒绝评审任务的 final)。需要发 final 的是开发 / 修复 / 分析 / 问答 / 评论触发类任务——内容**用你自己的话写**,不要套模板。
384
+ - **普通评论**(说明进展、@ 其他人或运行时)随时可发:
385
+ ```bash
386
+ morula comment add --object <objectId> --content <文本>
387
+ morula comment add --object <objectId> --content <文本> --mention-agent <stageExecutorId> # @ 阶段运行时(触发该执行器在本任务上干活)
385
388
  ```
386
-
387
- 服务端同时兼容 `---SUMMARY---`。**不写分隔符时**,服务端只能退回「按总结类标题 / 水平线猜测」,猜不中就会把你的过程文本一起发给用户——所以混了过程就一定要加。
388
- - 不要包含工具调试过程、内部日志、任何凭据或 token 信息。
389
+ chat 会话无 objectId 的任务(纯对话派发)不发评论——最终交付由 daemon 回填 assistant 消息。
390
+ - **评论纪律:只写结论与事实**——做了什么、结果如何、用户需要知道的后续;**不写**思考过程、探索步骤、工具日志、终端输出、命令回显。用户只关心「做了什么、结果怎样」,不关心「怎么做的」。内容较多时用小标题/列表组织,结论先置顶。
391
+ - **PR 汇报仅当「任务涉及代码改动」或「用户明确问到 PR/合并」时给出**;纯问答/调研类任务不要出现 PR/分支章节。
392
+ - **任务结果文本同样只写结论**:上报的任务结果会被服务端用于缺失兜底与通知摘要——若结果里混入了中间过程(英文探索叙述、工具尝试记录、思考片段),**必须**在真正的总结之前插入独占一行的 `---FINAL---` 分隔符,服务端兜底时只保留它之后的内容(`---SUMMARY---` 同样兼容;不写时服务端退回「按总结类标题 / 水平线猜测」,猜不中会把过程文本一起兜底出去)。
389
393
  - **不要把本地绝对路径当交付物**:工作目录路径只属于执行它的机器,读者打不开;生成的文件**必须先回传平台**(见 1.1 `morula attachment upload`),交付物用平台下载链接或仓库内相对路径。
394
+ - 不要包含工具调试过程、内部日志、任何凭据或 token 信息。
390
395
 
391
396
  ## 6. 禁止事项
392
397
 
393
- - 禁止直接调用 morula REST API / 非 CLI 方式写评论、改状态、读数据;**不要调用 `morula comment add` 自行置评**——完成评论由服务端统一发送。
398
+ - 禁止直接调用 morula REST API / 非 CLI 方式写评论、改状态、读数据——与平台交互只走 morula CLI(评论用第 5 条的 `morula comment add`,状态用第 4 条的 `morula task state`)。
394
399
  - 禁止读取 `~/.morula-cli`、凭据文件、环境变量中的密钥。
395
400
  - 只在任务指定的工作目录与仓库内操作,不要探索工作目录之外的文件系统。
396
401
  - 禁止把 token、安装 ID、内部 URL 写进评论或 commit。
@@ -15,7 +15,7 @@
15
15
  | 契约 | 实现 | 位置 |
16
16
  |------|------|------|
17
17
  | CLI 读评论 | `morula comment list --object <objectId>` | `packages/morula-cli/src/commands/comment.ts` |
18
- | CLI 写评论(**契约禁止 agent 自行调用**:完成评论由服务端统一发送,见本文件第 5 条) | `morula comment add`(命令存在,但本契约要求不调用) | `packages/morula-cli/src/commands/comment.ts` |
18
+ | CLI 写评论(**由 agent 自己发**,含 `--final` 最终总结与 `--mention-agent` @ 运行时;见本文件第 5 条) | `morula comment add` → `POST /comments`(agent_task 凭证;`kind='final'` 按 `(taskId, kind)` 唯一防重) | `packages/morula-cli/src/commands/comment.ts`、`src/modules/task-management/comment/comment.service.ts` |
19
19
  | CLI 任务详情(**无参**取本任务;带参取业务对象) | `morula task get` → `GET /agent-tasks/:id`;`morula task get <objectId>` → `GET /objects/:id` | `packages/morula-cli/src/commands/task.ts` |
20
20
  | daemon 注入凭据(agent 无需自行登录) | runner 注入 `env` 给 Provider 子进程 | `packages/runtime/src/daemon/runner.ts` |
21
21
  | 调 CLI 用 `$MORULA_CLI`(绝对路径,与当前 daemon 同源;PATH 上的裸 `morula` 可能是宿主自带的旧版) | `resolveAgentCliPath`(优先本包 `dist/morula.js`,产物缺失回退插件启动器);注入点:任务链路 `env`、会话链路 `env` | `packages/runtime/src/daemon/plugin-register.ts`、`runner.ts`、`session-host.ts` |
@@ -34,12 +34,15 @@
34
34
  | delivery 以本地实际分支为准 | `reportPrDelivery` 读 `git branch --show-current`,跳过占位/主干 | `packages/runtime/src/daemon/runner.ts` |
35
35
  | 交付上报遍历本任务全部仓库 | 主仓库目录(工作区根下的仓库子目录)+ 其余同级仓库子目录(prepare 产物,磁盘事实;按 repoFullName 归属排除主仓库),逐仓上报 branch/pushState、逐仓独立成败;次仓库 `workContextId` 省略时服务端按 `(lastAgentTaskId, repoFullName)` 反查 | `reportPrDelivery`/`reportRepoTargets`(`runner.ts`)、`collectMaterializedRepoDeliveryTargets`(`repo-checkout-service.ts`) |
36
36
 
37
- ## 4. 状态由服务端驱动(agent 不手动翻状态)
37
+ ## 4. 状态与任务操作(结论优先、动作为辅;proposal stage-runtime-as-task-actor)
38
38
 
39
39
  | 契约 | 实现 | 位置 |
40
40
  |------|------|------|
41
- | merge 自动关单(服务端驱动状态) | webhook merged → 按平台事实定位已关联链接 → 汇总 → Object 完成 | `src/modules/vcs-integration/webhook/vcs-event.service.ts`、`link/vcs-link.service.ts` |
42
- | agent 不调 CLI 改状态 | 协作契约第 4 条。**注意:CLI 有 `morula task state <id> --state <code>`**(机器协议 `POST /agent-tasks/:id/state`,供平台/自流转使用)——是**契约要求 agent 不调用**它,不是「CLI 没有这个命令」 | `packages/morula-cli/src/commands/task.ts`(action `state`)、`src/modules/agent-task/agent-task.controller.ts`(端点) |
41
+ | merge 自动关单(事实事件驱动状态) | webhook merged → 按平台事实定位已关联链接 → 汇总 → Object 完成 | `src/modules/vcs-integration/webhook/vcs-event.service.ts`、`link/vcs-link.service.ts` |
42
+ | 运行时可声明状态集合 = `in_progress` / `review`(D8 落地口径;终态与 backlog/todo 不可声明,D5) | `resolveRuntimeStateTransition`(唯一定义:控制器端点与 change_object_status 工具共用);正向走事件级规则 + ObjectService.update | `src/modules/agent-task/domain/runtime-state-actions.ts`、`agent-task.controller.ts`(`POST :id/state`) |
43
+ | **待评审 → 开发中 = 退回开发,单一效应入口**(记账 + 回退 + 派修复 + 双触发去重;不做裸状态写) | `ReviewLoopService.runtimeRevertToDev`(与 verdict 路径 `handleRejected` 共用 `dispatchDevRework`;事实去重 = 对象已有未完成 dev 任务则只记账不派单) | `src/modules/agent-task/review-loop.service.ts` |
44
+ | 任务活跃门禁(终态任务的 token 不得再推状态/指派) | `ACTIVE_TASK_STATUSES`(queued/dispatched/running/awaiting_approval) | `src/modules/agent-task/domain/runtime-state-actions.ts` |
45
+ | 指派负责人(目标 = 本空间成员或阶段执行器 principal;失败显式报错) | `POST /agent-tasks/:id/assignee`(ObjectService.update 落库,agent_task 字段白名单含 assigneePrincipalId) | `agent-task.controller.ts`、`object.service.ts` |
43
46
 
44
47
  ## 4.1 评审任务结论回传(morula review submit)
45
48
 
@@ -48,15 +51,17 @@
48
51
  | 评审结论机器协议(approved / changes_requested / commented,changes_requested 必须带 details) | `morula review submit <objectId> --verdict ... [--details] [--pr-number]` → `POST /agent-collaborations/review/submit`(服务端校验调用者 = 评审任务后落库并驱动回环) | `packages/morula-cli/src/commands/review.ts`、`src/modules/agent-task/review-loop.service.ts` |
49
52
  | 评审对象(objectId)经 AgentTask 本体下发(`morula task get` 无参返回) | AgentTask 记录 `objectId` 字段(enqueue 时写入) | `src/modules/agent-task/review-loop.service.ts` |
50
53
 
51
- ## 5. 评论交付纪律(一条最终评论,结果上平台)
54
+ ## 5. 评论交付纪律(最终总结由运行时自发,服务端防重兜底)
52
55
 
53
56
  | 契约 | 实现 | 位置 |
54
57
  |------|------|------|
55
- | 评论是用户可见的唯一通道;**完成评论由服务端统一以智能体身份发送**(agent 不调 `comment add`) | 服务端 `finalOutput` 回填 + 聚合发布;评论 @触发任务的总结自动挂到触发评论下(hasAgentRepliedToTrigger 去重) | `src/modules/agent-task/task-lifecycle.service.ts`、本 SKILL 第 5 条 |
56
- | 最终输出截取「总结段」(最高优先级 = `---FINAL---` 分隔符) | `cleanFinalOutput`:分隔符 → 总结类标题 → 水平线 → 原文兜底 | `src/modules/agent-task/task-lifecycle.service.ts` |
57
- | **评论 @触发任务 → 最终总结由服务端自动回复到触发评论下**(agent 无需评论 ID,不注入提示词) | 结构性挂靠:`CommentService.create`(resolveCommentAuthor 返回 triggerCommentId → parentCommentId 默认值);生命周期兜底:`task-lifecycle.service.ts` hasAgentRepliedToTrigger / isMentionReply | LOCAL-AGENT-COMMENT-REPLY-001 |
58
+ | 评论是用户可见的产出通道;**最终总结由 agent 自己发**(`morula comment add --final`,作者=智能体) | `POST /comments`(agent_task 凭证;`kind='final'` 服务端回填 `taskId`,`(tenantId, taskId, kind)` 唯一约束 → 同一任务一条) | `packages/morula-cli/src/commands/comment.ts`、`src/modules/task-management/comment/comment.service.ts`(FINAL-COMMENT-001) |
59
+ | **服务端缺失兜底**(DP-1):任务完成时检查没发过 final 才代发一条(占住唯一键;运行时迟到补发被拒绝) | `task-lifecycle.service.ts` onTaskCompleted:`runtimeFinalExists` 检查 + 兜底 create 带 `taskId/kind`(并发由 P2002 捕获) | `src/modules/agent-task/task-lifecycle.service.ts` |
60
+ | 兜底路径截取「总结段」(`---FINAL---` 分隔符 → 总结标题 → 水平线 → 原文兜底) | `cleanFinalOutput`(仅兜底代发路径使用;运行时自发路径内容纪律靠契约) | `src/modules/agent-task/task-lifecycle.service.ts` |
61
+ | **评论 @触发任务 → agent 的 final 自动挂到触发评论下**(agent 无需评论 ID) | 结构性挂靠:`CommentService.create`(resolveCommentAuthor 返回 triggerCommentId → parentCommentId 默认值);生命周期兜底:hasAgentRepliedToTrigger / isMentionReply | LOCAL-AGENT-COMMENT-REPLY-001 |
62
+ | **@ 阶段运行时**(`--mention-agent <stageExecutorId>`)→ 触发该执行器在任务上干活 | mentions 数组 agent 类型项 → `comment.mentioned` 事件 → AgentCollaborationService 派发 | `comment.service.ts`、`agent-collaboration.service.ts` |
58
63
  | 禁止本地绝对路径作为交付物 | 契约第 5 条;`reportPrDelivery` 只回报仓库相对信息 | `packages/runtime/src/daemon/runner.ts` |
59
- | 单条最终评论(不刷进度) | 契约第 5 条 | 本 SKILL |
64
+ | 单条最终评论(不刷进度;评论只写结论与事实,D10) | 契约第 5 条 + 唯一约束 | 本 SKILL |
60
65
 
61
66
  ## 6. 禁止事项
62
67
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arcships/morula-runtime",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.16",
4
+ "version": "0.1.0-alpha.17",
5
5
  "description": "Device-level CLI for the Morula local agent runtime (daemon/portal/models/auth) and the Morula business CLI (morula), distributed via npm",
6
6
  "bin": {
7
7
  "morula-runtime": "./bin/morula-runtime.js",