Skip to content

Patch Release 0.25.1#1152

Merged
Crunchyman-ralph merged 3 commits intomainfrom
next
Aug 22, 2025
Merged

Patch Release 0.25.1#1152
Crunchyman-ralph merged 3 commits intomainfrom
next

Conversation

@Crunchyman-ralph
Copy link
Collaborator

@Crunchyman-ralph Crunchyman-ralph commented Aug 22, 2025

What type of PR is this?

  • 🐛 Bug fix
  • ✨ Feature
  • 🔌 Integration
  • 📝 Docs
  • 🧹 Refactor
  • Other:

Description

Related Issues

How to Test This

# Example commands or steps

Expected result:

Contributor Checklist

  • Created changeset: npm run changeset
  • Tests pass: npm test
  • Format check passes: npm run format-check (or npm run format to fix)
  • Addressed CodeRabbit comments (if any)
  • Linked related issues (if any)
  • Manually tested the changes

Changelog Entry


For Maintainers

  • PR title follows conventional commits
  • Target branch correct
  • Labels added
  • Milestone assigned (if applicable)

Summary by CodeRabbit

  • Bug Fixes
    • Prevents crashes/hangs when an optional SDK isn’t installed and improves cancellation error handling.
  • Changes
    • Temporarily disables streaming for compatibility; non‑streaming is used across affected flows.
  • Documentation
    • Updates attribution wording in command documentation.
  • Style
    • Cleans up JSON formatting in extension and workspace configuration (no behavior changes).
  • Chores
    • Bumps an optional SDK dependency version.
    • Adds patch-release changeset entries and metadata.

Crunchyman-ralph and others added 3 commits August 22, 2025 17:01
…ject" when SDK missing; improve CLI stability (#1146)

* fix: handle missing @anthropic-ai/claude-code SDK gracefully

Add defensive checks to prevent "Right-hand side of 'instanceof' is not an object" errors when the optional Claude Code SDK is not installed.

Changes:
- Check if AbortError exists before using instanceof
- Check if query function exists before calling it
- Provide clear error messages when SDK is missing

This fixes the issue reported by users in v0.24.0 and v0.25.0 where Task Master would crash with instanceof errors when using the claude-code provider without the SDK installed.

* chore: bump @anthropic-ai/claude-code to ^1.0.88 and regenerate lockfile
* fix: temporarily disable streaming
@changeset-bot
Copy link

changeset-bot bot commented Aug 22, 2025

🦋 Changeset detected

Latest commit: db720a9

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 22, 2025

Walkthrough

Disables streaming in PRD parsing via a feature flag and updates tests accordingly. Adds runtime guards and safer AbortError handling in the Claude Code language model. Updates optional dependency version and formats JSON files. Adds changeset entries and updates a documentation attribution line.

Changes

Cohort / File(s) Summary
Changesets metadata
\.changeset/quiet-owls-fix-cli-sdk.md, \.changeset/rich-emus-say.md
Add patch changelog entries: CLI SDK guard/AbortError handling; note temporary streaming disablement. No API changes.
SDK guards and AbortError checks
src/ai-providers/custom-sdk/claude-code/language-model.js
Add SDK presence checks before query calls; guard AbortError instanceof checks across generate/stream paths. No signature changes.
Streaming disabled in PRD parsing
scripts/modules/task-manager/parse-prd/parse-prd-config.js, tests/unit/scripts/modules/task-manager/parse-prd.test.js
Introduce ENABLE_STREAMING=false gate; require it for streaming; shift tests to non-streaming expectations; skip previous streaming-fallback test.
Package management updates
package.json, apps/extension/package.json
Bump optional @anthropic-ai/claude-code to ^1.0.88; reformat workspaces to single line. Extension package JSON arrays reformatted only.
Docs attribution tweak
\.claude/commands/dedupe.md
Replace attribution line with a non-linked literal reference to Task Master Bot.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI/Caller as Caller
  participant Config as PrdParseConfig
  participant Parser as Parse PRD Service
  participant Gen as generateObjectService
  participant Stream as streamObjectService

  User->>CLI/Caller: parse PRD
  CLI/Caller->>Config: new PrdParseConfig(...)
  Note right of Config: ENABLE_STREAMING=false<br/>(temporary gate)
  Config-->>CLI/Caller: useStreaming=false
  CLI/Caller->>Parser: parse(input, useStreaming=false)
  alt useStreaming=false
    Parser->>Gen: generateObject(...)
    Gen-->>Parser: result
  else useStreaming=true
    Parser->>Stream: streamObject(...)
    Stream-->>Parser: stream events
  end
  Parser-->>CLI/Caller: parsed result
  CLI/Caller-->>User: output
Loading
sequenceDiagram
  autonumber
  participant Caller
  participant LM as ClaudeCodeLanguageModel
  participant SDK as Claude Code SDK (query)

  Caller->>LM: doGenerate(request)
  LM->>LM: if (!query) throw Error("SDK not loaded")
  LM->>SDK: query(request)
  SDK-->>LM: response
  LM-->>Caller: result

  rect rgba(255,235,205,0.3)
  note right of LM: Error handling (guarded)
  Caller->>LM: doGenerate(...) / doStream(...)
  LM->>LM: try { ... } catch (e) {<br/>if (AbortError && e instanceof AbortError) handleAbort()<br/>else throw e }
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • eyaltoledano

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch next

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
src/ai-providers/custom-sdk/claude-code/language-model.js (1)

440-486: Bug: ‘error’ is referenced outside a catch block in streaming path (unbound identifier).

Within doStream() you attempt JSON-truncation recovery using error inside the try body, but error is not defined there. This will throw a ReferenceError and bypass the intended recovery path.

Fix by moving the truncation handling into the catch (error) block and hoisting usage/accumulatedText so they’re visible in the catch:

@@
-          let usage = { promptTokens: 0, completionTokens: 0 };
-          let accumulatedText = '';
+          // Hoist so they are visible to the catch block
+          let usage = { promptTokens: 0, completionTokens: 0 };
+          let accumulatedText = '';
@@
-          // -------------------------------------------------------------
-          // Work-around for Claude-Code CLI/SDK JSON truncation bug (#913)
-          // -------------------------------------------------------------
-          // If we hit the SDK JSON SyntaxError but have buffered text, finalize
-          // the stream gracefully instead of emitting an error.
-          const isJsonTruncation =
-            error instanceof SyntaxError &&
-            /JSON/i.test(error.message || '') &&
-            (error.message.includes('position') ||
-              error.message.includes('Unexpected end'));
-
-          if (
-            isJsonTruncation &&
-            accumulatedText &&
-            accumulatedText.length > 0
-          ) {
-            // Prepare final text payload
-            const finalText =
-              options.mode?.type === 'object-json'
-                ? extractJson(accumulatedText)
-                : accumulatedText;
-
-            // Emit any remaining text
-            controller.enqueue({
-              type: 'text-delta',
-              textDelta: finalText
-            });
-
-            // Emit finish with truncated reason and warning
-            controller.enqueue({
-              type: 'finish',
-              finishReason: 'truncated',
-              usage,
-              providerMetadata: { 'claude-code': { truncated: true } },
-              warnings: [
-                {
-                  type: 'provider-warning',
-                  details:
-                    'Claude Code SDK JSON truncation detected; stream recovered.'
-                }
-              ]
-            });
-
-            controller.close();
-            return; // Skip normal error path
-          }
+          // Truncation handling moved to catch block
@@
-        } catch (error) {
-          let errorToEmit;
+        } catch (error) {
+          // JSON truncation recovery (mirrors doGenerate)
+          const isJsonTruncation =
+            error instanceof SyntaxError &&
+            /JSON/i.test(error.message || '') &&
+            (error.message.includes('position') ||
+              error.message.includes('Unexpected end'));
+          if (isJsonTruncation && accumulatedText && accumulatedText.length > 0) {
+            const finalText =
+              options.mode?.type === 'object-json'
+                ? extractJson(accumulatedText)
+                : accumulatedText;
+            controller.enqueue({ type: 'text-delta', textDelta: finalText });
+            controller.enqueue({
+              type: 'finish',
+              finishReason: 'truncated',
+              usage,
+              providerMetadata: { 'claude-code': { truncated: true } },
+              warnings: [
+                {
+                  type: 'provider-warning',
+                  details:
+                    'Claude Code SDK JSON truncation detected; stream recovered.'
+                }
+              ]
+            });
+            controller.close();
+            return;
+          }
+          let errorToEmit;
tests/unit/scripts/modules/task-manager/parse-prd.test.js (6)

798-839: Non-streaming with reportProgress (streaming disabled) is asserted correctly; add telemetry UI assertion.

Good pivot to non-streaming. Given guidelines require showing AI usage in CLI/text when telemetry exists, assert displayAiUsageSummary is invoked when applicable.

Apply this diff to import the UI helper and assert it:

@@
-jest.unstable_mockModule('../../../../../scripts/modules/ui.js', () => ({
+jest.unstable_mockModule('../../../../../scripts/modules/ui.js', () => ({
   getStatusWithColor: jest.fn((status) => status),
   startLoadingIndicator: jest.fn(),
   stopLoadingIndicator: jest.fn(),
   displayAiUsageSummary: jest.fn()
 }));
@@
-const { JSONParser } = await import('@streamparser/json');
+const { JSONParser } = await import('@streamparser/json');
+const { displayAiUsageSummary } = await import(
+  '../../../../../scripts/modules/ui.js'
+);
@@
-// With streaming disabled, should use generateObjectService instead
+// With streaming disabled, should use generateObjectService instead
 expect(generateObjectService).toHaveBeenCalled();
@@
-// Verify progress reporting was still called
+// Verify progress reporting was still called
 expect(mockReportProgress).toHaveBeenCalled();
+// If CLI/text path is used and telemetry is available, summarize usage
+expect(displayAiUsageSummary).toHaveBeenCalledWith({}, 'cli');

1009-1032: CLI text mode (streaming disabled) checks are good; also assert progress tracker creation.

You already note tracker components may still be used. Add an explicit assertion so regressions are caught.

@@
-// Progress tracker components may still be called for CLI mode display
-// but the actual parsing uses non-streaming
+// Tracker still created for CLI display even if parsing is non-streaming
+expect(createParsePrdTracker).toHaveBeenCalledWith(
+  expect.objectContaining({ numUnits: 3, unitName: 'task' })
+);

28-68: Normalize generateObjectService mock return shape across tests.

Return shapes vary between { tasks: [...] }, { mainResult: sample }, and { mainResult: { object } }. This obscures contract regressions and forces defensive branching. Standardize on one shape (recommended: { mainResult: { object }, telemetryData }).

Apply this diff to the initial mock and adjust individual tests to override only the payload, not the shape:

@@
-jest.unstable_mockModule(
-  '../../../../../scripts/modules/ai-services-unified.js',
-  () => ({
-    generateObjectService: jest.fn().mockResolvedValue({
-      tasks: [
-        { id: 1, title: 'Test Task 1', priority: 'high', description: 'Test description 1', status: 'pending', dependencies: [] },
-        { id: 2, title: 'Test Task 2', priority: 'medium', description: 'Test description 2', status: 'pending', dependencies: [] },
-        { id: 3, title: 'Test Task 3', priority: 'low', description: 'Test description 3', status: 'pending', dependencies: [] }
-      ]
-    }),
+jest.unstable_mockModule(
+  '../../../../../scripts/modules/ai-services-unified.js',
+  () => ({
+    generateObjectService: jest.fn().mockResolvedValue({
+      mainResult: {
+        object: {
+          tasks: [
+            { id: 1, title: 'Test Task 1', priority: 'high', description: 'Test description 1', status: 'pending', dependencies: [] },
+            { id: 2, title: 'Test Task 2', priority: 'medium', description: 'Test description 2', status: 'pending', dependencies: [] },
+            { id: 3, title: 'Test Task 3', priority: 'low', description: 'Test description 3', status: 'pending', dependencies: [] }
+          ],
+          metadata: { projectName: 'Fixture', totalTasks: 3, sourceFile: 'fixture.prd', generatedAt: '2025-01-01T00:00:00Z' }
+        }
+      },
+      telemetryData: {}
+    }),

568-593: Avoid matching exact error messages; assert on error types or patterns.

Per test guidelines, don’t lock tests to exact strings. Use regex or general properties to keep tests robust.

@@
-).rejects.toThrow('Test error in AI API call');
+).rejects.toThrow(/AI API call/i);
@@
-).rejects.toThrow('already contains');
+).rejects.toThrow(/already contains/i);
@@
-).rejects.toThrow('process.exit was called with code 1');
+).rejects.toThrow(/process\.exit was called with code \d+/);

Also applies to: 649-676, 678-693


236-251: Prefer mock-fs for FS ops to align with repo test standards.

You’re manually mocking fs; switching to mock-fs improves isolation (e.g., path joins, encodings) and aligns with guidance.

If you adopt mock-fs, ensure restoration in afterEach:

@@
-jest.unstable_mockModule('fs', () => ({
-  default: { /* ... */ },
-  readFileSync: jest.fn(),
-  existsSync: jest.fn(),
-  mkdirSync: jest.fn(),
-  writeFileSync: jest.fn()
-}));
+import mockFs from 'mock-fs';
@@
-beforeEach(() => {
+beforeEach(() => {
+  mockFs({
+    path: { 'to': { 'prd.txt': '# Sample PRD for Testing' } },
+    tasks: {}
+  });
   // existing spies/mocks...
 });
@@
-afterEach(() => {
+afterEach(() => {
+  mockFs.restore();
   jest.restoreAllMocks();
 });

471-479: Spying on console is fine; ensure restoration even on failure.

You restore spies in afterEach, good. Consider also restoring process.exit spy there to avoid bleed-over if a test throws before hitting your manual restore.

@@
- afterEach(() => {
-   // Restore all mocks after each test
-   jest.restoreAllMocks();
- });
+afterEach(() => {
+  jest.restoreAllMocks();
+  if (process.exit.mockRestore) process.exit.mockRestore();
+});
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7d56492 and db720a9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • .changeset/quiet-owls-fix-cli-sdk.md (1 hunks)
  • .changeset/rich-emus-say.md (1 hunks)
  • .claude/commands/dedupe.md (1 hunks)
  • apps/extension/package.json (3 hunks)
  • package.json (2 hunks)
  • scripts/modules/task-manager/parse-prd/parse-prd-config.js (1 hunks)
  • src/ai-providers/custom-sdk/claude-code/language-model.js (4 hunks)
  • tests/unit/scripts/modules/task-manager/parse-prd.test.js (7 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
package.json

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Files:

  • package.json
.changeset/*.md

📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)

.changeset/*.md: When running npm run changeset or npx changeset add, provide a concise summary of the changes for the CHANGELOG.md in imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.

Files:

  • .changeset/quiet-owls-fix-cli-sdk.md
  • .changeset/rich-emus-say.md
.changeset/*

📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)

Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.

Files:

  • .changeset/quiet-owls-fix-cli-sdk.md
  • .changeset/rich-emus-say.md
scripts/modules/**

📄 CodeRabbit inference engine (.cursor/rules/dev_workflow.mdc)

When using the MCP server, restart it if core logic in scripts/modules or MCP tool/direct function definitions change.

Files:

  • scripts/modules/task-manager/parse-prd/parse-prd-config.js
scripts/modules/task-manager/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/telemetry.mdc)

scripts/modules/task-manager/**/*.js: Functions in scripts/modules/task-manager/ that invoke AI services must call the appropriate AI service function (e.g., generateObjectService), passing commandName and outputType in the params object.
Core logic functions in scripts/modules/task-manager/ must return an object that includes aiServiceResponse.telemetryData.
If the core logic function handles CLI output (outputFormat === 'text' or 'cli'), and aiServiceResponse.telemetryData is available, it must call displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli') from scripts/modules/ui.js.

Do not call AI-specific getters (like getMainModelId, getMainMaxTokens) from core logic functions in scripts/modules/task-manager/*; instead, pass the role to the unified AI service.

Files:

  • scripts/modules/task-manager/parse-prd/parse-prd-config.js
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • scripts/modules/task-manager/parse-prd/parse-prd-config.js
  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
  • src/ai-providers/custom-sdk/claude-code/language-model.js
tests/{unit,integration,e2e,fixtures}/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)

Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/git_workflow.mdc)

**/*.{test,spec}.{js,ts,jsx,tsx}: Create a test file and ensure all tests pass when all subtasks are complete; commit tests if added or modified
When all subtasks are complete, run final testing using the appropriate test runner (e.g., npm test, jest, or manual testing)

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.test.js: Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Always mock tests properly based on the way the tested functions are defined and used.
Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.
Use fixtures from tests/fixtures/ for consistent sample data across tests.
Always declare mocks before importing the modules being tested in Jest test files.
Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.
When testing functions with callbacks, get the callback from your mock's call arguments, execute it directly with test inputs, and verify the results.
For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.
Reset mock functions (mockFn.mockReset()) before dynamic imports if they might have been called previously.
When verifying console assertions, assert against the actual arguments passed (single formatted string), not multiple arguments.
Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Set mock environment variables in test setup and restore them after each test.
Maintain test fixtures separate from test logic.
Follow the mock-first-then-import pattern for all Jest mocks.
Do not define mock variables before jest.mock() calls (they won't be accessible due to hoisting).
Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Mock readJSON and writeJSON to avoid real file system interactions in tests.
Verify file operations use the correct paths in expect statements.
Use different file paths for each test to avoid test interdependence.
Verify modifications on the in-memory task objects passed to w...

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
tests/unit/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/unit/**/*.test.js: Unit tests must be located in tests/unit/, test individual functions and utilities in isolation, mock all external dependencies, and keep tests small, focused, and fast.
Do not include actual command execution in unit tests.

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
tests/{unit,integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/{unit,integration,e2e}/**/*.test.js: When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.
When mocking the Commander.js chain, mock ALL chainable methods (option, argument, action, on, etc.) and return this (or the mock object) from all chainable method mocks.
Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.
Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.
Mock the action handlers for CLI commands and verify they're called with correct arguments.
Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
**/*.{test,spec}.*

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Test files should follow naming conventions: .test., .spec., or _test. depending on the language

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
tests/{unit,integration,e2e}/**

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible

Files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
🧠 Learnings (27)
📓 Common learnings
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Pull Request descriptions must use the provided template, including Task Overview, Subtasks Completed, Implementation Details, Testing, Breaking Changes, and Related Tasks
📚 Learning: 2025-08-07T13:00:22.966Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1090
File: apps/extension/package.json:241-243
Timestamp: 2025-08-07T13:00:22.966Z
Learning: In monorepos, local packages should use "*" as the version constraint in package.json dependencies, as recommended by npm. This ensures the local version from within the same workspace is always used, rather than attempting to resolve from external registries. This applies to packages like task-master-ai within the eyaltoledano/claude-task-master monorepo.

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.

Applied to files:

  • package.json
  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to package.json : Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not modify real task files (tasks.json) during tests.

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/{core/utils,tools}/**/*.js : Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/` (e.g., path/core logic helpers in `mcp-server/src/core/utils/`, tool execution/response helpers in `mcp-server/src/tools/utils.js`).

Applied to files:

  • package.json
📚 Learning: 2025-07-31T20:49:04.638Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#997
File: apps/extension/package.publish.json:2-8
Timestamp: 2025-07-31T20:49:04.638Z
Learning: In the eyaltoledano/claude-task-master repository, the VS Code extension uses a 3-file packaging system where package.json (with name "extension") is for development within the monorepo, while package.publish.json (with name "task-master-hamster") contains the clean manifest for VS Code marketplace publishing. The different names are intentional and serve distinct purposes in the build and publishing workflow.

Applied to files:

  • apps/extension/package.json
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.

Applied to files:

  • apps/extension/package.json
📚 Learning: 2025-08-11T12:30:23.843Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md

Applied to files:

  • .claude/commands/dedupe.md
📚 Learning: 2025-08-06T21:12:43.715Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:1-6
Timestamp: 2025-08-06T21:12:43.715Z
Learning: In the eyaltoledano/claude-task-master repository, agent files are intentionally duplicated between `.claude/agents/` (for internal project use) and `assets/claude/agents/` (as template files for users to copy). This duplication serves different purposes and should be maintained to support both internal development and user distribution needs.

Applied to files:

  • .claude/commands/dedupe.md
📚 Learning: 2025-07-20T01:35:05.831Z
Learnt from: rtmcrc
PR: eyaltoledano/claude-task-master#933
File: scripts/modules/task-manager/parse-prd.js:226-226
Timestamp: 2025-07-20T01:35:05.831Z
Learning: The parsePRD function in scripts/modules/task-manager/parse-prd.js has a different parameter structure than other task-manager functions - it uses `options` parameter instead of `context` parameter because it generates tasks from PRD documents rather than operating on existing tasks.

Applied to files:

  • scripts/modules/task-manager/parse-prd/parse-prd-config.js
  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Generate task files from the current tag context, include tag information in generated files, and do not mix tasks from different tags in file generation.

Applied to files:

  • scripts/modules/task-manager/parse-prd/parse-prd-config.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Verify modifications on the in-memory task objects passed to writeJSON.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Use `generateTextService` and implement robust manual JSON parsing (with Zod validation after parsing) when structured output is needed, as `generateObjectService` has shown unreliability with some providers/schemas.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test core logic independently with both data formats, mock file system operations, test tag resolution behavior, and verify migration compatibility in unit tests.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Mock readJSON and writeJSON to avoid real file system interactions in tests.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Do not use or pass reportProgress within *Direct functions.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use mock-fs to mock file system operations in tests, and restore the file system after each test.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not test exact error messages; test for error presence and general properties instead.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock the action handlers for CLI commands and verify they're called with correct arguments.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/unit/**/*.test.js : Do not include actual command execution in unit tests.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Applied to files:

  • tests/unit/scripts/modules/task-manager/parse-prd.test.js
🧬 Code graph analysis (1)
tests/unit/scripts/modules/task-manager/parse-prd.test.js (3)
mcp-server/src/core/direct-functions/parse-prd.js (1)
  • result (155-172)
scripts/modules/task-manager/parse-prd/parse-prd-streaming.js (1)
  • result (559-568)
tests/unit/parse-prd.test.js (1)
  • parsePRD (211-213)
🪛 LanguageTool
.changeset/quiet-owls-fix-cli-sdk.md

[grammar] ~5-~5: Use correct spacing
Context: ...1.0.88` for improved export consistency. Related to JSON truncation handling in #...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: There might be a mistake here.
Context: ...Related to JSON truncation handling in #920; this change addresses a separate error-...

(QB_NEW_EN_OTHER)


[grammar] ~7-~7: Use correct spacing
Context: ...rate error-path crash reported in #1142.

(QB_NEW_EN_OTHER_ERROR_IDS_5)

.changeset/rich-emus-say.md

[typographical] ~5-~5: To join two clauses or set off examples, consider using an em dash.
Context: ...ly disable streaming for improved model compatibility - will be re-enabled in upcoming release

(QB_NEW_EN_DASH_RULE_EM)


[grammar] ~5-~5: There might be a mistake here.
Context: ...- will be re-enabled in upcoming release

(QB_NEW_EN_OTHER)

🪛 markdownlint-cli2 (0.17.2)
.changeset/quiet-owls-fix-cli-sdk.md

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

.changeset/rich-emus-say.md

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (11)
.changeset/rich-emus-say.md (1)

5-5: Polish the changeset summary for style and clarity (imperative + punctuation).

Keep it user-facing and single-line. Replace the hyphen with a semicolon and end with a period per our changeset guidance.

Apply this diff:

-Temporarily disable streaming for improved model compatibility - will be re-enabled in upcoming release
+Temporarily disable streaming for improved model compatibility; re-enable in a future release.

Note: markdownlint MD041 (top-level heading) is a false positive for changeset files; safe to ignore here.

package.json (1)

89-92: Please manually verify the next version bump to 0.25.1

I attempted to run npx changeset status --verbose but encountered an error (could not determine executable to run). To ensure the release will be version 0.25.1 as per the PR title, please:

  • Inspect your .changeset/*.md front-matter to confirm it specifies a patch bump.
  • Verify that the current version in package.json (e.g. 0.25.0) plus this patch bump equals 0.25.1.
  • Optionally run locally (with dependencies installed) yarn changeset version or npx changeset version to preview the new version.
.claude/commands/dedupe.md (1)

36-36: Attribution tweak acknowledged; verify intent to remove the hyperlink.

The new attribution “Generated with [Task Master Bot]” (escaped) is fine. Confirm that removing the external link is intentional and consistent across other command docs.

.changeset/quiet-owls-fix-cli-sdk.md (1)

5-8: Condense changeset text to a single, user-facing line (avoid commit-style body).

Changeset entries should be concise and imperative. Move deep technical detail and issue cross-links to the PR description or commit body.

Apply this diff:

-fix(claude-code): prevent crash/hang when the optional `@anthropic-ai/claude-code` SDK is missing by guarding `AbortError instanceof` checks and adding explicit SDK presence checks in `doGenerate`/`doStream`. Also bump the optional dependency to `^1.0.88` for improved export consistency.
-
-Related to JSON truncation handling in #920; this change addresses a separate error-path crash reported in #1142.
+Fix crash/hang when optional Claude Code SDK is missing; guard AbortError checks, add SDK presence checks, and bump optional @anthropic-ai/claude-code to ^1.0.88.

Note: markdownlint MD041 is expected noise for changeset files; safe to ignore.

apps/extension/package.json (2)

14-15: Activation events change looks fine.

Collapsing to single-line arrays does not alter behavior. No action needed.


142-143: Enum formatting-only changes are safe.

Single-line enum arrays are equivalent. No functional impact.

Also applies to: 203-204

src/ai-providers/custom-sdk/claude-code/language-model.js (1)

235-239: Robust AbortError guards LGTM.

Guarding instanceof with (AbortError && ...) avoids ReferenceErrors when the SDK isn’t loaded. Good defensive change.

Also applies to: 491-495

scripts/modules/task-manager/parse-prd/parse-prd-config.js (2)

80-85: Provider check helper is concise and correct.

Simple gating over main vs research provider aligns with CUSTOM_PROVIDERS. No issues.


71-75: The above script will dump the entirety of the parsePRD function (lines 210–270). This will let us verify:

  • That the only branch-check for streaming versus non-streaming is if (config.useStreaming).
  • What the fallback/non-streaming path does immediately after the catch block.
  • That there are no other gating conditions (e.g., inspecting options.* or other flags).

Once we see the output, we can confirm if downstream routing honors config.useStreaming exclusively or if further adjustments are needed.

tests/unit/scripts/modules/task-manager/parse-prd.test.js (2)

840-920: Skipped fallback test: convert to explicit TODO with actionable plan.

Skipping is fine short-term, but please annotate the reason and intended rewrite (switch from parseStream to streamObjectService semantics) to avoid permanent drift.

Add a comment like:

- test.skip('should fallback to non-streaming when streaming fails with specific errors (streaming disabled)', async () => {
+ // TODO(tech-debt): Rework fallback test for streamObjectService shape and unskip.
+ test.skip('should fallback to non-streaming when streaming fails with specific errors (streaming disabled)', async () => {

954-978: Research path assertion LGTM.

Verifies non-streaming with role: 'research' under streaming-disabled mode. Matches task-manager guidelines.

"Education",
"Other"
],
"categories": ["AI", "Visualization", "Education", "Other"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

🛠️ Refactor suggestion

Use workspace-local version for monorepo dependency.

Per our monorepo practice, depend on the local workspace package rather than a pinned version to avoid publish-time skew and ensure dev builds pick up HEAD.

Apply this diff:

-    "task-master-ai": "0.25.0"
+    "task-master-ai": "*"

Follow-up: If you prefer explicit workspace protocol, we can switch to "workspace:*" across the repo in a separate PR.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/extension/package.json around line 12, the package currently references
a pinned external version instead of the workspace-local package; update the
dependency entry in the dependencies/devDependencies to use the workspace
protocol (e.g., "workspace:*") so the monorepo uses the local package at HEAD
during development and avoids publish-time skew.

"apps/*",
"."
],
"workspaces": ["apps/*", "."],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add the required test scripts per repository guidelines.

Our repo standards call for test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci in package.json. You already have most of these; add the missing ones as simple aliases to existing commands to keep CI happy.

Apply this diff:

   "scripts": {
     "test": "node --experimental-vm-modules node_modules/.bin/jest",
     "test:fails": "node --experimental-vm-modules node_modules/.bin/jest --onlyFailures",
     "test:watch": "node --experimental-vm-modules node_modules/.bin/jest --watch",
     "test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage",
     "test:e2e": "./tests/e2e/run_e2e.sh",
     "test:e2e-report": "./tests/e2e/run_e2e.sh --analyze-log",
     "prepare": "chmod +x bin/task-master.js mcp-server/server.js",
     "changeset": "changeset",
     "release": "changeset publish",
     "inspector": "npx @modelcontextprotocol/inspector node mcp-server/server.js",
     "mcp-server": "node mcp-server/server.js",
     "format-check": "biome format .",
-    "format": "biome format . --write"
+    "format": "biome format . --write",
+    "test:unit": "npm run test",
+    "test:integration": "npm run test:e2e",
+    "test:ci": "npm run test -- --ci"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"workspaces": ["apps/*", "."],
"scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest",
"test:fails": "node --experimental-vm-modules node_modules/.bin/jest --onlyFailures",
"test:watch": "node --experimental-vm-modules node_modules/.bin/jest --watch",
"test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage",
"test:e2e": "./tests/e2e/run_e2e.sh",
"test:e2e-report": "./tests/e2e/run_e2e.sh --analyze-log",
"prepare": "chmod +x bin/task-master.js mcp-server/server.js",
"changeset": "changeset",
"release": "changeset publish",
"inspector": "npx @modelcontextprotocol/inspector node mcp-server/server.js",
"mcp-server": "node mcp-server/server.js",
"format-check": "biome format .",
"format": "biome format . --write",
"test:unit": "npm run test",
"test:integration": "npm run test:e2e",
"test:ci": "npm run test -- --ci"
},
🤖 Prompt for AI Agents
In package.json around line 12, add the missing test script aliases required by
repo guidelines: add "test", "test:watch", "test:coverage", "test:unit",
"test:integration", "test:e2e", and "test:ci" in the scripts section as simple
aliases to existing test commands — for example set "test" to run the CI test
alias, "test:watch" to run the test command with --watch, "test:coverage" to run
the test command with --coverage, "test:ci" to run tests in CI mode (e.g.
--runInBand), and make "test:unit", "test:integration", and "test:e2e" point to
the CI test command with appropriate --testPathPattern or tag filters for
unit/integration/e2e; ensure these are just npm script aliases (npm run ...) so
CI recognizes them.

Comment on lines +67 to 75
// Feature flag: Temporarily disable streaming, use generateObject instead
// TODO: Re-enable streaming once issues are resolved
const ENABLE_STREAMING = false;

this.useStreaming =
typeof this.reportProgress === 'function' || this.outputFormat === 'text';
ENABLE_STREAMING &&
(typeof this.reportProgress === 'function' ||
this.outputFormat === 'text');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Streaming hard-disabled as a feature flag: make it configurable and observable.

The gate is correct for temporarily pausing streaming, but a hard-coded false forces code edits and commits to flip it. Prefer an env/config-driven flag and add a brief debug log when streaming is disabled to aid diagnosis.

Apply this diff to make the flag configurable with a safe default and keep the existing behavior:

@@
-    // Feature flag: Temporarily disable streaming, use generateObject instead
-    // TODO: Re-enable streaming once issues are resolved
-    const ENABLE_STREAMING = false;
+    // Feature flag: Temporarily disable streaming; default off.
+    // TODO: Re-enable once issues are resolved.
+    const ENABLE_STREAMING =
+      process.env.ENABLE_STREAMING === '1' ||
+      process.env.ENABLE_STREAMING === 'true';
@@
-    this.useStreaming =
-      ENABLE_STREAMING &&
-      (typeof this.reportProgress === 'function' || this.outputFormat === 'text');
+    this.useStreaming =
+      ENABLE_STREAMING &&
+      (typeof this.reportProgress === 'function' || this.outputFormat === 'text');
+    if (!this.useStreaming && process?.env?.DEBUG?.includes('parse-prd')) {
+      // lightweight breadcrumb in debug builds
+      log('debug', '[parse-prd] Streaming disabled via feature flag; using generateObject path.');
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Feature flag: Temporarily disable streaming, use generateObject instead
// TODO: Re-enable streaming once issues are resolved
const ENABLE_STREAMING = false;
this.useStreaming =
typeof this.reportProgress === 'function' || this.outputFormat === 'text';
ENABLE_STREAMING &&
(typeof this.reportProgress === 'function' ||
this.outputFormat === 'text');
}
// Feature flag: Temporarily disable streaming; default off.
// TODO: Re-enable once issues are resolved.
const ENABLE_STREAMING =
process.env.ENABLE_STREAMING === '1' ||
process.env.ENABLE_STREAMING === 'true';
this.useStreaming =
ENABLE_STREAMING &&
(typeof this.reportProgress === 'function' ||
this.outputFormat === 'text');
if (!this.useStreaming && process?.env?.DEBUG?.includes('parse-prd')) {
// lightweight breadcrumb in debug builds
log('debug', '[parse-prd] Streaming disabled via feature flag; using generateObject path.');
}
}
🤖 Prompt for AI Agents
In scripts/modules/task-manager/parse-prd/parse-prd-config.js around lines 67 to
75, replace the hard-coded ENABLE_STREAMING = false with a config/env-driven
boolean (e.g., read process.env.ENABLE_STREAMING or a config object, parse it
safely to boolean and default to false) so toggling doesn't require code
changes; set this.useStreaming using that value as before, and add a brief
debug/info log when streaming is disabled (using the module's logger or
console.debug) to make the state observable for troubleshooting.

Comment on lines +172 to +176
if (!query) {
throw new Error(
"Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Good runtime guard, but DRY it and fail earlier in loader.

Duplicate guards for a missing SDK are added in both generate and stream paths. Prefer hardening loadClaudeCodeModule() to validate required exports and throwing there, so call-sites don’t need to re-check.

Apply this diff to make the loader authoritative and remove the redundant checks:

@@
-async function loadClaudeCodeModule() {
-	if (!query || !AbortError) {
-		try {
-			const mod = await import('@anthropic-ai/claude-code');
-			query = mod.query;
-			AbortError = mod.AbortError;
-		} catch (err) {
-			throw new Error(
-				"Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
-			);
-		}
-	}
-}
+async function loadClaudeCodeModule() {
+  if (query && AbortError) return;
+  try {
+    const mod = await import('@anthropic-ai/claude-code');
+    if (!mod?.query || !mod?.AbortError) {
+      throw new Error(
+        "Claude Code SDK is installed but missing required exports ('query', 'AbortError'). Please upgrade '@anthropic-ai/claude-code' to a compatible version."
+      );
+    }
+    query = mod.query;
+    AbortError = mod.AbortError;
+  } catch (err) {
+    throw new Error(
+      "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
+    );
+  }
+}
@@
-      if (!query) {
-        throw new Error(
-          "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
-        );
-      }
+      // SDK availability validated by loadClaudeCodeModule()
@@
-          if (!query) {
-            throw new Error(
-              "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
-            );
-          }
+          // SDK availability validated by loadClaudeCodeModule()

Also applies to: 343-347

Comment on lines 340 to 348
const stream = new ReadableStream({
start: async (controller) => {
try {
if (!query) {
throw new Error(
"Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
);
}
const response = query({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure ReadableStream availability across runtimes.

ReadableStream is used directly; in some Node runtimes it’s behind node:stream/web or may require a polyfill. Verify global availability or import from 'node:stream/web'.

Run to confirm and locate any existing polyfill/import:


🏁 Script executed:

#!/bin/bash
# Check all references to ReadableStream and imports for stream/web
rg -nP '\bReadableStream\b|node:stream/web|stream/web' -C2 --no-ignore-vcs

Length of output: 1646


Add explicit ReadableStream import to support Node.js runtimes

The code on line 340 of src/ai-providers/custom-sdk/claude-code/language-model.js uses new ReadableStream(...) without guaranteeing it’s globally available in all Node versions. To ensure compatibility, import ReadableStream from the built-in Node module or provide a browser/global fallback.

• File needing change:
• src/ai-providers/custom-sdk/claude-code/language-model.js

• Action:

  1. At the top of the file, add:
    + // Ensure ReadableStream is available in Node.js
    + import { ReadableStream } from 'node:stream/web';
  2. (Optional) If targeting both browser and Node, you can guard the import:
    let ReadableStreamCtor = globalThis.ReadableStream;
    try {
      // Node.js ≥ v18
      ReadableStreamCtor ||= require('node:stream/web').ReadableStream;
    } catch {}

— This guarantees the ReadableStream constructor is available regardless of runtime.

🤖 Prompt for AI Agents
In src/ai-providers/custom-sdk/claude-code/language-model.js around lines 340 to
348, the code constructs a ReadableStream directly which may not exist in all
Node runtimes; to fix, add a portable ReadableStream reference at the top of the
file: attempt to use globalThis.ReadableStream and fallback to requiring
'node:stream/web'.ReadableStream (wrapped in try/catch), or otherwise export a
ReadableStreamCtor variable that the stream construction uses; ensure the rest
of the file replaces direct new ReadableStream(...) with new
ReadableStreamCtor(...) so the constructor is available in both Node and browser
environments.

@Crunchyman-ralph Crunchyman-ralph merged commit 0d7ff62 into main Aug 22, 2025
22 of 23 checks passed
This was referenced Aug 22, 2025
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants