feat: provider extensions and drop claude-code-router mode (#295)

* feat: add ReportOutputProvider for consumer-extended report artifacts

* fix: thread deliverablesSubdir through report assembly

* fix: produce structured report JSON on resume path

* fix: fail loud on structured report output provider errors

* feat: extend checkpoint provider and container DI for consumer-specific backends

* fix: pre-create .shannon overlay mount points on all platforms

* chore: drop claude-code-router mode

* fix: drop 'resets' keyword from spending-cap text patterns
This commit is contained in:
ezl-keygraph
2026-04-20 13:21:54 +05:30
committed by GitHub
parent 01644ff2ed
commit 581c208b84
31 changed files with 240 additions and 416 deletions
@@ -1,25 +1,59 @@
/**
* CheckpointProvider — injectable interface for external state persistence.
*
* Called after each agent completes to allow external progress tracking.
* During the concurrent vulnerability-exploitation phase, 5 pipelines run
* in parallel — onAgentComplete fires per-agent for granular progress.
* Called before and after each agent to support skip-guard (resume) and
* post-agent artifact persistence. During the concurrent vulnerability-exploitation
* phase, 5 pipelines run in parallel — methods fire per-agent for granular control.
*
* Default: no-op.
* Default: no-op (skip nothing, persist nothing).
*/
import type { PipelineState } from '../temporal/shared.js';
import type { AgentMetrics, PipelineState } from '../temporal/shared.js';
/** Result of a pre-agent skip check. */
export interface SkipDecision {
readonly skip: boolean;
readonly metrics?: AgentMetrics; // Required when skip=true
}
/** File-system context passed after agent completion for artifact persistence. */
export interface CheckpointContext {
readonly repoPath: string;
readonly sessionId: string;
readonly deliverablesSubdir: string;
readonly outputPath?: string;
}
export interface CheckpointProvider {
/**
* Called before an agent activity executes.
* Return { skip: true, metrics } to skip the agent (e.g., output files already exist).
* Return { skip: false } to run normally.
*/
shouldSkipAgent(
agentName: string,
repoPath: string,
deliverablesSubdir: string,
): Promise<SkipDecision>;
/**
* Called after an agent activity succeeds.
* Receives pipeline state and optional file context for artifact persistence.
*/
onAgentComplete(
agentName: string,
phase: string,
state: PipelineState,
context?: CheckpointContext,
): Promise<void>;
}
/** Default no-op implementation — no external checkpointing. */
export class NoOpCheckpointProvider implements CheckpointProvider {
async shouldSkipAgent(): Promise<SkipDecision> {
return { skip: false };
}
async onAgentComplete(): Promise<void> {
// No-op
}
@@ -1,7 +1,7 @@
/**
* FindingsProvider — injectable interface for external findings integration.
*
* Allows external security data (SAST, SCA, secrets, etc.) to be merged
* Allows external security data from consumer-supplied sources to be merged
* into the exploitation pipeline between vulnerability analysis and exploitation.
*
* Default: no-op returning { mergedCount: 0 }.
+3 -1
View File
@@ -5,7 +5,9 @@
* Consumers can provide alternate implementations via the DI container.
*/
export type { CheckpointProvider } from './checkpoint-provider.js';
export type { CheckpointProvider, CheckpointContext, SkipDecision } from './checkpoint-provider.js';
export { NoOpCheckpointProvider } from './checkpoint-provider.js';
export type { FindingsProvider } from './findings-provider.js';
export { NoOpFindingsProvider } from './findings-provider.js';
export type { ReportOutputProvider } from './report-output-provider.js';
export { NoOpReportOutputProvider } from './report-output-provider.js';
@@ -0,0 +1,22 @@
/**
* ReportOutputProvider — injectable interface for emitting an optional
* additional artifact alongside the assembled markdown report.
*
* Runs after the report agent has finalized
* `comprehensive_security_assessment_report.md`. Consumers can override to
* produce derived outputs; the default no-op produces nothing.
*/
import type { ActivityInput } from '../temporal/activities.js';
import type { ActivityLogger } from '../types/activity-logger.js';
export interface ReportOutputProvider {
generate(input: ActivityInput, logger: ActivityLogger): Promise<{ outputPath?: string }>;
}
/** Default no-op implementation — no additional output produced. */
export class NoOpReportOutputProvider implements ReportOutputProvider {
async generate(): Promise<{ outputPath?: string }> {
return {};
}
}