Commit Graph

6 Commits

Author SHA1 Message Date
ajmallesh d3816a29fa refactor: extract services layer, Result type, and ErrorCode classification
- Add DI container (src/services/) with AgentExecutionService, ConfigLoaderService, and ExploitationCheckerService — pure domain logic with no Temporal dependencies
- Introduce Result<T, E> type and ErrorCode enum for code-based error classification in classifyErrorForTemporal, replacing scattered string matching
- Consolidate billing/spending cap detection into utils/billing-detection.ts with shared pattern lists across message-handlers, claude-executor, and error-handling
- Extract LogStream abstraction for append-only logging with backpressure, used by both AgentLogger and WorkflowLogger
- Simplify activities.ts from inline lifecycle logic to thin wrappers delegating to services, with heartbeat and error classification
- Expand config-parser with human-readable AJV errors, security validation, and rule type-specific checks
2026-02-16 16:12:21 -08:00
ezl-keygraph f017a41436 fix: set originalWorkflowId in logPhaseTransition and remove path import from agents.ts
logPhaseTransition was the first activity to create session.json but
didn't pass workflowId, so originalWorkflowId was never set. This
caused terminateExistingWorkflows to look up the workspace name instead
of the actual workflow ID during resume.

Also remove path import from types/agents.ts to fix Temporal workflow
bundle determinism error.
2026-02-13 22:09:07 +05:30
ezl-keygraph f932fad2ed feat: add workflow resume from workspace via --workspace flag
When a workflow is interrupted (VM crash, Ctrl+C, Docker restart), it can
now be resumed by passing the workspace name. The system reads session.json
to determine which agents completed, validates deliverables exist on disk,
restores the git checkpoint, and skips already-completed agents.

- Add --workspace CLI flag and auto-terminate conflicting workflows
- Add loadResumeState, restoreGitCheckpoint, recordResumeAttempt activities
- Add skip logic for all 5 pipeline phases including parallel execution
- Separate sessionId (persistent directory) from workflowId (execution ID)
- Track resume attempts in session.json for audit trail
- Derive AgentName type from ALL_AGENTS array to eliminate duplication
- Add getDeliverablePath mapping for deliverable validation
2026-02-13 20:26:16 +05:30
Arjun Malleswaran 51e621d0d5 Feat/temporal (#46)
* refactor: modularize claude-executor and extract shared utilities

- Extract message handling into src/ai/message-handlers.ts with pure functions
- Extract output formatting into src/ai/output-formatters.ts
- Extract progress management into src/ai/progress-manager.ts
- Add audit-logger.ts with Null Object pattern for optional logging
- Add shared utilities: formatting.ts, file-io.ts, functional.ts
- Consolidate getPromptNameForAgent into src/types/agents.ts

* feat: add Claude Code custom commands for debug and review

* feat: add Temporal integration foundation (phase 1-2)

- Add Temporal SDK dependencies (@temporalio/client, worker, workflow, activity)
- Add shared types for pipeline state, metrics, and progress queries
- Add classifyErrorForTemporal() for retry behavior classification
- Add docker-compose for Temporal server with SQLite persistence

* feat: add Temporal activities for agent execution (phase 3)

- Add activities.ts with heartbeat loop, git checkpoint/rollback, and error classification
- Export runClaudePrompt, validateAgentOutput, ClaudePromptResult for Temporal use
- Track attempt number via Temporal Context for accurate audit logging
- Rollback git workspace before retry to ensure clean state

* feat: add Temporal workflow for 5-phase pipeline orchestration (phase 4)

* feat: add Temporal worker, client, and query tools (phase 5)

- Add worker.ts with workflow bundling and graceful shutdown
- Add client.ts CLI to start pipelines with progress polling
- Add query.ts CLI to inspect running workflow state
- Fix buffer overflow by truncating error messages and stack traces
- Skip git operations gracefully on non-git repositories
- Add kill.sh/start.sh dev scripts and Dockerfile.worker

* feat: fix Docker worker container setup

- Install uv instead of deprecated uvx package
- Add mcp-server and configs directories to container
- Mount target repo dynamically via TARGET_REPO env variable

* fix: add report assembly step to Temporal workflow

- Add assembleReportActivity to concatenate exploitation evidence files before report agent runs
- Call assembleFinalReport in workflow Phase 5 before runReportAgent
- Ensure deliverables directory exists before writing final report
- Simplify pipeline-testing report prompt to just prepend header

* refactor: consolidate Docker setup to root docker-compose.yml

* feat: improve Temporal client UX and env handling

- Change default to fire-and-forget (--wait flag to opt-in)
- Add splash screen and improve console output formatting
- Add .env to gitignore, remove from dockerignore for container access
- Add Taskfile for common development commands

* refactor: simplify session ID handling and improve Taskfile options

- Include hostname in workflow ID for better audit log organization
- Extract sanitizeHostname utility to audit/utils.ts for reuse
- Remove unused generateSessionLogPath and buildLogFilePath functions
- Simplify Taskfile with CONFIG/OUTPUT/CLEAN named parameters

* chore: add .env.example and simplify .gitignore

* docs: update README and CLAUDE.md for Temporal workflow usage

- Replace Docker CLI instructions with Task-based commands
- Add monitoring/stopping sections and workflow examples
- Document Temporal orchestration layer and troubleshooting
- Simplify file structure to key files overview

* refactor: replace Taskfile with bash CLI script

- Add shannon bash script with start/logs/query/stop/help commands
- Remove Taskfile.yml dependency (no longer requires Task installation)
- Update README.md and CLAUDE.md to use ./shannon commands
- Update client.ts output to show ./shannon commands

* docs: fix deliverable filename in README

* refactor: remove direct CLI and .shannon-store.json in favor of Temporal

- Delete src/shannon.ts direct CLI entry point (Temporal is now the only mode)
- Remove .shannon-store.json session lock (Temporal handles workflow deduplication)
- Remove broken scripts/export-metrics.js (imported non-existent function)
- Update package.json to remove main, start script, and bin entry
- Clean up CLAUDE.md and debug.md to remove obsolete references

* chore: remove licensing comments from prompt files to prevent leaking into actual prompts

* fix: resolve parallel workflow race conditions and retry logic bugs

- Fix save_deliverable race condition using closure pattern instead of global variable
- Fix error classification order so OutputValidationError matches before generic validation
- Fix ApplicationFailure re-classification bug by checking instanceof before re-throwing
- Add per-error-type retry limits (3 for output validation, 50 for billing)
- Add fast retry intervals for pipeline testing mode (10s vs 5min)
- Increase worker concurrent activities to 25 for parallel workflows

* refactor: pipeline vuln→exploit workflow for parallel execution

- Replace sync barrier between vuln/exploit phases with independent pipelines
- Each vuln type runs: vuln agent → queue check → conditional exploit
- Add checkExploitationQueue activity to skip exploits when no vulns found
- Use Promise.allSettled for graceful failure handling across pipelines
- Add PipelineSummary type for aggregated cost/duration/turns metrics

* fix: re-throw retryable errors in checkExploitationQueue

* fix: detect and retry on Claude Code spending cap errors

- Add spending cap pattern detection in detectApiError() with retryable error
- Add matching patterns to classifyErrorForTemporal() for proper Temporal retry
- Add defense-in-depth safeguard in runClaudePrompt() for $0 cost / low turn detection
- Add final sanity check in activities before declaring success

* fix: increase heartbeat timeout to prevent false worker-dead detection

Original 30s timeout was from POC spec assuming <5min activities. With
hour-long activities and multiple concurrent workflows sharing one worker,
resource contention causes event loop stalls exceeding 30s, triggering
false heartbeat timeouts. Increased to 10min (prod) and 5min (testing).

* fix: temporal db init

* fix: persist home dir

* feat: add per-workflow unified logging with ./shannon logs ID=<workflow-id>

- Add WorkflowLogger class for human-readable, per-workflow log files
- Create workflow.log in audit-logs/{workflowId}/ with phase, agent, tool, and LLM events
- Update ./shannon logs to require ID param and tail specific workflow log
- Add phase transition logging at workflow boundaries
- Include workflow completion summary with agent breakdown (duration, cost)
- Mount audit-logs volume in docker-compose for host access

---------

Co-authored-by: ezl-keygraph <ezhil@keygraph.io>
2026-01-15 10:36:11 -08:00
ezl-keygraph 45acb16711 refactor: remove orchestration layer (#45)
* refactor: remove orchestration layer and simplify CLI

Remove the complex orchestration layer including checkpoint management,
rollback/recovery commands, and session management commands. This
consolidates the execution logic directly in shannon.ts for a simpler
fire-and-forget execution model.

Changes:
- Remove checkpoint-manager.ts and rollback functionality
- Remove command-handler.ts and cli/prompts.ts
- Simplify session-manager.ts to just agent definitions
- Consolidate orchestration logic in shannon.ts
- Update CLAUDE.md documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: move session lock logic to shannon.ts, simplify session-manager

- Reduce session-manager.ts to only AGENTS, AGENT_ORDER, getParallelGroups()
- Move Session interface and lock file functions to shannon.ts
- Simplify Session to only: id, webUrl, repoPath, status, startedAt
- Remove unused types/session.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: use crypto.randomUUID() for session ID generation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 22:58:17 +05:30
ezl-keygraph 3ac07a4718 feat: typescript migration (#40)
* chore: initialize TypeScript configuration and build setup

- Add tsconfig.json for root and mcp-server with strict type checking
- Install typescript and @types/node as devDependencies
- Add npm build script for TypeScript compilation
- Update main entrypoint to compiled dist/shannon.js
- Update Dockerfile to build TypeScript before running
- Configure output directory and module resolution for Node.js

* refactor: migrate codebase from JavaScript to TypeScript

- Convert all 37 JavaScript files to TypeScript (.js -> .ts)
- Add type definitions in src/types/ for agents, config, errors, session
- Update mcp-server with proper TypeScript types
- Move entry point from shannon.mjs to src/shannon.ts
- Update tsconfig.json with rootDir: "./src" for cleaner dist output
- Update Dockerfile to build TypeScript before runtime
- Update package.json paths to use compiled dist/shannon.js

No runtime behavior changes - pure type safety migration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: update CLI references from ./shannon.mjs to shannon

- Update help text in src/cli/ui.ts
- Update usage examples in src/cli/command-handler.ts
- Update setup message in src/shannon.ts
- Update CLAUDE.md documentation with TypeScript file structure
- Replace all ./shannon.mjs references with shannon command

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: remove unnecessary eslint-disable comments

ESLint is not configured in this project, making these comments redundant.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 00:18:25 +05:30