@lazyingart/agintiflow 0.20.270 → 0.20.272

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.270",
3
+ "version": "0.20.272",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
@@ -5485,6 +5485,65 @@ try {
5485
5485
  runtime: postProducerRuntime,
5486
5486
  })}`
5487
5487
  );
5488
+ const failedAfterProducerState = structuredClone(staleGeneratedDeckState);
5489
+ failedAfterProducerState.meta.goalContract.taskGoal = failedAfterProducerState.goal;
5490
+ failedAfterProducerState.meta.projectVerification.mutationHistory.splice(1, 0, {
5491
+ revision: 8,
5492
+ toolName: "apply_patch",
5493
+ paths: ["TASK.md"],
5494
+ });
5495
+ failedAfterProducerState.meta.projectVerification.testRuns.push({
5496
+ command: generatedDeckValidator,
5497
+ at: "2026-08-27T19:05:00.000Z",
5498
+ mutationRevision: 10,
5499
+ privateMutationRevision: 0,
5500
+ passed: false,
5501
+ failureEvidenceVersion: 2,
5502
+ failureSignature: "fresh-generated-deck-visible-text",
5503
+ failureSummary: "acceptance failed: deck omits source-grounded phrase: single reader",
5504
+ });
5505
+ await fs.writeFile(
5506
+ path.join(workspace, "TASK.md"),
5507
+ "Treat source_brief.md, measurements.csv, prompt.txt, and TASK.md as immutable.\n",
5508
+ "utf8"
5509
+ );
5510
+ const failedAfterProducerPacket = await buildFailedTestRecoveryPacket(
5511
+ {
5512
+ provider: "deepseek",
5513
+ taskProfile: "slides",
5514
+ commandCwd: workspace,
5515
+ goal: failedAfterProducerState.goal,
5516
+ },
5517
+ failedAfterProducerState
5518
+ );
5519
+ assert(
5520
+ JSON.stringify(failedAfterProducerPacket.repairPaths) ===
5521
+ JSON.stringify(["build_deck.py"]),
5522
+ "a fresh generated-artifact failure dropped its latest mutable producer or retained an explicitly immutable input"
5523
+ );
5524
+ failedAfterProducerState.meta.failedTestRecoveryPacket = {
5525
+ packetVersion: 15,
5526
+ content: failedAfterProducerPacket.content,
5527
+ paths: failedAfterProducerPacket.paths,
5528
+ repairPaths: failedAfterProducerPacket.repairPaths,
5529
+ mutationRevision: 10,
5530
+ failureSignature: "fresh-generated-deck-visible-text",
5531
+ generatedAt: "2026-08-27T19:05:01.000Z",
5532
+ };
5533
+ const failedAfterProducerRuntime = nextStepRuntimeConfig(
5534
+ {
5535
+ provider: "deepseek",
5536
+ taskProfile: "slides",
5537
+ commandCwd: workspace,
5538
+ goal: failedAfterProducerState.goal,
5539
+ },
5540
+ failedAfterProducerState
5541
+ );
5542
+ assert(
5543
+ JSON.stringify(failedAfterProducerRuntime.testFailureRepairContextPaths) ===
5544
+ JSON.stringify(["build_deck.py"]),
5545
+ "failed-test recovery forced immutable evidence reads instead of grounding the canonical producer"
5546
+ );
5488
5547
  const immutableOnlyRepairState = {
5489
5548
  goal: "Treat service_ctl.py as immutable read-only source evidence and finish from existing results.",
5490
5549
  meta: {
@@ -6265,6 +6324,22 @@ try {
6265
6324
  })?.category === "repeated-no-progress-call",
6266
6325
  "a third identical unchanged shell probe was not blocked"
6267
6326
  );
6327
+ assert(
6328
+ repeatedNoProgressToolBlock(repeatedProbeState, "run_command", repeatedProbeArgs, {
6329
+ commandCwd: workspace,
6330
+ generatedArtifactProducerPending: true,
6331
+ generatedArtifactProducerCommand: repeatedProbeArgs.command,
6332
+ }) === null,
6333
+ "the exact authoritative generated-artifact producer remained blocked by stale no-progress history"
6334
+ );
6335
+ assert(
6336
+ repeatedNoProgressToolBlock(repeatedProbeState, "run_command", repeatedProbeArgs, {
6337
+ commandCwd: workspace,
6338
+ generatedArtifactProducerPending: true,
6339
+ generatedArtifactProducerCommand: "python3 build_deck.py",
6340
+ })?.category === "repeated-no-progress-call",
6341
+ "a mismatched generated-artifact producer disabled the ordinary no-progress guard"
6342
+ );
6268
6343
  const repeatedFailureState = {
6269
6344
  meta: {
6270
6345
  toolLoop: {
@@ -1685,7 +1685,10 @@ assert(
1685
1685
  "a pending exact verifier did not activate the constrained project-command phase"
1686
1686
  );
1687
1687
  const exactVerifierTools = selectProgressiveTools(allTools, {
1688
- config: exactVerifierRuntime,
1688
+ config: {
1689
+ ...exactVerifierRuntime,
1690
+ convergenceSuppressedToolNames: ["run_command"],
1691
+ },
1689
1692
  goal: `Run ${exactVerifier}.`,
1690
1693
  profile: "security",
1691
1694
  });
@@ -1754,6 +1757,7 @@ const generatedArtifactProducerTools = selectProgressiveTools(allTools, {
1754
1757
  testFailureRepairMutationRequired: true,
1755
1758
  generatedArtifactProducerPending: true,
1756
1759
  generatedArtifactProducerCommand: "python3 build_deck.py",
1760
+ convergenceSuppressedToolNames: ["run_command"],
1757
1761
  },
1758
1762
  goal: "Rebuild the generated presentation before rerunning its validator.",
1759
1763
  profile: "slides",
@@ -1768,6 +1772,22 @@ assertStrict.deepEqual(
1768
1772
  ["python3 build_deck.py"],
1769
1773
  "the generated-artifact producer command was not schema-constrained"
1770
1774
  );
1775
+ const disabledGeneratedArtifactProducerTools = selectProgressiveTools(allTools, {
1776
+ config: {
1777
+ provider: "localllm",
1778
+ allowShellTool: false,
1779
+ generatedArtifactProducerPending: true,
1780
+ generatedArtifactProducerCommand: "python3 build_deck.py",
1781
+ convergenceSuppressedToolNames: ["run_command"],
1782
+ },
1783
+ goal: "Rebuild the generated presentation.",
1784
+ profile: "slides",
1785
+ });
1786
+ sameNames(
1787
+ disabledGeneratedArtifactProducerTools,
1788
+ ["finish"],
1789
+ "an authoritative producer phase bypassed an explicit shell capability disable"
1790
+ );
1771
1791
 
1772
1792
  const mutationOnlyFailedTestRepairTools = selectProgressiveTools(allTools, {
1773
1793
  config: {
@@ -3523,6 +3543,7 @@ const pendingTestTools = selectProgressiveTools(allTools, {
3523
3543
  provider: "localllm",
3524
3544
  testVerificationPending: true,
3525
3545
  testVerificationCommand: "python -m unittest discover -s tests -v",
3546
+ convergenceSuppressedToolNames: ["run_command"],
3526
3547
  },
3527
3548
  goal: "Verify the canonical mutation.",
3528
3549
  profile: "data",
@@ -70,6 +70,24 @@ const wrappedImmutableSourceContract = deriveScsTaskContract({
70
70
  taskProfile: "slides",
71
71
  });
72
72
 
73
+ const actionWrappedImmutableSourceContract = deriveScsTaskContract({
74
+ goal: [
75
+ "Continue the exact task. Do not",
76
+ "modify source_brief.md, measurements.csv, prompt.txt, or TASK.md.",
77
+ "Repair build_deck.py and rebuild output/deck.pptx.",
78
+ ].join("\n"),
79
+ taskProfile: "slides",
80
+ });
81
+
82
+ const pathWrappedImmutableSourceContract = deriveScsTaskContract({
83
+ goal: [
84
+ "Continue the exact task. Do not modify",
85
+ "source_brief.md, measurements.csv, prompt.txt, or TASK.md.",
86
+ "Repair build_deck.py and rebuild output/deck.pptx.",
87
+ ].join("\n"),
88
+ taskProfile: "slides",
89
+ });
90
+
73
91
  const recoveryInstructionContract = deriveScsTaskContract({
74
92
  goal: [
75
93
  "Use the retained source and these two failures: the tests invoke ../service_ctl.py, while `python3 service_ctl.py start --state-dir .runtime` fails. Preserve the lifecycle assertions rather than replacing them, repair service_ctl.py, and remove the accidental untracked resume-after-git-baseline-recovery-dev-prompt.txt.",
@@ -173,6 +191,16 @@ assert(
173
191
  ),
174
192
  "an immutable source path leaked into exact output requirements"
175
193
  );
194
+ for (const contract of [
195
+ actionWrappedImmutableSourceContract,
196
+ pathWrappedImmutableSourceContract,
197
+ ]) {
198
+ assert.deepEqual(
199
+ contract.excludedOutputPaths.sort(),
200
+ ["TASK.md", "measurements.csv", "prompt.txt", "source_brief.md"].sort(),
201
+ "a negative action or its governed path list lost protection across a line wrap"
202
+ );
203
+ }
176
204
  assert(
177
205
  recoveryInstructionContract.excludedOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt") &&
178
206
  !recoveryInstructionContract.exactOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt"),
@@ -4085,6 +4085,7 @@ async function applyContinuationPrompt(state, config, observers) {
4085
4085
  packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
4086
4086
  content: retainedTestEvidence.content,
4087
4087
  paths: retainedTestEvidence.paths,
4088
+ repairPaths: retainedTestEvidence.repairPaths,
4088
4089
  mutationRevision: Number(currentFailure?.mutationRevision || 0),
4089
4090
  failureSignature: String(currentFailure?.failureSignature || ""),
4090
4091
  command: String(currentFailure?.command || ""),
@@ -6624,6 +6625,64 @@ function safeRecoveryEvidencePath(value = "") {
6624
6625
  return PLAIN_TEXT_FILE_EXTENSIONS.has(path.extname(candidate).toLowerCase()) ? candidate : "";
6625
6626
  }
6626
6627
 
6628
+ function failedTestMutationRepairPaths(
6629
+ config = {},
6630
+ state = {},
6631
+ testRun = {},
6632
+ excludedPaths = []
6633
+ ) {
6634
+ const verification = state.meta?.projectVerification || {};
6635
+ const history = Array.isArray(verification.mutationHistory)
6636
+ ? verification.mutationHistory
6637
+ : verification.lastMutation
6638
+ ? [verification.lastMutation]
6639
+ : [];
6640
+ const maximumRevision = Math.max(
6641
+ 0,
6642
+ Number(testRun?.mutationRevision ?? verification.mutationRevision ?? 0)
6643
+ );
6644
+ const taskGoal = String(
6645
+ state.meta?.goalContract?.taskGoal || state.goal || config.goal || ""
6646
+ ).trim();
6647
+ const activeTaskHash = taskGoal ? hashForLog(taskGoal) : "";
6648
+ const repairPaths = [];
6649
+ for (const mutation of [...history].reverse()) {
6650
+ if (
6651
+ Number(mutation?.revision || 0) > maximumRevision ||
6652
+ !["apply_patch", "write_file"].includes(String(mutation?.toolName || "")) ||
6653
+ (activeTaskHash && mutation?.taskHash && mutation.taskHash !== activeTaskHash)
6654
+ ) {
6655
+ continue;
6656
+ }
6657
+ for (const candidate of Array.isArray(mutation?.paths) ? mutation.paths : []) {
6658
+ const safePath = safeRecoveryEvidencePath(candidate);
6659
+ if (
6660
+ !safePath ||
6661
+ pathLooksLikeTestSource(safePath) ||
6662
+ isPrivateVerificationEvidencePath(safePath) ||
6663
+ filterExplicitlyExcludedOutputPaths([safePath], excludedPaths).length === 0 ||
6664
+ repairPaths.includes(safePath)
6665
+ ) {
6666
+ continue;
6667
+ }
6668
+ repairPaths.push(safePath);
6669
+ if (repairPaths.length >= 6) return repairPaths;
6670
+ }
6671
+ }
6672
+ return repairPaths;
6673
+ }
6674
+
6675
+ function failedTestCanonicalRepairPaths(state = {}) {
6676
+ const packet = state.meta?.failedTestRecoveryPacket || {};
6677
+ const preferred = Array.isArray(packet.repairPaths) && packet.repairPaths.length
6678
+ ? packet.repairPaths
6679
+ : packet.paths;
6680
+ return (Array.isArray(preferred) ? preferred : [])
6681
+ .map(safeRecoveryEvidencePath)
6682
+ .filter(Boolean)
6683
+ .filter((item, index, items) => items.indexOf(item) === index);
6684
+ }
6685
+
6627
6686
  function recoveryEvidenceDependencies(sourcePath = "", content = "") {
6628
6687
  const dependencies = [];
6629
6688
  const append = (candidate) => {
@@ -6984,8 +7043,17 @@ export async function buildFailedTestRecoveryPacket(config = {}, state = {}) {
6984
7043
  ]
6985
7044
  .map(safeRecoveryEvidencePath)
6986
7045
  .filter(Boolean);
7046
+ const mutationRepairPaths = failedTestMutationRepairPaths(
7047
+ config,
7048
+ state,
7049
+ testRun,
7050
+ taskContract.excludedOutputPaths || []
7051
+ );
6987
7052
  const mutationEvidencePaths = new Set(
6988
- (Array.isArray(verification.lastMutation?.paths) ? verification.lastMutation.paths : [])
7053
+ [
7054
+ ...mutationRepairPaths,
7055
+ ...(Array.isArray(verification.lastMutation?.paths) ? verification.lastMutation.paths : []),
7056
+ ]
6989
7057
  .map(safeRecoveryEvidencePath)
6990
7058
  .filter(Boolean)
6991
7059
  );
@@ -7476,8 +7544,33 @@ export async function buildFailedTestRecoveryPacket(config = {}, state = {}) {
7476
7544
  at: new Date().toISOString(),
7477
7545
  focuses: diagnosticFocuses,
7478
7546
  };
7547
+ const evidencePaths = [...seen].filter((item) =>
7548
+ excerpts.some((excerpt) => excerpt.startsWith(`### ${item}\n`))
7549
+ );
7550
+ const diagnosticRepairPaths = diagnosticFocuses
7551
+ .map((focus) => safeRecoveryEvidencePath(focus?.path))
7552
+ .filter(Boolean);
7553
+ const preferredRepairPaths = [
7554
+ ...diagnosticRepairPaths,
7555
+ ...mutationRepairPaths,
7556
+ ]
7557
+ .filter((item, index, items) => items.indexOf(item) === index)
7558
+ .filter((item) => evidencePaths.includes(item));
7559
+ const fallbackRepairPaths = evidencePaths
7560
+ .filter((item) => !pathLooksLikeTestSource(item))
7561
+ .filter(
7562
+ (item) =>
7563
+ filterExplicitlyExcludedOutputPaths(
7564
+ [item],
7565
+ taskContract.excludedOutputPaths || []
7566
+ ).length > 0
7567
+ );
7479
7568
  return {
7480
- paths: [...seen].filter((item) => excerpts.some((excerpt) => excerpt.startsWith(`### ${item}\n`))),
7569
+ paths: evidencePaths,
7570
+ repairPaths: (preferredRepairPaths.length
7571
+ ? preferredRepairPaths
7572
+ : fallbackRepairPaths
7573
+ ).slice(0, 6),
7481
7574
  content: [
7482
7575
  `Bounded failed-test evidence packet v${FAILED_TEST_RECOVERY_PACKET_VERSION}. These are exact current workspace excerpts selected from the discovered test and its local dependencies. Use them to calculate the producing transformation; do not restart broad discovery.`,
7483
7576
  testRun.command ? `Verification command: ${testRun.command}` : "",
@@ -7841,6 +7934,23 @@ function noProgressOutcomeFingerprint(toolResult = {}) {
7841
7934
 
7842
7935
  export function repeatedNoProgressToolBlock(state, toolName, args = {}, config = {}) {
7843
7936
  if (toolName !== "run_command" || expectedRepeatedObservationCommand(args.command)) return null;
7937
+ const requestedCommand = projectTestCommandKey(
7938
+ normalizeLeadingWorkspaceCd(args.command, config)
7939
+ );
7940
+ const pendingProducerCommand = projectTestCommandKey(
7941
+ normalizeLeadingWorkspaceCd(config.generatedArtifactProducerCommand, config)
7942
+ );
7943
+ if (
7944
+ config.generatedArtifactProducerPending === true &&
7945
+ requestedCommand &&
7946
+ requestedCommand === pendingProducerCommand
7947
+ ) {
7948
+ // A persisted session can contain no-progress history from a runtime that
7949
+ // did not yet credit generated-artifact rebuilds as mutations. The current
7950
+ // exact producer contract is authoritative and gets one executable route;
7951
+ // unrelated repeated probes remain guarded below.
7952
+ return null;
7953
+ }
7844
7954
  const toolLoop = state.meta?.toolLoop || {};
7845
7955
  const signature = staticToolCallSignature(toolName, args || {}, {
7846
7956
  commandCwd: config.commandCwd,
@@ -11659,9 +11769,7 @@ export function nextStepRuntimeConfig(config = {}, state = {}) {
11659
11769
  );
11660
11770
  });
11661
11771
  const recoveryPacketPaths = currentRecoveryPacket
11662
- ? (Array.isArray(state.meta?.failedTestRecoveryPacket?.paths)
11663
- ? state.meta.failedTestRecoveryPacket.paths
11664
- : [])
11772
+ ? failedTestCanonicalRepairPaths(state)
11665
11773
  .map(safeRecoveryEvidencePath)
11666
11774
  .filter(Boolean)
11667
11775
  .filter((item, index, items) => items.indexOf(item) === index)
@@ -13403,9 +13511,7 @@ function requiredDeclarationIdentitiesForPatch(state = {}, targetPath = "") {
13403
13511
  }
13404
13512
 
13405
13513
  function requiredSymbolRepairPath(state = {}, owner = "") {
13406
- const sourcePaths = (state.meta?.failedTestRecoveryPacket?.paths || [])
13407
- .map((item) => safeRecoveryEvidencePath(item))
13408
- .filter(Boolean)
13514
+ const sourcePaths = failedTestCanonicalRepairPaths(state)
13409
13515
  .filter((item) => !/(?:^|\/)tests?(?:\/|$)/i.test(item));
13410
13516
  const ownerBasename = String(owner || "")
13411
13517
  .split(".")
@@ -16525,7 +16631,7 @@ async function recordToolContractViolation({
16525
16631
  const completedRequestedPaths = requestedCalls
16526
16632
  .map((call) => call.path)
16527
16633
  .filter((item) => item && completedArtifacts.has(item));
16528
- const repairPaths = (state.meta?.failedTestRecoveryPacket?.paths || [])
16634
+ const repairPaths = failedTestCanonicalRepairPaths(state)
16529
16635
  .map((item) => String(item || "").replace(/\\/g, "/"))
16530
16636
  .filter((item) => item && !/(?:^|\/)tests?(?:\/|$)/i.test(item))
16531
16637
  .slice(0, 6);
@@ -17406,9 +17512,7 @@ export function recoverUnavailableVerificationRerunAsCanonicalRead(
17406
17512
  ...(Array.isArray(config.testFailureRepairPatchTargets)
17407
17513
  ? config.testFailureRepairPatchTargets.map((target) => target?.path)
17408
17514
  : []),
17409
- ...(Array.isArray(state.meta?.failedTestRecoveryPacket?.paths)
17410
- ? state.meta.failedTestRecoveryPacket.paths
17411
- : []),
17515
+ ...failedTestCanonicalRepairPaths(state),
17412
17516
  ]
17413
17517
  .map(safeRecoveryEvidencePath)
17414
17518
  .filter(Boolean)
@@ -19193,6 +19297,7 @@ async function runAgentOnceUnlocked(config) {
19193
19297
  packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
19194
19298
  content: recoveryEvidence.content,
19195
19299
  paths: recoveryEvidence.paths,
19300
+ repairPaths: recoveryEvidence.repairPaths,
19196
19301
  mutationRevision: Number(currentFailure.mutationRevision || 0),
19197
19302
  failureSignature: String(currentFailure.failureSignature || ""),
19198
19303
  command: String(currentFailure.command || ""),
@@ -20471,6 +20576,7 @@ async function runAgentOnceUnlocked(config) {
20471
20576
  packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
20472
20577
  content: recoveryEvidence.content,
20473
20578
  paths: recoveryEvidence.paths,
20579
+ repairPaths: recoveryEvidence.repairPaths,
20474
20580
  mutationRevision: Number(currentFailure.mutationRevision || 0),
20475
20581
  failureSignature: String(currentFailure.failureSignature || ""),
20476
20582
  command: String(currentFailure.command || ""),
@@ -1938,7 +1938,10 @@ export function selectProgressiveTools(
1938
1938
  }
1939
1939
 
1940
1940
  if (config.generatedArtifactProducerPending === true) {
1941
- const available = new Map(enabled.map(({ name, tool }) => [name, tool]));
1941
+ // An authoritative producer phase supersedes a stale convergence marker.
1942
+ // Keep explicit capability disables effective by selecting from the real
1943
+ // enabled baseline rather than from the convergence-pruned surface.
1944
+ const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
1942
1945
  const producerCommand = constrainRunCommand(
1943
1946
  available.get("run_command"),
1944
1947
  config.generatedArtifactProducerCommand,
@@ -1954,8 +1957,11 @@ export function selectProgressiveTools(
1954
1957
  typeof config.testFailureStalemateCommand === "string" &&
1955
1958
  config.testFailureStalemateCommand.trim()
1956
1959
  ) {
1960
+ const mandatoryAvailable = new Map(
1961
+ baselineEnabled.map(({ name, tool }) => [name, tool])
1962
+ );
1957
1963
  const verificationCommand = constrainRunCommand(
1958
- available.get("run_command"),
1964
+ mandatoryAvailable.get("run_command"),
1959
1965
  config.testFailureStalemateCommand,
1960
1966
  "Run this exact retained failing verifier once to refresh stale evidence after repeated semantic repair rejections. This is a bounded stalemate escape hatch, not permission to rerun arbitrary commands or loop unchanged tests."
1961
1967
  );
@@ -2053,7 +2059,7 @@ export function selectProgressiveTools(
2053
2059
  }
2054
2060
 
2055
2061
  if (config.requiredProjectCommandPending === true) {
2056
- const available = new Map(enabled.map(({ name, tool }) => [name, tool]));
2062
+ const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
2057
2063
  const requiredCommand = constrainRunCommand(
2058
2064
  available.get("run_command"),
2059
2065
  config.requiredProjectCommand,
@@ -2063,7 +2069,7 @@ export function selectProgressiveTools(
2063
2069
  }
2064
2070
 
2065
2071
  if (config.testVerificationPending === true) {
2066
- const available = new Map(enabled.map(({ name, tool }) => [name, tool]));
2072
+ const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
2067
2073
  const verificationCommand = constrainRunCommand(
2068
2074
  available.get("run_command"),
2069
2075
  config.testVerificationCommand,
@@ -542,12 +542,26 @@ export function filterExplicitlyExcludedOutputPaths(paths = [], exclusions = [])
542
542
  }
543
543
 
544
544
  export function inferExplicitlyExcludedOutputPaths(goal = "") {
545
+ const extensionPattern = "md|txt|json|jsonl|ndjson|ya?ml|html|css|js|ts|tsx|jsx|py|sh|csv|tex|svg|png|jpe?g|webp|mp4|mov|pdf|docx";
545
546
  // Preserve coordinated path lists that wrap after a comma. Prompt and task
546
547
  // files commonly format "do not modify a, b,\nc, or d" across lines; splitting
547
548
  // that text first drops the governing negative action from the continuation.
548
- const source = String(goal || "").replace(/([,,、])\s*\r?\n\s*/gu, "$1 ");
549
+ const negativePrefix = "(?:do\\s+not|don't|dont|must\\s+not|should\\s+not|never)";
550
+ const negativeAction = "(?:run|rerun|re-run|execut(?:e|ed|ing)|creat(?:e|ed|ing)|recreat(?:e|ed|ing)|writ(?:e|ten|ing)|generat(?:e|ed|ing)|sav(?:e|ed|ing)|output|touch|modif(?:y|ied|ying)|edit(?:ed|ing)?|stage|commit)";
551
+ const wrappedNegativeAction = new RegExp(
552
+ `(\\b${negativePrefix}\\b)\\s*\\r?\\n\\s*(?=${negativeAction}\\b)`,
553
+ "giu"
554
+ );
555
+ const wrappedNegativePath = new RegExp(
556
+ `(\\b${negativePrefix}\\b[^.!?。!?;;\\n]{0,180}\\b${negativeAction}\\b)\\s*\\r?\\n\\s*` +
557
+ `(?=\\S{1,260}\\.(?:${extensionPattern})\\b)`,
558
+ "giu"
559
+ );
560
+ const source = String(goal || "")
561
+ .replace(/([,,、])\s*\r?\n\s*/gu, "$1 ")
562
+ .replace(wrappedNegativeAction, "$1 ")
563
+ .replace(wrappedNegativePath, "$1 ");
549
564
  if (!source.trim()) return [];
550
- const extensionPattern = "md|txt|json|jsonl|ndjson|ya?ml|html|css|js|ts|tsx|jsx|py|sh|csv|tex|svg|png|jpe?g|webp|mp4|mov|pdf|docx";
551
565
  const pathPattern = new RegExp(
552
566
  '((?:~|\\.{1,2}|/|[A-Za-z0-9_\\-\\u4e00-\\u9fff])[\\w./~\\-\\u4e00-\\u9fff]{0,260}\\.(?:' +
553
567
  extensionPattern +