@ai-setting/roy-task-plugin 0.7.12 → 0.7.13

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.
@@ -67,7 +67,7 @@ the user sees.
67
67
 
68
68
  5. RECORD — operation records (see Operation Discipline below)
69
69
 
70
- 6. COMPLETE — 收尾:用 `task_complete` after item-by-item verification
70
+ 6. COMPLETE — 收尾:用 `task_complete` after item-by-item verification (see Complete Discipline below)
71
71
 
72
72
  ### Goals 子项拆分规则
73
73
 
@@ -141,7 +141,6 @@ stage is reached, **not after the fact** (not in a batch at the end).
141
141
 
142
142
  ### Task Complete — 核实义务
143
143
 
144
-
145
144
  Before calling `task_complete`, you MUST:
146
145
 
147
146
  1. Read the task's `goal` (description) and `delivery` (goals_and_expected_deliverables) fields.
package/dist/cli.js CHANGED
@@ -458,10 +458,15 @@ import {
458
458
  } from "@ai-setting/roy-agent-core/env/task/prompt";
459
459
 
460
460
  // ../agent/src/trim-permission.ts
461
+ var ROLE_SCOPE_QUALIFIER = /验收方|收尾分两种角色/;
461
462
  var TRIM_RULES = Object.freeze([
462
463
  {
463
464
  name: "complete-禁止调用",
464
- match: (line) => /不要调用/.test(line) && /task_complete/.test(line) && /权限/.test(line)
465
+ match: (line) => /(不要|禁止|别|无需|不需要|不能|无权|不得|仍无|不持有|不具备|未获得)/.test(line) && /task_complete/.test(line)
466
+ },
467
+ {
468
+ name: "角色权限断言",
469
+ match: (line) => /(执行方|验收方)/.test(line) && /(权限|资格|无权|不能|没有)/.test(line) && /task_complete/.test(line) && !/你的收尾动作是/.test(line)
465
470
  },
466
471
  {
467
472
  name: "track-禁止置终态",
@@ -470,19 +475,45 @@ var TRIM_RULES = Object.freeze([
470
475
  {
471
476
  name: "lifecycle-角色二分标题",
472
477
  match: (line) => /收尾分两种角色/.test(line),
473
- replace: () => "6. COMPLETE — 收尾:用 `task_complete` after item-by-item verification",
474
- dropFollowing: 5
478
+ replace: () => "6. COMPLETE — 收尾:用 `task_complete` after item-by-item verification" + " (see Complete Discipline below)"
479
+ },
480
+ {
481
+ name: "lifecycle-执行方条目",
482
+ match: (line) => /执行方/.test(line) && /(roy )?sub-agent/.test(line)
483
+ },
484
+ {
485
+ name: "lifecycle-执行方收尾指令",
486
+ match: (line, ctx) => (/结束并返回结果|结束并返回/.test(line) || /最后一条/.test(line) && /task_operation_create/.test(line)) && (/执行方/.test(line) || /执行方/.test(ctx.prevLine ?? ""))
487
+ },
488
+ {
489
+ name: "lifecycle-验收方条目",
490
+ match: (line) => /验收方/.test(line) && /(default agent|接待员)/.test(line)
475
491
  },
476
492
  {
477
493
  name: "complete-标题角色限定",
478
- match: (line) => /^#{1,6}\s/.test(line) && /仅验收方适用/.test(line),
479
- replace: (line) => line.replace(/\s*(\*\*仅验收方适用\*\*)/, "")
494
+ match: (line) => /^#{1,6}\s/.test(line) && /验收方/.test(line),
495
+ replace: (line) => line.replace(/\s*[((][^))]*验收方[^))]*[))]/g, "")
480
496
  },
481
497
  {
482
498
  name: "complete-角色作用域引用块",
483
499
  match: (line) => /角色作用域/.test(line) || /若你是/.test(line) && /执行方/.test(line) && /权限/.test(line) || /你的收尾动作是/.test(line) && /验收由主智能体负责/.test(line)
484
500
  }
485
501
  ]);
502
+ function isListItemHead(line) {
503
+ return /^\s*([-*+]\s|\d+\.\s)/.test(line);
504
+ }
505
+ function isContinuationOf(line, head) {
506
+ if (isListItemHead(line))
507
+ return false;
508
+ if (/^\s*(#{1,6}\s|>)/.test(line))
509
+ return false;
510
+ if (/^\s*```/.test(line))
511
+ return false;
512
+ if (line.trim() === "")
513
+ return false;
514
+ const indent = (s) => s.match(/^\s*/)?.[0].length ?? 0;
515
+ return indent(line) > indent(head);
516
+ }
486
517
  function trimTaskCompletePermissionText(text) {
487
518
  if (!text)
488
519
  return text;
@@ -491,19 +522,39 @@ function trimTaskCompletePermissionText(text) {
491
522
  const out = [];
492
523
  for (let i = 0;i < lines.length; i++) {
493
524
  const line = lines[i];
494
- const rule = TRIM_RULES.find((r) => r.match(line));
525
+ const rule = TRIM_RULES.find((r) => r.match(line, { prevLine: lines[i - 1] }));
495
526
  if (!rule) {
496
527
  out.push(line);
497
528
  continue;
498
529
  }
499
- if (rule.replace)
500
- out.push(rule.replace(line));
501
- const drop = rule.dropFollowing ?? 0;
502
- for (let k = 0;k < drop && i + 1 < lines.length; k++) {
503
- i++;
530
+ if (rule.replace) {
531
+ const replaced = rule.replace(line);
532
+ if (ROLE_SCOPE_QUALIFIER.test(replaced)) {
533
+ throw new Error(`trim-permission: rule "${rule.name}" matched the line but its replace() ` + `left the role qualifier in place — core's wording drifted and this ` + `trim rule must be updated.
534
+ line: ${line}`);
535
+ }
536
+ out.push(replaced);
537
+ }
538
+ if (!rule.replace && isListItemHead(line)) {
539
+ while (i + 1 < lines.length && isContinuationOf(lines[i + 1], line)) {
540
+ i++;
541
+ }
542
+ }
543
+ }
544
+ const collapsed = [];
545
+ let inFence = false;
546
+ for (const line of out) {
547
+ if (/^\s*```/.test(line)) {
548
+ inFence = !inFence;
549
+ collapsed.push(line);
550
+ continue;
551
+ }
552
+ if (!inFence && line.trim() === "" && collapsed.length > 0 && collapsed[collapsed.length - 1].trim() === "") {
553
+ continue;
504
554
  }
555
+ collapsed.push(line);
505
556
  }
506
- return out.join(`
557
+ return collapsed.join(`
507
558
  `);
508
559
  }
509
560
 
@@ -1211,7 +1262,8 @@ function errMsg(err) {
1211
1262
 
1212
1263
  // ../../../packages/cli/src/daemon/discipline.ts
1213
1264
  import { TASK_DISCIPLINE_PROMPT } from "@ai-setting/roy-agent-core/env/task/prompt";
1214
- var PLUGIN_TASK_DISCIPLINE_PROMPT = trimTaskCompletePermissionText(TASK_DISCIPLINE_PROMPT);
1265
+ var CORE_TASK_DISCIPLINE_PROMPT_RAW = TASK_DISCIPLINE_PROMPT;
1266
+ var PLUGIN_TASK_DISCIPLINE_PROMPT = trimTaskCompletePermissionText(CORE_TASK_DISCIPLINE_PROMPT_RAW);
1215
1267
  var RUNTIMES_WITH_AGENT_SYSTEM_PROMPT = Object.freeze([
1216
1268
  "opencode",
1217
1269
  "claude"
@@ -3559,7 +3611,7 @@ function formatStatus(report) {
3559
3611
  }
3560
3612
 
3561
3613
  // ../../../packages/cli/src/main.ts
3562
- var VERSION = "0.7.12";
3614
+ var VERSION = "0.7.13";
3563
3615
  async function main(argv) {
3564
3616
  const parsed = parseArgs(argv);
3565
3617
  switch (parsed.command) {