reviewflow 3.12.0 → 3.13.0
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/CHANGELOG.md +7 -0
- package/dist/frameworks/claude/claudeInvoker.d.ts +29 -0
- package/dist/frameworks/claude/claudeInvoker.d.ts.map +1 -1
- package/dist/frameworks/claude/claudeInvoker.js +201 -268
- package/dist/frameworks/claude/claudeInvoker.js.map +1 -1
- package/dist/frameworks/claude/streamJsonParser.d.ts +1 -38
- package/dist/frameworks/claude/streamJsonParser.d.ts.map +1 -1
- package/dist/frameworks/claude/streamJsonParser.js +16 -88
- package/dist/frameworks/claude/streamJsonParser.js.map +1 -1
- package/dist/frameworks/claude/timers/claudeInvocationTimers.d.ts +14 -0
- package/dist/frameworks/claude/timers/claudeInvocationTimers.d.ts.map +1 -0
- package/dist/frameworks/claude/timers/claudeInvocationTimers.js +23 -0
- package/dist/frameworks/claude/timers/claudeInvocationTimers.js.map +1 -0
- package/dist/main/dependencies.d.ts +2 -0
- package/dist/main/dependencies.d.ts.map +1 -1
- package/dist/main/dependencies.js +2 -0
- package/dist/main/dependencies.js.map +1 -1
- package/dist/main/routes.d.ts.map +1 -1
- package/dist/main/routes.js +3 -0
- package/dist/main/routes.js.map +1 -1
- package/dist/main/server.d.ts.map +1 -1
- package/dist/main/server.js +16 -0
- package/dist/main/server.js.map +1 -1
- package/dist/mcp/mcpServerStdio.d.ts.map +1 -1
- package/dist/mcp/mcpServerStdio.js +10 -1
- package/dist/mcp/mcpServerStdio.js.map +1 -1
- package/dist/modules/claude-invocation/entities/billingState/billingState.gateway.d.ts +8 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.schema.d.ts +8 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.schema.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.schema.js +7 -0
- package/dist/modules/claude-invocation/entities/billingState/billingState.schema.js.map +1 -0
- package/dist/modules/claude-invocation/entities/billingState/environment.gateway.d.ts +4 -0
- package/dist/modules/claude-invocation/entities/billingState/environment.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/billingState/environment.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/billingState/environment.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.d.ts +16 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.gateway.d.ts +52 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.guard.d.ts +11 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.guard.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.guard.js +4 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.guard.js.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.js +29 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.js.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.schema.d.ts +38 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.schema.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.schema.js +27 -0
- package/dist/modules/claude-invocation/entities/claudeSession/claudeSession.schema.js.map +1 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.schema.d.ts +10 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.schema.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.schema.js +14 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.schema.js.map +1 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.valueObject.d.ts +10 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.valueObject.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.valueObject.js +11 -0
- package/dist/modules/claude-invocation/entities/retrySchedule/retrySchedule.valueObject.js.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/mcpCompletion.gateway.d.ts +8 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/mcpCompletion.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/mcpCompletion.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/mcpCompletion.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/reviewReport.gateway.d.ts +16 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/reviewReport.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/reviewReport.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/reviewReport.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.guard.d.ts +8 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.guard.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.guard.js +7 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.guard.js.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.schema.d.ts +28 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.schema.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.schema.js +9 -0
- package/dist/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.schema.js.map +1 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.gateway.d.ts +6 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.gateway.js +2 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.schema.d.ts +16 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.schema.d.ts.map +1 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.schema.js +8 -0
- package/dist/modules/claude-invocation/entities/supervisorHealth/supervisorHealth.schema.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.d.ts +10 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.js +32 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.d.ts +25 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.js +102 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.d.ts +8 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.js +11 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.d.ts +34 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.js +131 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.d.ts +10 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.js +24 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.d.ts +12 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.js +25 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.d.ts +8 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.d.ts.map +1 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.js +18 -0
- package/dist/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/auditBilling.usecase.d.ts +15 -0
- package/dist/modules/claude-invocation/usecases/auditBilling.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/auditBilling.usecase.js +12 -0
- package/dist/modules/claude-invocation/usecases/auditBilling.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.d.ts +16 -0
- package/dist/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.js +64 -0
- package/dist/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.d.ts +10 -0
- package/dist/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.js +12 -0
- package/dist/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.d.ts +15 -0
- package/dist/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.js +25 -0
- package/dist/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.d.ts +34 -0
- package/dist/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.js +32 -0
- package/dist/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/retrieveReviewReport.usecase.d.ts +20 -0
- package/dist/modules/claude-invocation/usecases/retrieveReviewReport.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/retrieveReviewReport.usecase.js +17 -0
- package/dist/modules/claude-invocation/usecases/retrieveReviewReport.usecase.js.map +1 -0
- package/dist/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.d.ts +41 -0
- package/dist/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.d.ts.map +1 -0
- package/dist/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.js +88 -0
- package/dist/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.js.map +1 -0
- package/dist/modules/review-execution/usecases/mcp/setPhase.usecase.d.ts +2 -0
- package/dist/modules/review-execution/usecases/mcp/setPhase.usecase.d.ts.map +1 -1
- package/dist/modules/review-execution/usecases/mcp/setPhase.usecase.js +4 -1
- package/dist/modules/review-execution/usecases/mcp/setPhase.usecase.js.map +1 -1
- package/dist/tests/acceptance/169-migrate-claude-invocation-to-bg-mode.acceptance.test.d.ts +2 -0
- package/dist/tests/acceptance/169-migrate-claude-invocation-to-bg-mode.acceptance.test.d.ts.map +1 -0
- package/dist/tests/acceptance/169-migrate-claude-invocation-to-bg-mode.acceptance.test.js +238 -0
- package/dist/tests/acceptance/169-migrate-claude-invocation-to-bg-mode.acceptance.test.js.map +1 -0
- package/dist/tests/factories/claudeSession.factory.d.ts +5 -0
- package/dist/tests/factories/claudeSession.factory.d.ts.map +1 -0
- package/dist/tests/factories/claudeSession.factory.js +17 -0
- package/dist/tests/factories/claudeSession.factory.js.map +1 -0
- package/dist/tests/factories/sessionCompletion.factory.d.ts +5 -0
- package/dist/tests/factories/sessionCompletion.factory.d.ts.map +1 -0
- package/dist/tests/factories/sessionCompletion.factory.js +11 -0
- package/dist/tests/factories/sessionCompletion.factory.js.map +1 -0
- package/dist/tests/integration/claudeInvocation.integration.test.d.ts +2 -0
- package/dist/tests/integration/claudeInvocation.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/claudeInvocation.integration.test.js +147 -0
- package/dist/tests/integration/claudeInvocation.integration.test.js.map +1 -0
- package/dist/tests/stubs/billingState.stub.d.ts +10 -0
- package/dist/tests/stubs/billingState.stub.d.ts.map +1 -0
- package/dist/tests/stubs/billingState.stub.js +32 -0
- package/dist/tests/stubs/billingState.stub.js.map +1 -0
- package/dist/tests/stubs/claudeSession.stub.d.ts +23 -0
- package/dist/tests/stubs/claudeSession.stub.d.ts.map +1 -0
- package/dist/tests/stubs/claudeSession.stub.js +55 -0
- package/dist/tests/stubs/claudeSession.stub.js.map +1 -0
- package/dist/tests/stubs/environment.stub.d.ts +7 -0
- package/dist/tests/stubs/environment.stub.d.ts.map +1 -0
- package/dist/tests/stubs/environment.stub.js +10 -0
- package/dist/tests/stubs/environment.stub.js.map +1 -0
- package/dist/tests/stubs/mcpCompletion.stub.d.ts +13 -0
- package/dist/tests/stubs/mcpCompletion.stub.d.ts.map +1 -0
- package/dist/tests/stubs/mcpCompletion.stub.js +29 -0
- package/dist/tests/stubs/mcpCompletion.stub.js.map +1 -0
- package/dist/tests/stubs/reviewReport.stub.d.ts +11 -0
- package/dist/tests/stubs/reviewReport.stub.d.ts.map +1 -0
- package/dist/tests/stubs/reviewReport.stub.js +21 -0
- package/dist/tests/stubs/reviewReport.stub.js.map +1 -0
- package/dist/tests/stubs/supervisorHealth.stub.d.ts +8 -0
- package/dist/tests/stubs/supervisorHealth.stub.d.ts.map +1 -0
- package/dist/tests/stubs/supervisorHealth.stub.js +18 -0
- package/dist/tests/stubs/supervisorHealth.stub.js.map +1 -0
- package/dist/tests/units/architecture/noClaudePInProduction.test.d.ts +2 -0
- package/dist/tests/units/architecture/noClaudePInProduction.test.d.ts.map +1 -0
- package/dist/tests/units/architecture/noClaudePInProduction.test.js +89 -0
- package/dist/tests/units/architecture/noClaudePInProduction.test.js.map +1 -0
- package/dist/tests/units/frameworks/claude/buildSpawnEnv.test.d.ts +2 -0
- package/dist/tests/units/frameworks/claude/buildSpawnEnv.test.d.ts.map +1 -0
- package/dist/tests/units/frameworks/claude/buildSpawnEnv.test.js +30 -0
- package/dist/tests/units/frameworks/claude/buildSpawnEnv.test.js.map +1 -0
- package/dist/tests/units/frameworks/claude/streamJsonParser.test.js +15 -72
- package/dist/tests/units/frameworks/claude/streamJsonParser.test.js.map +1 -1
- package/dist/tests/units/frameworks/claude/timers/claudeInvocationTimers.test.d.ts +2 -0
- package/dist/tests/units/frameworks/claude/timers/claudeInvocationTimers.test.d.ts.map +1 -0
- package/dist/tests/units/frameworks/claude/timers/claudeInvocationTimers.test.js +66 -0
- package/dist/tests/units/frameworks/claude/timers/claudeInvocationTimers.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/claudeSession/claudeSession.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/entities/claudeSession/claudeSession.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/claudeSession/claudeSession.test.js +51 -0
- package/dist/tests/units/modules/claude-invocation/entities/claudeSession/claudeSession.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/retrySchedule/retrySchedule.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/entities/retrySchedule/retrySchedule.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/retrySchedule/retrySchedule.test.js +28 -0
- package/dist/tests/units/modules/claude-invocation/entities/retrySchedule/retrySchedule.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.test.js +27 -0
- package/dist/tests/units/modules/claude-invocation/entities/sessionCompletion/sessionCompletion.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.test.js +40 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.test.js +188 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.test.js +17 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.test.js +119 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.test.js +39 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/mcpCompletion.memory.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.test.js +64 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.test.js +32 -0
- package/dist/tests/units/modules/claude-invocation/interface-adapters/gateways/supervisorHealth.memory.gateway.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/auditBilling.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/auditBilling.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/auditBilling.usecase.test.js +33 -0
- package/dist/tests/units/modules/claude-invocation/usecases/auditBilling.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.test.js +53 -0
- package/dist/tests/units/modules/claude-invocation/usecases/awaitSessionCompletion.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.test.js +31 -0
- package/dist/tests/units/modules/claude-invocation/usecases/checkSupervisorHealth.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.test.js +17 -0
- package/dist/tests/units/modules/claude-invocation/usecases/cleanupClaudeSession.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.test.js +97 -0
- package/dist/tests/units/modules/claude-invocation/usecases/dispatchClaudeSession.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/retrieveReviewReport.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/retrieveReviewReport.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/retrieveReviewReport.usecase.test.js +49 -0
- package/dist/tests/units/modules/claude-invocation/usecases/retrieveReviewReport.usecase.test.js.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.test.d.ts +2 -0
- package/dist/tests/units/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.test.d.ts.map +1 -0
- package/dist/tests/units/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.test.js +171 -0
- package/dist/tests/units/modules/claude-invocation/usecases/runClaudeReviewJob.usecase.test.js.map +1 -0
- package/dist/tests/units/usecases/mcp/setPhase.usecase.test.js +21 -0
- package/dist/tests/units/usecases/mcp/setPhase.usecase.test.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.13.0](https://github.com/DGouron/review-flow/compare/reviewflow-v3.12.0...reviewflow-v3.13.0) (2026-05-22)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
* **claude-invocation:** implement spec-169 migrate claude -p to --bg mode ([#170](https://github.com/DGouron/review-flow/issues/170)) ([f3e408a](https://github.com/DGouron/review-flow/commit/f3e408af03056bb23017b29b62d811a25e62fb67))
|
|
14
|
+
|
|
8
15
|
## [3.12.0](https://github.com/DGouron/review-flow/compare/reviewflow-v3.11.0...reviewflow-v3.12.0) (2026-05-20)
|
|
9
16
|
|
|
10
17
|
|
|
@@ -11,6 +11,25 @@ import { ProjectConfigRoutingPolicyGateway } from '../../modules/review-executio
|
|
|
11
11
|
import { TrackTokenUsageUseCase } from '../../modules/token-accounting/usecases/trackTokenUsage/trackTokenUsage.usecase.js';
|
|
12
12
|
import { GetBudgetStatusUseCase } from '../../modules/token-accounting/usecases/getBudgetStatus/getBudgetStatus.usecase.js';
|
|
13
13
|
import { BudgetStatusPresenter, type BudgetStatusViewModel } from '../../modules/token-accounting/interface-adapters/presenters/budgetStatus.presenter.js';
|
|
14
|
+
import type { ClaudeSessionGateway } from '../../modules/claude-invocation/entities/claudeSession/claudeSession.gateway.js';
|
|
15
|
+
import type { McpCompletionBridge } from '../../modules/claude-invocation/entities/sessionCompletion/mcpCompletion.gateway.js';
|
|
16
|
+
import type { ReviewReportGateway } from '../../modules/claude-invocation/entities/sessionCompletion/reviewReport.gateway.js';
|
|
17
|
+
import type { BillingStateGateway } from '../../modules/claude-invocation/entities/billingState/billingState.gateway.js';
|
|
18
|
+
import type { EnvironmentGateway } from '../../modules/claude-invocation/entities/billingState/environment.gateway.js';
|
|
19
|
+
/**
|
|
20
|
+
* Bundle of gateways needed by runClaudeReviewJob. Built in the composition
|
|
21
|
+
* root so the Fastify process, the supervisor/billing timers, and the MCP
|
|
22
|
+
* completion bridge can share the same instances.
|
|
23
|
+
*/
|
|
24
|
+
export interface ClaudeInvocationDeps {
|
|
25
|
+
sessionGateway: ClaudeSessionGateway;
|
|
26
|
+
completionBridge: McpCompletionBridge;
|
|
27
|
+
reportGateway: ReviewReportGateway;
|
|
28
|
+
billingState: BillingStateGateway;
|
|
29
|
+
environment: EnvironmentGateway;
|
|
30
|
+
timeoutMs: number;
|
|
31
|
+
pollIntervalMs: number;
|
|
32
|
+
}
|
|
14
33
|
/**
|
|
15
34
|
* Gateways and use cases required by invokeClaudeReview. Extracted from the
|
|
16
35
|
* function body so production wiring stays in the composition root and tests
|
|
@@ -26,6 +45,7 @@ export interface ClaudeInvokerDependencies {
|
|
|
26
45
|
budgetStatusPresenter: BudgetStatusPresenter;
|
|
27
46
|
broadcastBudgetStatus: (viewModel: BudgetStatusViewModel) => void;
|
|
28
47
|
getEnabledLocalPaths?: () => string[];
|
|
48
|
+
invocation: ClaudeInvocationDeps;
|
|
29
49
|
}
|
|
30
50
|
/**
|
|
31
51
|
* Default wiring used when invokeClaudeReview is called without explicit deps.
|
|
@@ -36,6 +56,15 @@ export interface ClaudeInvokerDependencies {
|
|
|
36
56
|
* The no-op `broadcastBudgetStatus` here is intentional for tests and CLI
|
|
37
57
|
* one-shots where there is no WebSocket fanout to perform.
|
|
38
58
|
*/
|
|
59
|
+
/**
|
|
60
|
+
* Build the environment for spawning a Claude child process.
|
|
61
|
+
*
|
|
62
|
+
* Strips CLAUDECODE so a Claude-launched ReviewFlow does not leak its parent
|
|
63
|
+
* session marker into the child, and forces TERM=dumb + CI=true to keep the
|
|
64
|
+
* child in non-interactive mode.
|
|
65
|
+
*/
|
|
66
|
+
export declare function buildSpawnEnv(processEnv: NodeJS.ProcessEnv, override?: Record<string, string>): NodeJS.ProcessEnv;
|
|
67
|
+
export declare function createDefaultClaudeInvocationDeps(): ClaudeInvocationDeps;
|
|
39
68
|
export declare function createDefaultClaudeInvokerDependencies(): ClaudeInvokerDependencies;
|
|
40
69
|
export declare function resolveMcpServerPath(): string;
|
|
41
70
|
export declare function writeMcpContext(job: ReviewJob): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeInvoker.d.ts","sourceRoot":"","sources":["../../../src/frameworks/claude/claudeInvoker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+DAA+D,CAAC;
|
|
1
|
+
{"version":3,"file":"claudeInvoker.d.ts","sourceRoot":"","sources":["../../../src/frameworks/claude/claudeInvoker.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { writeFileSync, mkdirSync, existsSync, unlinkSync } from 'node:fs';
|
|
3
3
|
import { join, dirname } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { ProgressParser } from '../../frameworks/claude/progressParser.js';
|
|
6
5
|
import { logInfo, logWarn, logError } from '../../frameworks/logging/logBuffer.js';
|
|
7
6
|
import { getModel } from '../../frameworks/settings/runtimeSettings.js';
|
|
8
7
|
import { getProjectAgents, getFollowupAgents, loadProjectConfig } from '../../config/projectConfig.js';
|
|
@@ -23,8 +22,12 @@ import { FilesystemTokenUsageGateway } from '../../modules/token-accounting/inte
|
|
|
23
22
|
import { GetBudgetStatusUseCase } from '../../modules/token-accounting/usecases/getBudgetStatus/getBudgetStatus.usecase.js';
|
|
24
23
|
import { FilesystemBudgetGateway } from '../../modules/token-accounting/interface-adapters/gateways/budget/budget.filesystem.gateway.js';
|
|
25
24
|
import { BudgetStatusPresenter } from '../../modules/token-accounting/interface-adapters/presenters/budgetStatus.presenter.js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
25
|
+
import { ClaudeSessionCliGateway, } from '../../modules/claude-invocation/interface-adapters/gateways/claudeSession.cli.gateway.js';
|
|
26
|
+
import { FileSystemMcpCompletionBridge } from '../../modules/claude-invocation/interface-adapters/gateways/mcpCompletion.fileSystem.gateway.js';
|
|
27
|
+
import { ReviewReportFileSystemGateway } from '../../modules/claude-invocation/interface-adapters/gateways/reviewReport.fileSystem.gateway.js';
|
|
28
|
+
import { InMemoryBillingStateGateway } from '../../modules/claude-invocation/interface-adapters/gateways/billingState.memory.gateway.js';
|
|
29
|
+
import { ProcessEnvironmentGateway } from '../../modules/claude-invocation/interface-adapters/gateways/environment.process.gateway.js';
|
|
30
|
+
import { runClaudeReviewJob } from '../../modules/claude-invocation/usecases/runClaudeReviewJob.usecase.js';
|
|
28
31
|
/**
|
|
29
32
|
* Default wiring used when invokeClaudeReview is called without explicit deps.
|
|
30
33
|
*
|
|
@@ -34,6 +37,62 @@ import { StreamJsonParser } from '../../frameworks/claude/streamJsonParser.js';
|
|
|
34
37
|
* The no-op `broadcastBudgetStatus` here is intentional for tests and CLI
|
|
35
38
|
* one-shots where there is no WebSocket fanout to perform.
|
|
36
39
|
*/
|
|
40
|
+
/**
|
|
41
|
+
* Build the environment for spawning a Claude child process.
|
|
42
|
+
*
|
|
43
|
+
* Strips CLAUDECODE so a Claude-launched ReviewFlow does not leak its parent
|
|
44
|
+
* session marker into the child, and forces TERM=dumb + CI=true to keep the
|
|
45
|
+
* child in non-interactive mode.
|
|
46
|
+
*/
|
|
47
|
+
export function buildSpawnEnv(processEnv, override) {
|
|
48
|
+
const { CLAUDECODE: _claudeCode, ...rest } = processEnv;
|
|
49
|
+
return {
|
|
50
|
+
...rest,
|
|
51
|
+
TERM: 'dumb',
|
|
52
|
+
CI: 'true',
|
|
53
|
+
...(override ?? {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Default process runner used by createDefaultClaudeInvocationDeps when the
|
|
58
|
+
* composition root does not provide one. Wraps node:child_process.spawn so
|
|
59
|
+
* tests can inject a fake runner instead.
|
|
60
|
+
*/
|
|
61
|
+
function defaultProcessRunner() {
|
|
62
|
+
return async ({ args, cwd, env }) => new Promise((resolve, reject) => {
|
|
63
|
+
const child = spawn(resolveClaudePath(), args, {
|
|
64
|
+
cwd,
|
|
65
|
+
env: buildSpawnEnv(process.env, env),
|
|
66
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
67
|
+
});
|
|
68
|
+
let stdout = '';
|
|
69
|
+
let stderr = '';
|
|
70
|
+
child.stdout?.on('data', chunk => {
|
|
71
|
+
stdout += chunk.toString();
|
|
72
|
+
});
|
|
73
|
+
child.stderr?.on('data', chunk => {
|
|
74
|
+
stderr += chunk.toString();
|
|
75
|
+
});
|
|
76
|
+
child.on('error', reject);
|
|
77
|
+
child.on('close', code => {
|
|
78
|
+
resolve({ stdout, stderr, exitCode: code ?? -1 });
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function createDefaultClaudeInvocationDeps() {
|
|
83
|
+
return {
|
|
84
|
+
sessionGateway: new ClaudeSessionCliGateway(defaultProcessRunner()),
|
|
85
|
+
// FileSystem-backed because the MCP server runs in a sub-process spawned
|
|
86
|
+
// by `claude --bg`, so an in-memory bridge cannot reach the Fastify host.
|
|
87
|
+
// See FileSystemMcpCompletionBridge for the wire format.
|
|
88
|
+
completionBridge: new FileSystemMcpCompletionBridge(),
|
|
89
|
+
reportGateway: new ReviewReportFileSystemGateway(),
|
|
90
|
+
billingState: new InMemoryBillingStateGateway(),
|
|
91
|
+
environment: new ProcessEnvironmentGateway(),
|
|
92
|
+
timeoutMs: 15 * 60 * 1000,
|
|
93
|
+
pollIntervalMs: 30 * 1000,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
37
96
|
export function createDefaultClaudeInvokerDependencies() {
|
|
38
97
|
const tokenUsageGateway = new FilesystemTokenUsageGateway();
|
|
39
98
|
const budgetGateway = new FilesystemBudgetGateway();
|
|
@@ -48,6 +107,7 @@ export function createDefaultClaudeInvokerDependencies() {
|
|
|
48
107
|
getBudgetStatus: new GetBudgetStatusUseCase({ budgetGateway, tokenUsageGateway }),
|
|
49
108
|
budgetStatusPresenter: new BudgetStatusPresenter(),
|
|
50
109
|
broadcastBudgetStatus: () => { },
|
|
110
|
+
invocation: createDefaultClaudeInvocationDeps(),
|
|
51
111
|
};
|
|
52
112
|
}
|
|
53
113
|
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -116,10 +176,6 @@ export function cleanupMcpContext(jobId) {
|
|
|
116
176
|
// Ignore cleanup errors
|
|
117
177
|
}
|
|
118
178
|
}
|
|
119
|
-
// Memory guard configuration
|
|
120
|
-
const MEMORY_LIMIT_GB = 4; // Kill process if RSS exceeds 4GB
|
|
121
|
-
const MEMORY_CHECK_INTERVAL_MS = 5000; // Check every 5 seconds
|
|
122
|
-
const MEMORY_LIMIT_BYTES = MEMORY_LIMIT_GB * 1024 * 1024 * 1024;
|
|
123
179
|
function fetchDiffStatsSafely(job, deps, logger) {
|
|
124
180
|
try {
|
|
125
181
|
const gateway = deps.diffStatsFetchFactory(job.platform);
|
|
@@ -281,13 +337,11 @@ export async function invokeClaudeReview(job, logger, onProgress, signal, deps =
|
|
|
281
337
|
// Build MCP config: isolated from project .mcp.json to avoid
|
|
282
338
|
// third-party MCP servers (e.g. gitnexus) causing initialization timeouts
|
|
283
339
|
const mcpConfigJson = buildMcpConfigJson();
|
|
284
|
-
// Build arguments
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
// --mcp-config + --strict-mcp-config: use ONLY review-progress MCP server
|
|
340
|
+
// Build arguments for the --bg (background subscription billing) invocation.
|
|
341
|
+
// The session id is captured from stdout; completion is observed through MCP
|
|
342
|
+
// (set_phase) or `claude agents --json` polling. No -p, no --print, no stream-json.
|
|
288
343
|
const args = [
|
|
289
|
-
'--
|
|
290
|
-
'--verbose',
|
|
344
|
+
'--bg',
|
|
291
345
|
'--model', model,
|
|
292
346
|
'--permission-mode', 'bypassPermissions',
|
|
293
347
|
'--append-system-prompt', mcpSystemPrompt,
|
|
@@ -295,7 +349,7 @@ export async function invokeClaudeReview(job, logger, onProgress, signal, deps =
|
|
|
295
349
|
'--strict-mcp-config',
|
|
296
350
|
'--allowedTools', 'Read,Glob,Grep,Bash,Edit,Task,Skill,Write,LSP,mcp__review-progress__*',
|
|
297
351
|
'--disallowedTools', 'EnterPlanMode,AskUserQuestion',
|
|
298
|
-
|
|
352
|
+
prompt,
|
|
299
353
|
];
|
|
300
354
|
// Setup MCP job context file (used by MCP server to identify the review)
|
|
301
355
|
writeMcpContext(job);
|
|
@@ -319,13 +373,6 @@ export async function invokeClaudeReview(job, logger, onProgress, signal, deps =
|
|
|
319
373
|
jobType: job.jobType || 'review',
|
|
320
374
|
customAgents: projectAgents?.length ?? 'default',
|
|
321
375
|
});
|
|
322
|
-
// Initialize progress parser with project agents (or defaults)
|
|
323
|
-
const progressParser = new ProgressParser(job.id, (event, progress) => {
|
|
324
|
-
logger.debug({ event, progress: progress.overallProgress }, 'Progress update');
|
|
325
|
-
onProgress?.(progress, event);
|
|
326
|
-
}, projectAgents);
|
|
327
|
-
// Emit initial progress
|
|
328
|
-
onProgress?.(progressParser.getProgress());
|
|
329
376
|
// Check if already cancelled
|
|
330
377
|
if (signal?.aborted) {
|
|
331
378
|
logWarn('Review annulée avant démarrage', { jobId: job.id });
|
|
@@ -335,265 +382,151 @@ export async function invokeClaudeReview(job, logger, onProgress, signal, deps =
|
|
|
335
382
|
stdout: '',
|
|
336
383
|
stderr: 'Review cancelled before start',
|
|
337
384
|
durationMs: Date.now() - startTime,
|
|
338
|
-
finalProgress: progressParser.getProgress(),
|
|
339
385
|
cancelled: true,
|
|
340
386
|
};
|
|
341
387
|
}
|
|
342
|
-
return
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
388
|
+
return invokeViaBackgroundSession({
|
|
389
|
+
job,
|
|
390
|
+
prompt,
|
|
391
|
+
model,
|
|
392
|
+
mcpSystemPrompt,
|
|
393
|
+
mcpConfigJson,
|
|
394
|
+
diffStats,
|
|
395
|
+
startTime,
|
|
396
|
+
signal,
|
|
397
|
+
}, logger, onProgress, deps);
|
|
398
|
+
}
|
|
399
|
+
async function invokeViaBackgroundSession(context, logger, onProgress, deps) {
|
|
400
|
+
const { job, prompt, model, mcpSystemPrompt, mcpConfigJson, diffStats, startTime, signal } = context;
|
|
401
|
+
const invocation = deps.invocation;
|
|
402
|
+
const mergeRequestId = `${job.platform}-${job.projectPath}-${job.mrNumber}`;
|
|
403
|
+
const jobType = job.jobType === 'followup' ? 'followup' : 'review';
|
|
404
|
+
// attempt counter is reserved for the queue layer to re-enqueue with backoff
|
|
405
|
+
// when status === 'retry' is returned. Until that wiring exists, every
|
|
406
|
+
// invocation is treated as attempt 0 and a single retry signal surfaces back
|
|
407
|
+
// to the controller as a soft failure.
|
|
408
|
+
const attempt = 0;
|
|
409
|
+
const flags = {
|
|
410
|
+
model,
|
|
411
|
+
mcpConfigJson,
|
|
412
|
+
systemPrompt: mcpSystemPrompt,
|
|
413
|
+
allowedTools: 'Read,Glob,Grep,Bash,Edit,Task,Skill,Write,LSP,mcp__review-progress__*',
|
|
414
|
+
disallowedTools: 'EnterPlanMode,AskUserQuestion',
|
|
415
|
+
permissionMode: 'bypassPermissions',
|
|
416
|
+
};
|
|
417
|
+
let result;
|
|
418
|
+
try {
|
|
419
|
+
result = await runClaudeReviewJob({
|
|
420
|
+
jobId: job.id,
|
|
421
|
+
jobType,
|
|
422
|
+
prompt,
|
|
423
|
+
flags,
|
|
424
|
+
localPath: job.localPath,
|
|
425
|
+
mergeRequestId,
|
|
426
|
+
mergeRequestNumber: job.mrNumber,
|
|
427
|
+
attempt,
|
|
428
|
+
signal,
|
|
429
|
+
}, {
|
|
430
|
+
sessionGateway: invocation.sessionGateway,
|
|
431
|
+
completionBridge: invocation.completionBridge,
|
|
432
|
+
reportGateway: invocation.reportGateway,
|
|
433
|
+
billingState: invocation.billingState,
|
|
434
|
+
environment: invocation.environment,
|
|
435
|
+
now: () => new Date(),
|
|
436
|
+
timeoutMs: invocation.timeoutMs,
|
|
437
|
+
pollIntervalMs: invocation.pollIntervalMs,
|
|
360
438
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
║ Job: ${job.id.substring(0, 50).padEnd(50)} ║
|
|
375
|
-
║ ║
|
|
376
|
-
║ The review process consumed too much memory. ║
|
|
377
|
-
║ This usually happens when running too many sub-agents ║
|
|
378
|
-
║ in parallel. Consider using sequential execution. ║
|
|
379
|
-
║ ║
|
|
380
|
-
╚═══════════════════════════════════════════════════════════════════╝
|
|
381
|
-
`;
|
|
382
|
-
logger.error({ rssMB, limitMB: MEMORY_LIMIT_GB * 1024, jobId: job.id }, 'Memory limit exceeded, killing process');
|
|
383
|
-
logError('Memory limit exceeded', {
|
|
384
|
-
jobId: job.id,
|
|
385
|
-
rssMB,
|
|
386
|
-
limitMB: MEMORY_LIMIT_GB * 1024,
|
|
387
|
-
message: 'Review killed due to excessive memory consumption',
|
|
388
|
-
});
|
|
389
|
-
// Output error to stderr for visibility
|
|
390
|
-
stderr += errorMessage;
|
|
391
|
-
// Kill the child process
|
|
392
|
-
child.kill('SIGKILL');
|
|
393
|
-
clearInterval(memoryCheckInterval);
|
|
394
|
-
}
|
|
395
|
-
else if (rssMB > (MEMORY_LIMIT_GB * 1024 * 0.8)) {
|
|
396
|
-
// Warn when approaching limit (80%)
|
|
397
|
-
logger.warn({ rssMB, limitMB: MEMORY_LIMIT_GB * 1024 }, 'Memory usage high, approaching limit');
|
|
398
|
-
}
|
|
399
|
-
}, MEMORY_CHECK_INTERVAL_MS);
|
|
400
|
-
// Handle cancellation via AbortSignal
|
|
401
|
-
const abortHandler = () => {
|
|
402
|
-
if (!cancelled) {
|
|
403
|
-
cancelled = true;
|
|
404
|
-
logger.info({ jobId: job.id }, 'Review annulée par utilisateur');
|
|
405
|
-
logWarn('Review annulée', { jobId: job.id });
|
|
406
|
-
child.kill('SIGTERM');
|
|
407
|
-
// Give it time to cleanup, then force kill
|
|
408
|
-
setTimeout(() => {
|
|
409
|
-
if (!child.killed) {
|
|
410
|
-
child.kill('SIGKILL');
|
|
411
|
-
}
|
|
412
|
-
}, 5000);
|
|
413
|
-
}
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
cleanupMcpContext(job.id);
|
|
442
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
443
|
+
logger.error({ error: message, jobId: job.id }, 'runClaudeReviewJob threw');
|
|
444
|
+
logError('Review en erreur', { jobId: job.id, message });
|
|
445
|
+
return {
|
|
446
|
+
success: false,
|
|
447
|
+
exitCode: null,
|
|
448
|
+
stdout: '',
|
|
449
|
+
stderr: message,
|
|
450
|
+
durationMs: Date.now() - startTime,
|
|
451
|
+
selectedModel: model,
|
|
414
452
|
};
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
logger.debug({ preview }, 'Claude stdout');
|
|
427
|
-
});
|
|
428
|
-
child.stderr.on('data', (data) => {
|
|
429
|
-
const chunk = data.toString();
|
|
430
|
-
stderr += chunk;
|
|
431
|
-
logger.warn({ chunk }, 'Claude stderr');
|
|
432
|
-
logWarn('Claude stderr', { jobId: job.id, message: chunk.substring(0, 500) });
|
|
433
|
-
});
|
|
434
|
-
child.on('error', (error) => {
|
|
435
|
-
logger.error({ error }, 'Erreur lors du spawn de Claude');
|
|
436
|
-
logError('Erreur spawn Claude', { jobId: job.id, error: error.message });
|
|
437
|
-
progressParser.markFailed(error.message);
|
|
438
|
-
resolve({
|
|
439
|
-
success: false,
|
|
440
|
-
exitCode: null,
|
|
441
|
-
stdout,
|
|
442
|
-
stderr: stderr + `\nSpawn error: ${error.message}`,
|
|
443
|
-
durationMs: Date.now() - startTime,
|
|
444
|
-
finalProgress: progressParser.getProgress(),
|
|
445
|
-
});
|
|
453
|
+
}
|
|
454
|
+
cleanupMcpContext(job.id);
|
|
455
|
+
const durationMs = Date.now() - startTime;
|
|
456
|
+
const durationMin = Math.round(durationMs / 60000);
|
|
457
|
+
if (result.status === 'completed') {
|
|
458
|
+
logInfo('Review terminée', {
|
|
459
|
+
jobId: job.id,
|
|
460
|
+
mrNumber: job.mrNumber,
|
|
461
|
+
duration: `${durationMin} min`,
|
|
462
|
+
outputLength: result.content.length,
|
|
463
|
+
model,
|
|
446
464
|
});
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
clearInterval(memoryCheckInterval);
|
|
450
|
-
cleanupMcpContext(job.id);
|
|
451
|
-
if (signal) {
|
|
452
|
-
signal.removeEventListener('abort', abortHandler);
|
|
453
|
-
}
|
|
454
|
-
const durationMs = Date.now() - startTime;
|
|
455
|
-
const success = code === 0 && !cancelled && !memoryExceeded;
|
|
456
|
-
const assistantText = streamParser.getAssistantText();
|
|
457
|
-
const tokenUsage = streamParser.getUsage();
|
|
458
|
-
// Save logs: raw stream-json + reconstructed human text for readability
|
|
465
|
+
// Save review statistics (followups are not counted as reviews)
|
|
466
|
+
if (job.jobType !== 'followup') {
|
|
459
467
|
try {
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const logPath = join(logsDir, `${sanitizedJobId}-stdout.log`);
|
|
466
|
-
writeFileSync(logPath, `=== Claude Review Output ===\nJob: ${job.id}\nMR: ${job.mrNumber}\nSkill: ${job.skill}\nModel: ${model}\nExit code: ${code}\nDuration: ${Math.round(durationMs / 1000)}s\nTimestamp: ${new Date().toISOString()}\n\n--- ASSISTANT TEXT ---\n${assistantText}\n\n--- STDERR ---\n${stderr}\n\n--- RAW STREAM-JSON ---\n${stdout}\n`);
|
|
467
|
-
logger.info({ logPath }, 'Review stdout saved to log file');
|
|
468
|
-
}
|
|
469
|
-
catch {
|
|
470
|
-
// Non-critical
|
|
471
|
-
}
|
|
472
|
-
// Finalize progress
|
|
473
|
-
if (memoryExceeded) {
|
|
474
|
-
progressParser.markFailed('Memory limit exceeded - review killed');
|
|
475
|
-
}
|
|
476
|
-
else if (cancelled) {
|
|
477
|
-
progressParser.markFailed('Annulée par utilisateur');
|
|
478
|
-
}
|
|
479
|
-
else if (success) {
|
|
480
|
-
progressParser.markAllCompleted();
|
|
468
|
+
const mrId = `${job.platform}-${job.projectPath}-${job.mrNumber}`;
|
|
469
|
+
const mrDetails = deps.trackingGateway.getById(job.localPath, mrId);
|
|
470
|
+
const assignedBy = mrDetails?.assignment?.username;
|
|
471
|
+
const reviewStats = addReviewStats(job.localPath, job.mrNumber, durationMs, result.content, assignedBy, diffStats);
|
|
472
|
+
logger.info({ reviewStats }, 'Stats de review enregistrées');
|
|
481
473
|
}
|
|
482
|
-
|
|
483
|
-
|
|
474
|
+
catch (statsError) {
|
|
475
|
+
logger.warn({ error: statsError }, 'Erreur lors de l\'enregistrement des stats');
|
|
484
476
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
: cancelled
|
|
498
|
-
? 'Claude annulé'
|
|
499
|
-
: success
|
|
500
|
-
? 'Claude terminé avec succès'
|
|
501
|
-
: 'Claude terminé avec erreur');
|
|
502
|
-
// Log to dashboard with summary
|
|
503
|
-
const durationMin = Math.round(durationMs / 60000);
|
|
504
|
-
if (memoryExceeded) {
|
|
505
|
-
logError('Review killed - Memory limit exceeded', {
|
|
506
|
-
jobId: job.id,
|
|
507
|
-
mrNumber: job.mrNumber,
|
|
508
|
-
duration: `${durationMin} min`,
|
|
509
|
-
limitGB: MEMORY_LIMIT_GB,
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
else if (cancelled) {
|
|
513
|
-
logWarn('Review annulée', {
|
|
514
|
-
jobId: job.id,
|
|
515
|
-
mrNumber: job.mrNumber,
|
|
516
|
-
duration: `${durationMin} min`,
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
else if (success) {
|
|
520
|
-
logInfo('Review terminée', {
|
|
521
|
-
jobId: job.id,
|
|
522
|
-
mrNumber: job.mrNumber,
|
|
523
|
-
duration: `${durationMin} min`,
|
|
524
|
-
outputLength: assistantText.length,
|
|
525
|
-
model,
|
|
526
|
-
});
|
|
527
|
-
// Save review statistics (followups are not counted as reviews)
|
|
528
|
-
if (job.jobType !== 'followup') {
|
|
529
|
-
try {
|
|
530
|
-
const mrId = `${job.platform}-${job.projectPath}-${job.mrNumber}`;
|
|
531
|
-
const mrDetails = deps.trackingGateway.getById(job.localPath, mrId);
|
|
532
|
-
const assignedBy = mrDetails?.assignment?.username;
|
|
533
|
-
const reviewStats = addReviewStats(job.localPath, job.mrNumber, durationMs, assistantText, assignedBy, diffStats);
|
|
534
|
-
logger.info({ reviewStats }, 'Stats de review enregistrées');
|
|
535
|
-
}
|
|
536
|
-
catch (statsError) {
|
|
537
|
-
logger.warn({ error: statsError }, 'Erreur lors de l\'enregistrement des stats');
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
// Persist token usage for cost tracking (non-critical, never blocks the review result)
|
|
541
|
-
if (tokenUsage) {
|
|
542
|
-
try {
|
|
543
|
-
await deps.trackTokenUsage.execute({
|
|
544
|
-
jobId: job.id,
|
|
545
|
-
mrNumber: job.mrNumber,
|
|
546
|
-
platform: job.platform,
|
|
547
|
-
projectPath: job.projectPath,
|
|
548
|
-
localPath: job.localPath,
|
|
549
|
-
model,
|
|
550
|
-
recordedAt: new Date().toISOString(),
|
|
551
|
-
usage: tokenUsage,
|
|
552
|
-
});
|
|
553
|
-
logger.info({ jobId: job.id, model, usage: tokenUsage }, 'Token usage recorded');
|
|
554
|
-
const broadcastLocalPaths = deps.getEnabledLocalPaths?.() ?? [job.localPath];
|
|
555
|
-
await broadcastBudgetAfterUsage({
|
|
556
|
-
getBudgetStatus: deps.getBudgetStatus,
|
|
557
|
-
broadcastBudgetStatus: deps.broadcastBudgetStatus,
|
|
558
|
-
presenter: deps.budgetStatusPresenter,
|
|
559
|
-
}, { localPaths: broadcastLocalPaths }, logger);
|
|
560
|
-
}
|
|
561
|
-
catch (trackError) {
|
|
562
|
-
logger.warn({ jobId: job.id, error: trackError }, 'Failed to persist token usage');
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
// Log assistant text preview for debugging
|
|
566
|
-
if (assistantText.length > 0) {
|
|
567
|
-
logInfo('Claude output preview', {
|
|
568
|
-
jobId: job.id,
|
|
569
|
-
preview: assistantText.substring(0, 1000),
|
|
570
|
-
fullLength: assistantText.length,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
logError('Review échouée', {
|
|
576
|
-
jobId: job.id,
|
|
577
|
-
mrNumber: job.mrNumber,
|
|
578
|
-
exitCode: code,
|
|
579
|
-
duration: `${durationMin} min`,
|
|
580
|
-
stderr: stderr.substring(0, 500),
|
|
581
|
-
stdoutPreview: (assistantText || stdout).substring(0, 300),
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
resolve({
|
|
585
|
-
success,
|
|
586
|
-
exitCode: memoryExceeded ? null : code,
|
|
587
|
-
stdout: assistantText,
|
|
588
|
-
stderr,
|
|
589
|
-
durationMs,
|
|
590
|
-
finalProgress,
|
|
591
|
-
cancelled: cancelled || memoryExceeded,
|
|
592
|
-
usage: tokenUsage,
|
|
593
|
-
selectedModel: model,
|
|
477
|
+
}
|
|
478
|
+
// Token usage tracking is disabled in --bg mode: the legacy stream-json
|
|
479
|
+
// path is gone and `claude --bg` does not emit usage to stdout. Re-enabling
|
|
480
|
+
// requires parsing `claude logs <sessionId>` — tracked in SPEC-171
|
|
481
|
+
// (docs/specs/171-bg-token-usage-tracking.md). Until SPEC-171 ships, the
|
|
482
|
+
// budget dashboard reports zero spending for --bg reviews.
|
|
483
|
+
if (onProgress) {
|
|
484
|
+
onProgress({
|
|
485
|
+
currentPhase: 'completed',
|
|
486
|
+
overallProgress: 100,
|
|
487
|
+
lastUpdate: new Date(),
|
|
488
|
+
agents: [],
|
|
594
489
|
});
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
success: true,
|
|
493
|
+
exitCode: 0,
|
|
494
|
+
stdout: result.content,
|
|
495
|
+
stderr: '',
|
|
496
|
+
durationMs,
|
|
497
|
+
usage: null,
|
|
498
|
+
selectedModel: model,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
if (result.status === 'retry') {
|
|
502
|
+
logWarn('Rate-limited — backoff demandé', {
|
|
503
|
+
jobId: job.id,
|
|
504
|
+
delayMs: result.delayMs,
|
|
505
|
+
nextAttempt: result.attempt,
|
|
595
506
|
});
|
|
507
|
+
return {
|
|
508
|
+
success: false,
|
|
509
|
+
exitCode: 1,
|
|
510
|
+
stdout: '',
|
|
511
|
+
stderr: `rate-limited; retry in ${result.delayMs}ms (attempt ${result.attempt})`,
|
|
512
|
+
durationMs,
|
|
513
|
+
selectedModel: model,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
logError('Review échouée', {
|
|
517
|
+
jobId: job.id,
|
|
518
|
+
mrNumber: job.mrNumber,
|
|
519
|
+
duration: `${durationMin} min`,
|
|
520
|
+
reason: result.reason,
|
|
596
521
|
});
|
|
522
|
+
return {
|
|
523
|
+
success: false,
|
|
524
|
+
exitCode: 1,
|
|
525
|
+
stdout: '',
|
|
526
|
+
stderr: result.reason,
|
|
527
|
+
durationMs,
|
|
528
|
+
selectedModel: model,
|
|
529
|
+
};
|
|
597
530
|
}
|
|
598
531
|
/**
|
|
599
532
|
* Send desktop notification
|