gsd-pi 2.82.0-dev.3709f22a5 → 2.82.0-dev.4285182e8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +2 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
  4. package/dist/resources/extensions/gsd/auto/loop.js +14 -1
  5. package/dist/resources/extensions/gsd/auto/phases.js +53 -29
  6. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  7. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  8. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -19
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +13 -6
  11. package/dist/resources/extensions/gsd/auto-recovery.js +40 -13
  12. package/dist/resources/extensions/gsd/auto-start.js +3 -3
  13. package/dist/resources/extensions/gsd/auto-verification.js +17 -4
  14. package/dist/resources/extensions/gsd/auto-worktree.js +65 -9
  15. package/dist/resources/extensions/gsd/auto.js +14 -8
  16. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +6 -1
  17. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +1 -1
  18. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  19. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  20. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  21. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  22. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
  23. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  24. package/dist/resources/extensions/gsd/crash-recovery.js +16 -4
  25. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  26. package/dist/resources/extensions/gsd/forensics.js +3 -3
  27. package/dist/resources/extensions/gsd/git-service.js +6 -2
  28. package/dist/resources/extensions/gsd/gsd-db.js +20 -6
  29. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  30. package/dist/resources/extensions/gsd/guided-flow.js +8 -5
  31. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
  32. package/dist/resources/extensions/gsd/paths.js +4 -0
  33. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  34. package/dist/resources/extensions/gsd/state.js +3 -3
  35. package/dist/resources/extensions/gsd/status-guards.js +7 -0
  36. package/dist/resources/extensions/gsd/templates/plan.md +1 -0
  37. package/dist/resources/extensions/gsd/templates/task-plan.md +6 -0
  38. package/dist/resources/extensions/gsd/tools/plan-slice.js +3 -5
  39. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  40. package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
  41. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  42. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  43. package/dist/web/standalone/.next/BUILD_ID +1 -1
  44. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  45. package/dist/web/standalone/.next/build-manifest.json +3 -3
  46. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  47. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  48. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/index.html +1 -1
  66. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  73. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  76. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  77. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  78. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  79. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  80. package/dist/web/standalone/.next/static/chunks/{webpack-9a4db269f9ed63ad.js → webpack-855d616060cb6e59.js} +1 -1
  81. package/package.json +1 -1
  82. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  83. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  84. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  85. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  86. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  87. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  88. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  89. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  90. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  91. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  92. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  93. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  95. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  97. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  98. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  100. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  101. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  103. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  104. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  105. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  106. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  107. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  108. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  109. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  110. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  111. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  112. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  113. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  114. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  115. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  116. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  117. package/packages/pi-tui/dist/terminal.js +12 -0
  118. package/packages/pi-tui/dist/terminal.js.map +1 -1
  119. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  120. package/packages/pi-tui/src/terminal.ts +11 -0
  121. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  122. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
  123. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
  124. package/src/resources/extensions/gsd/auto/loop.ts +14 -1
  125. package/src/resources/extensions/gsd/auto/phases.ts +60 -36
  126. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  127. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  128. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  129. package/src/resources/extensions/gsd/auto-dispatch.ts +13 -19
  130. package/src/resources/extensions/gsd/auto-post-unit.ts +14 -6
  131. package/src/resources/extensions/gsd/auto-recovery.ts +45 -11
  132. package/src/resources/extensions/gsd/auto-start.ts +2 -3
  133. package/src/resources/extensions/gsd/auto-verification.ts +22 -2
  134. package/src/resources/extensions/gsd/auto-worktree.ts +74 -9
  135. package/src/resources/extensions/gsd/auto.ts +13 -8
  136. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
  137. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +1 -1
  138. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  139. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  140. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  141. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  142. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
  143. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  144. package/src/resources/extensions/gsd/crash-recovery.ts +16 -2
  145. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  146. package/src/resources/extensions/gsd/forensics.ts +3 -3
  147. package/src/resources/extensions/gsd/git-service.ts +6 -3
  148. package/src/resources/extensions/gsd/gsd-db.ts +18 -6
  149. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  150. package/src/resources/extensions/gsd/guided-flow.ts +8 -5
  151. package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
  152. package/src/resources/extensions/gsd/paths.ts +5 -0
  153. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  154. package/src/resources/extensions/gsd/state.ts +3 -3
  155. package/src/resources/extensions/gsd/status-guards.ts +8 -0
  156. package/src/resources/extensions/gsd/templates/plan.md +1 -0
  157. package/src/resources/extensions/gsd/templates/task-plan.md +6 -0
  158. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +2 -0
  159. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +139 -1
  160. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +6 -5
  161. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +76 -5
  162. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  163. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  164. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -0
  165. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  166. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +27 -0
  167. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
  168. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  169. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +9 -0
  170. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
  171. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  172. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  173. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +26 -1
  174. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  175. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
  176. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  177. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  178. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  179. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +43 -0
  180. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  181. package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
  182. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +17 -0
  183. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  184. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  185. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +18 -0
  186. package/src/resources/extensions/gsd/tools/plan-slice.ts +3 -4
  187. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  188. package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
  189. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  190. package/dist/web/standalone/.next/static/chunks/8359.7eb3bb8f8ecf4c01.js +0 -10
  191. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  192. /package/dist/web/standalone/.next/static/{kkGf3_VaPFkiDNV_D7Dtl → 78uanrILNOKG-Jpi4itAE}/_buildManifest.js +0 -0
  193. /package/dist/web/standalone/.next/static/{kkGf3_VaPFkiDNV_D7Dtl → 78uanrILNOKG-Jpi4itAE}/_ssgManifest.js +0 -0
@@ -165,6 +165,13 @@ test("decideFinalizeResult maps break results to stop decisions", () => {
165
165
  );
166
166
  });
167
167
 
168
+ test("decideFinalizeResult maps step-wizard breaks to completed step exits", () => {
169
+ assert.deepEqual(
170
+ decideFinalizeResult({ action: "break", reason: "step-wizard" }),
171
+ { action: "complete-and-break" },
172
+ );
173
+ });
174
+
168
175
  test("decideFinalizeResult maps continue and next results", () => {
169
176
  assert.deepEqual(
170
177
  decideFinalizeResult({ action: "continue" }),
@@ -746,3 +746,21 @@ test("transport compatibility still blocks units whose MCP tools are not exposed
746
746
  assert.match(error ?? "", /requires secure_env_collect/);
747
747
  assert.match(error ?? "", /currently exposes only/);
748
748
  });
749
+
750
+ test("transport compatibility accepts MCP-namespaced runtime tools", () => {
751
+ const error = getWorkflowTransportSupportError(
752
+ "claude-code",
753
+ ["gsd_summary_save"],
754
+ {
755
+ projectRoot: "/tmp/project",
756
+ env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
757
+ surface: "auto-mode",
758
+ unitType: "research-slice",
759
+ authMode: "externalCli",
760
+ baseUrl: "local://claude-code",
761
+ activeTools: ["mcp__gsd-workflow__gsd_summary_save"],
762
+ },
763
+ );
764
+
765
+ assert.equal(error, null);
766
+ });
@@ -27,7 +27,7 @@ import { logWarning } from "../workflow-logger.js";
27
27
  import { validatePlanningPathScope } from "../planning-path-scope.js";
28
28
  import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
29
29
  import type { TaskRow } from "../db-task-slice-rows.js";
30
- import { buildTaskFileName, gsdRoot, resolveTasksDir } from "../paths.js";
30
+ import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
31
31
 
32
32
  export interface PlanSliceTaskInput {
33
33
  taskId: string;
@@ -314,12 +314,11 @@ export async function handlePlanSlice(
314
314
  }
315
315
 
316
316
  try {
317
- const tasksDir = resolveTasksDir(basePath, params.milestoneId, params.sliceId);
317
+ const tasksDir = join(gsdProjectionRoot(basePath), "milestones", params.milestoneId, "slices", params.sliceId, "tasks");
318
318
  for (const taskId of omittedTaskIds) {
319
- if (!tasksDir) continue;
320
319
  const taskPlanPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
321
320
  if (existsSync(taskPlanPath)) rmSync(taskPlanPath, { force: true });
322
- const artifactPath = relative(gsdRoot(basePath), taskPlanPath).replace(/\\/g, "/");
321
+ const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
323
322
  deleteArtifactByPath(artifactPath);
324
323
  }
325
324
 
@@ -18,6 +18,7 @@ export interface WorkflowCapabilityOptions {
18
18
  unitType?: string;
19
19
  authMode?: "apiKey" | "oauth" | "externalCli" | "none";
20
20
  baseUrl?: string;
21
+ activeTools?: string[];
21
22
  }
22
23
 
23
24
  const MCP_WORKFLOW_TOOL_SURFACE = new Set([
@@ -383,6 +384,15 @@ function hasAskUserQuestionsTool(activeTools: string[]): boolean {
383
384
  });
384
385
  }
385
386
 
387
+ function hasRequiredTool(requiredTool: string, activeTools: string[]): boolean {
388
+ return activeTools.some((toolName) => {
389
+ if (toolName === requiredTool) return true;
390
+ if (!toolName.startsWith("mcp__")) return false;
391
+ const toolSeparator = toolName.indexOf("__", "mcp__".length);
392
+ return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
393
+ });
394
+ }
395
+
386
396
  function workflowMcpStructuredQuestionsOptIn(env: NodeJS.ProcessEnv = process.env): boolean {
387
397
  const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
388
398
  return value === "1" || value === "true";
@@ -423,8 +433,15 @@ export function getWorkflowTransportSupportError(
423
433
  return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: the GSD workflow MCP server is not configured or discoverable. Detected Claude Code model but no workflow MCP. Please run /gsd mcp init . from your project root. You can also configure GSD_WORKFLOW_MCP_COMMAND, build packages/mcp-server/dist/cli.js, or install gsd-mcp-server on PATH.`;
424
434
  }
425
435
 
426
- const missing = [...new Set(requiredTools)].filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
436
+ const uniqueRequired = [...new Set(requiredTools)];
437
+ const missing = (options.activeTools && options.activeTools.length > 0)
438
+ ? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
439
+ : uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
427
440
  if (missing.length === 0) return null;
428
441
 
442
+ if (options.activeTools && options.activeTools.length > 0) {
443
+ return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
444
+ }
445
+
429
446
  return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${Array.from(MCP_WORKFLOW_TOOL_SURFACE).sort().join(", ")}.`;
430
447
  }
@@ -618,7 +618,7 @@ export function removeWorktree(
618
618
  try {
619
619
  rmSync(nestedGitPath, { recursive: true, force: true });
620
620
  logWarning("reconcile",
621
- `Removed nested .git directory from scaffolded project to prevent data loss (#2616)`,
621
+ `Removed nested .git directory from scaffolded project to prevent data loss`,
622
622
  { worktree: name, nestedRepo: nestedDir },
623
623
  );
624
624
  } catch {
@@ -109,6 +109,7 @@ const MAX_BUFFER_BYTES = 512 * 1024;
109
109
  * Prevents CPU spinning when deltas arrive faster than regex evaluation (#468).
110
110
  */
111
111
  const JS_FALLBACK_CHECK_INTERVAL_MS = 50;
112
+ const JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES = 4 * 1024;
112
113
 
113
114
  const DEFAULT_SCOPE: TtsrScope = {
114
115
  allowText: true,
@@ -383,7 +384,10 @@ export class TtsrManager {
383
384
  // streams — regex on a growing buffer is O(rules × buffer_size) (#468).
384
385
  const now = Date.now();
385
386
  const lastCheck = this.#lastJsCheckAt.get(bufferKey) ?? 0;
386
- if (now - lastCheck < JS_FALLBACK_CHECK_INTERVAL_MS) {
387
+ if (
388
+ nextBuffer.length >= JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES &&
389
+ now - lastCheck < JS_FALLBACK_CHECK_INTERVAL_MS
390
+ ) {
387
391
  stopTimer({ bufferSize: nextBuffer.length, throttled: true });
388
392
  return [];
389
393
  }