Documentation
¶
Index ¶
- Constants
- Variables
- func ADRDir(baseDir string) string
- func AllowedToolsForMode(mode domain.TrackingMode) []string
- func ArchitectDiscussFileName(wave domain.Wave) string
- func BuildApprover(cfg domain.ApproverConfig, input io.Reader, promptOut io.Writer) port.Approver
- func BuildNextGenPrompt(cfg *domain.Config, scanDir string, completedWave domain.Wave, ...) (string, error)
- func BuildNotifier(gate domain.GateConfig) port.Notifier
- func BuildReviewFixPrompt(branch string, comments string) string
- func CanResume(baseDir string, state *domain.SessionState) bool
- func Center(s string, width int) string
- func CheckConfig(configPath string) domain.DoctorCheck
- func CheckContextBudget(streamJSON string, baseDir string) domain.DoctorCheck
- func CheckEventStore(baseDir string) domain.DoctorCheck
- func CheckSkills(baseDir string) domain.DoctorCheck
- func CheckStateDir(baseDir string, repair bool) domain.DoctorCheck
- func CheckTool(ctx context.Context, name string) domain.DoctorCheck
- func ClaudeSettingsExists(baseDir string) bool
- func ClaudeSettingsPath(baseDir string) string
- func ClearArchitectOutput(scanDir string, wave domain.Wave)
- func ClearNextgenOutput(scanDir string, wave domain.Wave)
- func ClearScribeOutput(scanDir string, wave domain.Wave)
- func ClusterLabel(name string, issueCount int, completeness float64, maxWidth int) string
- func CompletedWaves(waves []domain.Wave) []domain.Wave
- func ComposeDMail(ctx context.Context, store port.OutboxStore, mail *DMail) error
- func ComposeFeedback(ctx context.Context, store port.OutboxStore, wave domain.Wave, ...) error
- func ComposeReport(ctx context.Context, store port.OutboxStore, wave domain.Wave, ...) error
- func ComposeSpecification(ctx context.Context, store port.OutboxStore, wave domain.Wave, ...) error
- func ComposeStallEscalation(ctx context.Context, store port.OutboxStore, wave domain.Wave, errors []string, ...) error
- func CountADRFiles(adrDir string) int
- func DMailIdempotencyKey(mail *DMail) string
- func DMailName(prefix, waveKey string) string
- func DeleteArchiveFiles(baseDir string, files []string) ([]string, error)
- func DisplayADRConflicts(w io.Writer, conflicts []domain.ADRConflict)
- func DisplayArchitectResponse(w io.Writer, resp *domain.ArchitectResponse)
- func DisplayCompletedWaveActions(w io.Writer, wave domain.Wave)
- func DisplayRippleEffects(w io.Writer, ripples []domain.Ripple)
- func DisplayScribeResponse(w io.Writer, resp *domain.ScribeResponse)
- func DisplayShibitoWarnings(w io.Writer, warnings []domain.ShibitoWarning)
- func DisplayWaveCompletion(w io.Writer, wave domain.Wave, ripples []domain.Ripple, ...)
- func DisplayWidth(s string) int
- func EnsureMailDirs(baseDir string) error
- func EnsureRunDir(stateDir string) error
- func EnsureScanDir(baseDir, sessionID string) (string, error)
- func EnterSession(ctx context.Context, cfg EnterConfig) error
- func EventStorePath(baseDir, sessionID string) string
- func ExtractMeta(filePath, stateDir, tool string) domain.IndexEntry
- func ExtractStreamResult(streamJSON string) string
- func ExtractSummary(filePath string) string
- func FeedbackBody(wave domain.Wave, result *domain.WaveApplyResult) string
- func FormatADRConflictSection(resp *domain.ScribeResponse) string
- func FormatFeedbackForPrompt(feedback []*DMail) string
- func FormatReportsForPrompt(reports []*DMail) string
- func GenerateClaudeSettings(baseDir string, force bool) (string, error)
- func GenerateMCPConfig(baseDir string, mode domain.TrackingMode, force bool) (string, error)
- func GenerateNextWaves(ctx context.Context, cfg *domain.Config, scanDir string, ...) ([]domain.Wave, error)
- func GenerateNextWavesDryRun(cfg *domain.Config, scanDir string, completedWave domain.Wave, ...) error
- func InstallSkills(baseDir string, skillsFS fs.FS, logger domain.Logger) error
- func ListDMail(baseDir, sub string) ([]string, error)
- func ListExpiredArchive(baseDir string, days int, logger domain.Logger) ([]string, error)
- func ListExpiredEventFiles(ctx context.Context, baseDir string, days int) ([]string, error)
- func LoadAllEvents(ctx context.Context, baseDir string) ([]domain.Event, error)
- func LoadConfig(path string) (*domain.Config, error)
- func LoadLatestResumableState(ctx context.Context, baseDir string, match func(*domain.SessionState) bool) (*domain.SessionState, string, error)
- func LoadLatestState(ctx context.Context, baseDir string) (*domain.SessionState, string, error)
- func LoadScanResult(path string) (*domain.ScanResult, error)
- func MCPConfigExists(baseDir string) (bool, error)
- func MCPConfigPath(baseDir string) string
- func MarshalDMail(mail *DMail) ([]byte, error)
- func MergeScanResults(clusters []domain.ClusterScanResult, shibitoWarnings []domain.ShibitoWarning, ...) domain.ScanResult
- func MonitorInbox(ctx context.Context, baseDir string, logger domain.Logger) (<-chan *DMail, error)
- func NeedsMoreWaves(cluster domain.ClusterScanResult, waves []domain.Wave) bool
- func NewBranchResolver() port.BranchResolver
- func NewEventStore(stateDir string, logger domain.Logger) port.EventStore
- func NewOnceRunner(cfg *domain.Config, baseDir string, logger domain.Logger) port.ClaudeRunner
- func NewReviewExecutor(dir string) port.ReviewExecutor
- func NewReviewFixRunner(runner port.ClaudeRunner, branch port.BranchResolver, dir string, ...) port.ReviewFixRunner
- func NewSessionRecorder(stateDir, sessionID string, logger domain.Logger) (port.Recorder, error)
- func NewSpanEventStore(inner port.EventStore) port.EventStore
- func NewTrackedRunner(cfg *domain.Config, baseDir string, logger domain.Logger) port.ClaudeRunner
- func NextADRNumber(adrDir string) (int, error)
- func NextgenFileName(wave domain.Wave) string
- func NormalizeJSONFile(path string) error
- func NormalizeScribeResult(result *domain.ScribeResponse, adrID string, logger domain.Logger)
- func OverrideFindSkillsRefDir(fn func(string) string) func()
- func OverrideGenerateSkills(fn func(string, domain.Logger) error) func()
- func OverrideInstallSkillsRef(fn func() error) func()
- func OverrideLookPath(fn func(cmd string) (string, error)) func()
- func OverrideNewCmd(fn func(ctx context.Context, name string, args ...string) *exec.Cmd) func()
- func PadRight(s string, width int) string
- func ParseArchitectResult(path string) (*domain.ArchitectResponse, error)
- func ParseClassifyResult(path string) (*domain.ClassifyResult, error)
- func ParseClusterScanResult(path string) (*domain.ClusterScanResult, error)
- func ParseNextGenResult(path string) (*domain.NextGenResult, error)
- func ParseScribeResult(path string) (*domain.ScribeResponse, error)
- func ParseWaveApplyResult(path string) (*domain.WaveApplyResult, error)
- func ParseWaveGenerateResult(path string) (*domain.WaveGenerateResult, error)
- func PreflightCheck(binaries ...string) error
- func PromptCompletedWaveSelection(ctx context.Context, w io.Writer, s *bufio.Scanner, completed []domain.Wave) (domain.Wave, error)
- func PromptDiscussTopic(ctx context.Context, w io.Writer, s *bufio.Scanner) (string, error)
- func PromptResume(ctx context.Context, w io.Writer, s *bufio.Scanner, baseDir string, ...) (domain.ResumeChoice, error)
- func PromptSelectiveApproval(ctx context.Context, w io.Writer, s *bufio.Scanner, wave domain.Wave) ([]domain.WaveAction, []domain.WaveAction, error)
- func PromptWaveApproval(ctx context.Context, w io.Writer, s *bufio.Scanner, wave domain.Wave) (domain.ApprovalChoice, error)
- func PromptWaveSelection(ctx context.Context, w io.Writer, s *bufio.Scanner, waves []domain.Wave) (domain.Wave, error)
- func PruneArchive(baseDir string, days int, logger domain.Logger) ([]string, error)
- func PruneEventFiles(ctx context.Context, baseDir string, files []string) ([]string, error)
- func PruneFlushedOutbox(ctx context.Context, baseDir string) (int, error)
- func ReadCLAUDEMD(scanDir string) string
- func ReadExistingADRs(adrDir string) ([]domain.ExistingADR, error)
- func ReadyIssueIDs(waves []domain.Wave) []string
- func RecordScanState(baseDir, sessionID string, result *domain.ScanResult, cfg *domain.Config, ...) string
- func RenderADRFromDiscuss(dr domain.DiscussResult, adrNum int) string
- func RenderMatrixNavigator(result *domain.ScanResult, projectName string, waves []domain.Wave, ...) string
- func RenderNavigator(result *domain.ScanResult, projectName string) string
- func RenderProgressBar(current float64, width int) string
- func ReportBody(wave domain.Wave, result *domain.WaveApplyResult) string
- func RescanCore(ctx context.Context, cfg *domain.Config, baseDir, sessionID string, ...) (scanDir, scanResultPath string, scanResult *domain.ScanResult, ...)
- func ResolveMCPConfigPath(baseDir string) string
- func ResumeScanDir(state *domain.SessionState, baseDir string) string
- func ResumeSession(baseDir string, state *domain.SessionState) (*domain.ScanResult, []domain.Wave, map[string]bool, int, error)
- func RunArchitectDiscuss(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, ...) (*domain.ArchitectResponse, error)
- func RunArchitectDiscussDryRun(cfg *domain.Config, scanDir string, wave domain.Wave, topic string, ...) error
- func RunAutoDiscuss(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, ...) (*domain.AutoDiscussResult, error)
- func RunClaudeDryRun(cfg *domain.Config, prompt, outputPath string, name string, ...) error
- func RunConvergenceGate(ctx context.Context, dmails []*DMail, notifier port.Notifier, ...) (bool, error)
- func RunDoctor(ctx context.Context, configPath string, baseDir string, logger domain.Logger, ...) []domain.DoctorCheck
- func RunParallel[I, R any](ctx context.Context, items []I, concurrency int, ...) ([]R, []string)
- func RunParallelDeepScan(ctx context.Context, cfg *domain.Config, scanDir string, ...) ([]domain.ClusterScanResult, []string)
- func RunReadyLabel(ctx context.Context, cfg *domain.Config, readyIssueIDs string, out io.Writer, ...) error
- func RunRescanSession(ctx context.Context, cfg *domain.Config, baseDir string, ...) error
- func RunResumeSession(ctx context.Context, cfg *domain.Config, baseDir string, ...) error
- func RunReview(ctx context.Context, reviewCmd string, dir string) (*domain.ReviewResult, error)
- func RunReviewGate(ctx context.Context, gate domain.GateConfig, cfg *domain.Config, ...) (bool, error)
- func RunScan(ctx context.Context, cfg *domain.Config, baseDir string, sessionID string, ...) (*domain.ScanResult, error)
- func RunScribeADR(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, ...) (*domain.ScribeResponse, error)
- func RunScribeADRDryRun(cfg *domain.Config, scanDir string, wave domain.Wave, ...) error
- func RunSession(ctx context.Context, cfg *domain.Config, baseDir string, sessionID string, ...) error
- func RunWaveApply(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, ...) (*domain.WaveApplyResult, error)
- func RunWaveGenerate(ctx context.Context, cfg *domain.Config, scanDir string, ...) ([]domain.Wave, []string, map[string]bool, error)
- func SanitizeADRTitle(title string) string
- func ScanLine(ctx context.Context, s *bufio.Scanner) (string, error)
- func ScribeFileName(wave domain.Wave) string
- func SessionEventsDir(baseDir, sessionID string) string
- func SetCircuitBreaker(cb *platform.CircuitBreaker)
- func ShellQuote(s string) string
- func ShellQuoteCmd(s string) string
- func ShellQuoteUnix(s string) string
- func SpecificationBody(wave domain.Wave) string
- func Status(ctx context.Context, baseDir string) domain.StatusReport
- func SupersedeADR(adrPath, supersededBy string) error
- func ToApplyResult(wave domain.Wave, internal *domain.WaveApplyResult) domain.ApplyResult
- func ToDiscussResult(wave domain.Wave, resp *domain.ArchitectResponse, topic string) domain.DiscussResult
- func Truncate(s string, maxWidth int) string
- func TryLockDaemon(stateDir string) (func(), error)
- func UpdateConfig(path string, key string, value string) error
- func ValidateDMail(mail *DMail) error
- func WaveApplyFileName(wave domain.Wave) string
- func WaveIssueIDs(wave domain.Wave) []string
- func WriteClaudeLog(baseDir string, rawEvents []string) error
- func WriteEstimatedStrictness(path string, estimated map[string]domain.StrictnessLevel) error
- func WriteGitIgnore(baseDir string) error
- func WriteScanResult(path string, result *domain.ScanResult) error
- func WriteShibitoInsights(w *InsightWriter, warnings []domain.ShibitoWarning, sessionID string, ...)
- func WriteStrictnessInsights(w *InsightWriter, clusters []domain.ClusterScanResult, sessionID string, ...)
- type ClaudeAdapter
- type CmdApprover
- type CmdNotifier
- type DMail
- func DrainInboxFeedback(ch <-chan *DMail, logger domain.Logger) []*DMail
- func FilterConvergence(dmails []*DMail) []*DMail
- func ParseDMail(data []byte) (*DMail, error)
- func ReceiveDMail(baseDir, filename string) (*DMail, error)
- func RunConvergenceGateWithRedrain(ctx context.Context, initial []*DMail, inboxCh <-chan *DMail, ...) (dmails []*DMail, approved bool, err error)
- type DMailKind
- type DeepScanFunc
- type DispatchingRecorder
- type EnterConfig
- type FeedbackCollector
- func (c *FeedbackCollector) All() []*DMail
- func (c *FeedbackCollector) ConvergenceNames() []string
- func (c *FeedbackCollector) FeedbackOnly() []*DMail
- func (c *FeedbackCollector) NewSinceSnapshot() []*DMail
- func (c *FeedbackCollector) NotifyCh() <-chan struct{}
- func (c *FeedbackCollector) ReportsOnly() []*DMail
- func (c *FeedbackCollector) Snapshot()
- type FileHandoverWriter
- type IndexWriter
- type InitAdapter
- type InsightWriter
- type LocalNotifier
- type LoggingRecorder
- type MCPConfig
- type MCPServerEntry
- type RecorderFactoryAdapter
- func (f *RecorderFactoryAdapter) NewEventStore(stateDir string, logger domain.Logger) port.EventStore
- func (f *RecorderFactoryAdapter) NewSessionRecorder(stateDir, sessionID string, logger domain.Logger) (port.Recorder, error)
- func (f *RecorderFactoryAdapter) SessionEventsDir(baseDir, sessionID string) string
- type RetryRunner
- type RunOption
- type SQLiteCodingSessionStore
- func (s *SQLiteCodingSessionStore) Close() error
- func (s *SQLiteCodingSessionStore) FindByProviderSessionID(ctx context.Context, provider domain.Provider, pid string) ([]domain.CodingSessionRecord, error)
- func (s *SQLiteCodingSessionStore) LatestByProviderSessionID(ctx context.Context, provider domain.Provider, pid string) (domain.CodingSessionRecord, error)
- func (s *SQLiteCodingSessionStore) List(ctx context.Context, opts port.ListSessionOpts) ([]domain.CodingSessionRecord, error)
- func (s *SQLiteCodingSessionStore) Load(ctx context.Context, id string) (domain.CodingSessionRecord, error)
- func (s *SQLiteCodingSessionStore) Save(ctx context.Context, record domain.CodingSessionRecord) error
- func (s *SQLiteCodingSessionStore) UpdateStatus(ctx context.Context, id string, status domain.SessionStatus, ...) error
- type SQLiteOutboxStore
- func (s *SQLiteOutboxStore) Close() error
- func (s *SQLiteOutboxStore) Flush(ctx context.Context) (int, error)
- func (s *SQLiteOutboxStore) IncrementalVacuum() error
- func (s *SQLiteOutboxStore) PruneFlushed(ctx context.Context) (int, error)
- func (s *SQLiteOutboxStore) Stage(ctx context.Context, name string, data []byte) error
- type ScanRunnerAdapter
- type SessionRunnerAdapter
- func (a *SessionRunnerAdapter) BuildNotifier(gate domain.GateConfig) port.Notifier
- func (a *SessionRunnerAdapter) NewDispatchingRecorder(inner port.Recorder, dispatcher port.EventDispatcher, logger domain.Logger) port.Recorder
- func (a *SessionRunnerAdapter) ReviewGateRunner() port.ReviewGateRunner
- func (a *SessionRunnerAdapter) RunRescanSession(ctx context.Context, cfg *domain.Config, baseDir string, ...) error
- func (a *SessionRunnerAdapter) RunResumeSession(ctx context.Context, cfg *domain.Config, baseDir string, ...) error
- func (a *SessionRunnerAdapter) RunSession(ctx context.Context, cfg *domain.Config, baseDir, sessionID string, ...) error
- func (a *SessionRunnerAdapter) SetReviewGateRunner(runner port.ReviewGateRunner)
- type SessionTrackingAdapter
- type SpanEventStore
- type StateLoaderAdapter
- func (l *StateLoaderAdapter) CanResume(baseDir string, state *domain.SessionState) bool
- func (l *StateLoaderAdapter) LoadLatestResumableState(ctx context.Context, baseDir string, match func(*domain.SessionState) bool) (*domain.SessionState, string, error)
- func (l *StateLoaderAdapter) LoadLatestState(ctx context.Context, baseDir string) (*domain.SessionState, string, error)
- type StdinApprover
Constants ¶
const ADRSubdir = "docs/adr"
const (
)
Variables ¶
var BaseAllowedTools = []string{
"Read",
"Write",
"Bash(ls:*)",
"Bash(wc:*)",
"Bash(find:*)",
"Bash(echo:*)",
"Bash(sort:*)",
"Bash(grep:*)",
"Bash(awk:*)",
"Bash(sed:*)",
"Bash(head:*)",
"Bash(cat:*)",
}
Base tools (e.g. filesystem access, basic bash) that are generally useful and safe to enable by default for most workflows.
var ErrSpecNoImplementationSteps = errors.New("spec: no implementation steps after filtering")
ErrSpecNoImplementationSteps indicates that a wave had no implementation-oriented actions after filtering issue-management types, so no spec D-Mail was generated.
var GHAllowedTools = []string{
"Bash(git:*)",
"Bash(gh:*)",
"WebFetch(domain:github.com)",
"WebFetch(domain:raw.githubusercontent.com)",
}
GitHub CLI tools (git, gh) and GitHub WebFetch tools that sightjack commonly uses for GitHub-related tasks.
var LinearMCPAllowedTools = []string{
"mcp__linear__list_issues",
"mcp__linear__get_issue",
"mcp__linear__create_issue",
"mcp__linear__update_issue",
"mcp__linear__list_issue_statuses",
"mcp__linear__get_issue_status",
"mcp__linear__list_issue_labels",
"mcp__linear__create_issue_label",
"mcp__linear__list_comments",
"mcp__linear__create_comment",
"mcp__linear__list_projects",
"mcp__linear__get_project",
"mcp__linear__save_project",
"mcp__linear__list_project_labels",
"mcp__linear__list_teams",
"mcp__linear__get_team",
"mcp__linear__list_users",
"mcp__linear__get_user",
"mcp__linear__list_cycles",
"mcp__linear__search_documentation",
}
LinearMCPAllowedTools lists the official Linear MCP server tools that sightjack needs. Passing this via WithAllowedTools prevents context explosion from unrelated plugins loading hundreds of tool definitions (see anthropics/claude-code#25857).
var WithAllowedTools = port.WithAllowedTools
WithAllowedTools restricts the tools available to the Claude model.
var WithConfigBase = port.WithConfigBase
WithConfigBase sets the base directory for resolving stateDir settings.
var WithWorkDir = port.WithWorkDir
WithWorkDir sets the working directory for the Claude subprocess.
Functions ¶
func AllowedToolsForMode ¶ added in v0.0.11
func AllowedToolsForMode(mode domain.TrackingMode) []string
AllowedToolsForMode returns the appropriate tool list based on tracking mode. Wave mode: base + GitHub tools only (no Linear MCP). Linear mode: base + GitHub + Linear MCP tools.
func ArchitectDiscussFileName ¶
ArchitectDiscussFileName returns the output filename for an architect discussion.
func BuildApprover ¶
BuildApprover creates the appropriate Approver based on config. Priority: AutoApprove → CmdApprover → StdinApprover.
func BuildNextGenPrompt ¶
func BuildNextGenPrompt(cfg *domain.Config, scanDir string, completedWave domain.Wave, cluster domain.ClusterScanResult, completedWaves []domain.Wave, existingADRs []domain.ExistingADR, rejectedActions []domain.WaveAction, strictness string, feedback []*DMail, reports []*DMail) (string, error)
BuildNextGenPrompt constructs the prompt for post-completion wave generation.
func BuildNotifier ¶
func BuildNotifier(gate domain.GateConfig) port.Notifier
BuildNotifier creates the appropriate Notifier based on config. If NotifyCmd is set, uses CmdNotifier. Otherwise uses LocalNotifier (OS-native).
func BuildReviewFixPrompt ¶
BuildReviewFixPrompt creates a focused prompt for fixing review comments.
func CanResume ¶
func CanResume(baseDir string, state *domain.SessionState) bool
CanResume checks whether a saved session state supports resumption. It returns false when the cached ScanResult path is empty (e.g. v0.4 state files) or the file no longer exists on disk. baseDir is used to resolve relative ScanResultPaths stored in newer events.
func CheckConfig ¶
func CheckConfig(configPath string) domain.DoctorCheck
CheckConfig validates that the config file exists and can be loaded.
func CheckContextBudget ¶ added in v0.0.5
func CheckContextBudget(streamJSON string, baseDir string) domain.DoctorCheck
CheckContextBudget parses stream-json output from a Claude CLI invocation and estimates context consumption by category.
func CheckEventStore ¶ added in v0.0.3
func CheckEventStore(baseDir string) domain.DoctorCheck
CheckEventStore validates the event store directory structure and JSONL integrity. Delegates to eventsource.ValidateStore for the actual file-level checks. Returns CheckSkip if the events directory does not exist yet.
func CheckSkills ¶
func CheckSkills(baseDir string) domain.DoctorCheck
CheckSkills verifies that SKILL.md files exist under .siren/skills/ and that their frontmatter contains a dmail-schema-version field.
func CheckStateDir ¶
func CheckStateDir(baseDir string, repair bool) domain.DoctorCheck
CheckStateDir verifies that the .siren/ state directory exists and is writable. When repair is true and the directory is missing, it creates the directory and returns CheckFixed.
func CheckTool ¶
func CheckTool(ctx context.Context, name string) domain.DoctorCheck
CheckTool verifies that a CLI tool is installed and executable. It runs `<tool> --version` to confirm functionality.
func ClaudeSettingsExists ¶ added in v0.0.12
ClaudeSettingsExists reports whether .claude/settings.json exists.
func ClaudeSettingsPath ¶ added in v0.0.12
ClaudeSettingsPath returns the path to the .claude/settings.json file under the tool state directory.
func ClearArchitectOutput ¶
ClearArchitectOutput removes any existing architect output file to prevent stale results from a prior discuss round being parsed if Claude fails to write a new file.
func ClearNextgenOutput ¶
ClearNextgenOutput removes any existing nextgen output file.
func ClearScribeOutput ¶
ClearScribeOutput removes any existing scribe output file to prevent stale results from a prior run being parsed if Claude fails to write a new file.
func ClusterLabel ¶ added in v0.0.11
ClusterLabel builds the display label for a cluster row in the matrix navigator. Shows "[ok]" for complete clusters (completeness >= 0.99 and zero issues).
func CompletedWaves ¶
CompletedWaves filters waves to only those with "completed" status.
func ComposeDMail ¶
ComposeDMail stages a d-mail via the transactional outbox store, then flushes it to archive/ and outbox/ using atomic file writes.
func ComposeFeedback ¶
func ComposeFeedback(ctx context.Context, store port.OutboxStore, wave domain.Wave, result *domain.WaveApplyResult) error
ComposeFeedback stages a report D-Mail for amadeus consumption. Called after successful wave apply to complete the sightjack → amadeus feedback loop (O2). Uses DMailReport kind because sightjack's sendable contract only produces specification and report.
func ComposeReport ¶
func ComposeReport(ctx context.Context, store port.OutboxStore, wave domain.Wave, result *domain.WaveApplyResult) error
ComposeReport creates and sends a report d-mail for a completed wave.
func ComposeSpecification ¶
func ComposeSpecification(ctx context.Context, store port.OutboxStore, wave domain.Wave, mode ...domain.TrackingMode) error
ComposeSpecification creates and sends a specification d-mail for an approved wave. In wave mode, issue management actions are filtered out — only implementation-oriented actions (implement, fix, verify, etc.) are included as steps. If no implementation actions remain, the spec D-Mail is not generated.
func ComposeStallEscalation ¶ added in v0.0.11
func ComposeStallEscalation(ctx context.Context, store port.OutboxStore, wave domain.Wave, errors []string, reason string) error
ComposeStallEscalation stages a stall-escalation D-Mail in the outbox. Called when a wave is detected as stalled due to repeated structural errors.
func CountADRFiles ¶
CountADRFiles returns the number of files matching NNNN-*.md in adrDir. Returns 0 if the directory is empty or does not exist.
func DMailIdempotencyKey ¶
DMailIdempotencyKey computes a SHA256 content-based idempotency key from the core fields of a DMail (name, kind, description, body).
func DMailName ¶
DMailName generates a collision-safe d-mail name with tool prefix and UUID suffix. Format: sj-{kind}-{sanitized-key}_{uuid8} Example: DMailName("spec", "error-handling:w1") → "sj-spec-error-handling-w1_a3f2b7c4"
func DeleteArchiveFiles ¶
DeleteArchiveFiles deletes the named files from .siren/archive/. Files that no longer exist are silently skipped (ErrNotExist is not an error). Returns the list of filenames that were processed.
func DisplayADRConflicts ¶
func DisplayADRConflicts(w io.Writer, conflicts []domain.ADRConflict)
DisplayADRConflicts shows potential conflicts between new and existing ADRs.
func DisplayArchitectResponse ¶
func DisplayArchitectResponse(w io.Writer, resp *domain.ArchitectResponse)
DisplayArchitectResponse shows the architect's analysis and any wave modifications.
func DisplayCompletedWaveActions ¶
DisplayCompletedWaveActions shows the actions that were applied in a completed wave.
func DisplayRippleEffects ¶
DisplayRippleEffects shows cross-cluster effects after a wave is applied.
func DisplayScribeResponse ¶
func DisplayScribeResponse(w io.Writer, resp *domain.ScribeResponse)
DisplayScribeResponse shows the scribe's ADR generation result.
func DisplayShibitoWarnings ¶
func DisplayShibitoWarnings(w io.Writer, warnings []domain.ShibitoWarning)
DisplayShibitoWarnings shows shibito resurrection detection warnings.
func DisplayWaveCompletion ¶
func DisplayWaveCompletion(w io.Writer, wave domain.Wave, ripples []domain.Ripple, overallCompleteness float64, newWavesAvailable int)
DisplayWaveCompletion shows a rich wave completion summary with grouped ripple effects.
func DisplayWidth ¶
func EnsureMailDirs ¶
EnsureMailDirs creates inbox/, outbox/, archive/ under .siren/.
func EnsureRunDir ¶ added in v0.0.10
EnsureRunDir creates the .run/ directory under stateDir if it does not exist. Call once before opening stores that write to .run/ (idempotent).
func EnsureScanDir ¶
EnsureScanDir creates the scan directory for a session and returns its path. It also writes .siren/.gitignore as a best-effort side effect.
func EnterSession ¶ added in v0.0.12
func EnterSession(ctx context.Context, cfg EnterConfig) error
EnterSession launches the provider CLI in interactive mode with --resume. stdin/stdout/stderr are connected to the user's TTY. This function does NOT use ClaudeAdapter — it hands control to the user's terminal.
func EventStorePath ¶
EventStorePath returns the filesystem path for a session's event store.
func ExtractMeta ¶ added in v0.0.8
func ExtractMeta(filePath, stateDir, tool string) domain.IndexEntry
ExtractMeta populates a domain.IndexEntry from a markdown file, extracting operation type, issue ID, status, timestamp, and summary.
func ExtractStreamResult ¶ added in v0.0.5
ExtractStreamResult parses stream-json output and returns the "result" field from the result message. Used to reuse inference check output for inference validation.
func ExtractSummary ¶ added in v0.0.8
ExtractSummary returns the first markdown heading (# ...) found after skipping optional YAML frontmatter. If no heading is found, it returns the first non-empty line. The result is truncated to maxSummaryLen characters.
func FeedbackBody ¶
func FeedbackBody(wave domain.Wave, result *domain.WaveApplyResult) string
FeedbackBody formats wave apply results as Markdown body for a feedback d-mail. Distinct from ReportBody: uses "Wave Feedback" heading to differentiate the sightjack → amadeus feedback loop (O2) from the standard report d-mail.
func FormatADRConflictSection ¶ added in v0.0.11
func FormatADRConflictSection(resp *domain.ScribeResponse) string
FormatADRConflictSection formats the conflicts from a ScribeResponse into a Markdown section suitable for appending to the ADR content. Returns an empty string if there are no conflicts.
func FormatFeedbackForPrompt ¶
FormatFeedbackForPrompt formats feedback d-mails as a Markdown section suitable for injection into wave generation prompts. HIGH severity items are emphasized with a ### [HIGH] header. Returns "" for nil or empty input.
func FormatReportsForPrompt ¶
FormatReportsForPrompt formats report d-mails as a Markdown section suitable for injection into wave generation prompts. Reports come from other tools (e.g. amadeus check results) and provide cross-tool context. Returns "" for nil or empty input.
func GenerateClaudeSettings ¶ added in v0.0.12
GenerateClaudeSettings creates a minimal .claude/settings.json that disables all plugins for Claude subprocess isolation.
func GenerateMCPConfig ¶ added in v0.0.12
GenerateMCPConfig creates a .mcp.json file. Linear mode includes Linear MCP server. Wave mode produces empty config. If a legacy .run/mcp-config.json exists and the new file does not, the legacy content is migrated forward to preserve custom MCP server entries.
func GenerateNextWaves ¶
func GenerateNextWaves(ctx context.Context, cfg *domain.Config, scanDir string, completedWave domain.Wave, cluster domain.ClusterScanResult, completedWaves []domain.Wave, existingADRs []domain.ExistingADR, rejectedActions []domain.WaveAction, strictness string, feedback []*DMail, reports []*DMail, runner port.ClaudeRunner, logger domain.Logger) ([]domain.Wave, error)
GenerateNextWaves executes post-completion wave generation for a cluster.
func GenerateNextWavesDryRun ¶
func GenerateNextWavesDryRun(cfg *domain.Config, scanDir string, completedWave domain.Wave, cluster domain.ClusterScanResult, completedWaves []domain.Wave, existingADRs []domain.ExistingADR, rejectedActions []domain.WaveAction, strictness string, feedback []*DMail, reports []*DMail, logger domain.Logger) error
GenerateNextWavesDryRun saves the nextgen prompt to a file instead of executing Claude.
func InstallSkills ¶
InstallSkills copies embedded skill templates into baseDir/.siren/skills/. Existing files are overwritten when content differs (idempotent). Directories are created as needed. Logs to logger when a file is updated.
func ListExpiredArchive ¶
ListExpiredArchive returns filenames in .siren/archive/ whose mtime exceeds the given number of days. Only .md files are considered. Returns an empty slice (not error) when the archive directory does not exist.
func ListExpiredEventFiles ¶
ListExpiredEventFiles returns event files older than the retention threshold.
func LoadAllEvents ¶
LoadAllEvents aggregates events from all session stores.
func LoadConfig ¶
LoadConfig reads a YAML config file and returns a Config with defaults applied for any fields not specified in the file.
func LoadLatestResumableState ¶
func LoadLatestResumableState(ctx context.Context, baseDir string, match func(*domain.SessionState) bool) (*domain.SessionState, string, error)
LoadLatestResumableState loads the latest session state that matches the predicate.
func LoadLatestState ¶
LoadLatestState loads the most recent session state from event data.
func LoadScanResult ¶
func LoadScanResult(path string) (*domain.ScanResult, error)
LoadScanResult reads a cached ScanResult from a JSON file.
func MCPConfigExists ¶ added in v0.0.12
MCPConfigExists reports whether the .mcp.json file exists and is valid JSON.
func MCPConfigPath ¶ added in v0.0.12
MCPConfigPath returns the path to the .mcp.json file.
func MarshalDMail ¶
MarshalDMail serializes a DMail to YAML frontmatter + Markdown body. Automatically injects an idempotency_key into metadata based on content hash.
func MergeScanResults ¶
func MergeScanResults(clusters []domain.ClusterScanResult, shibitoWarnings []domain.ShibitoWarning, scanWarnings []string) domain.ScanResult
MergeScanResults combines per-cluster deep scan results into a single domain.ScanResult. shibitoWarnings are propagated from the Pass 1 classify result.
func MonitorInbox ¶
MonitorInbox starts monitoring the inbox directory for feedback and convergence d-mails. It first drains existing files (initial scan), then watches for new files via fsnotify. Each d-mail is received (archived + removed from inbox). Feedback, convergence, and report d-mails are sent to the returned channel. Consumer-side dedup is applied (MY-271). The channel is closed when the context is cancelled.
func NeedsMoreWaves ¶
func NeedsMoreWaves(cluster domain.ClusterScanResult, waves []domain.Wave) bool
NeedsMoreWaves returns true when post-completion wave generation should run. Delegates to domain.NeedsMoreWaves.
func NewBranchResolver ¶ added in v0.0.11
func NewBranchResolver() port.BranchResolver
NewBranchResolver creates a BranchResolver.
func NewEventStore ¶
func NewEventStore(stateDir string, logger domain.Logger) port.EventStore
NewEventStore creates an event store rooted at stateDir. eventsource is the event persistence adapter (AWS Event Sourcing pattern). cmd layer should use this instead of importing eventsource directly (ADR S0008).
func NewOnceRunner ¶ added in v0.0.12
NewOnceRunner creates a provider-tracked runner WITHOUT retry. Use this for operations with side-effects that must not be retried (e.g. wave apply, classify with label mutations). baseDir is used to resolve the session tracking database path.
func NewReviewExecutor ¶ added in v0.0.11
func NewReviewExecutor(dir string) port.ReviewExecutor
NewReviewExecutor creates a ReviewExecutor for the given working directory.
func NewReviewFixRunner ¶ added in v0.0.11
func NewReviewFixRunner(runner port.ClaudeRunner, branch port.BranchResolver, dir string, logger domain.Logger) port.ReviewFixRunner
NewReviewFixRunner creates a ReviewFixRunner.
func NewSessionRecorder ¶
NewSessionRecorder creates a recorder for the given session.
func NewSpanEventStore ¶
func NewSpanEventStore(inner port.EventStore) port.EventStore
NewSpanEventStore creates a span-instrumented EventStore wrapper.
func NewTrackedRunner ¶ added in v0.0.12
NewTrackedRunner creates a provider-tracked runner with retry, session tracking, and circuit breaker protection. This is the standard way to create a runner for session-level operations that should be retried on transient failures. baseDir is used to resolve the session tracking database path.
func NextADRNumber ¶
NextADRNumber scans adrDir for files matching NNNN-*.md and returns max(NNNN)+1. Returns 1 if the directory is empty or does not exist.
func NextgenFileName ¶
NextgenFileName returns the output filename for a nextgen wave generation run.
func NormalizeJSONFile ¶
NormalizeJSONFile reads a JSON file, re-encodes it with raw UTF-8 (no \uXXXX for non-ASCII characters), and writes it back. This normalizes Claude's output so that human-readable characters (e.g. Japanese) appear as raw UTF-8 instead of escape sequences.
It also handles non-JSON text wrapping that Claude may produce: markdown code blocks (```json ... ```) and natural language prefixes/suffixes around JSON content.
func NormalizeScribeResult ¶
func NormalizeScribeResult(result *domain.ScribeResponse, adrID string, logger domain.Logger)
NormalizeScribeResult ensures the parsed ADRID matches the filesystem-derived adrID. Claude may return a mismatched or empty adr_id; the generated ID is authoritative because it is used to name the ADR file on disk.
func OverrideFindSkillsRefDir ¶ added in v0.0.7
OverrideFindSkillsRefDir replaces the skills-ref directory finder for testing.
func OverrideGenerateSkills ¶ added in v0.0.7
OverrideGenerateSkills replaces the skills generator for testing.
func OverrideInstallSkillsRef ¶ added in v0.0.7
func OverrideInstallSkillsRef(fn func() error) func()
OverrideInstallSkillsRef replaces the skills-ref installer for testing.
func OverrideLookPath ¶ added in v0.0.4
OverrideLookPath replaces the path lookup function for testing and returns a cleanup function.
func OverrideNewCmd ¶
OverrideNewCmd replaces the command constructor for testing and returns a cleanup function. Exported for cross-package test injection (root test suite).
func ParseArchitectResult ¶
func ParseArchitectResult(path string) (*domain.ArchitectResponse, error)
ParseArchitectResult reads and parses an architect response JSON file.
func ParseClassifyResult ¶
func ParseClassifyResult(path string) (*domain.ClassifyResult, error)
ParseClassifyResult reads and parses the classify.json output file.
func ParseClusterScanResult ¶
func ParseClusterScanResult(path string) (*domain.ClusterScanResult, error)
ParseClusterScanResult reads and parses a cluster_{name}.json output file.
func ParseNextGenResult ¶
func ParseNextGenResult(path string) (*domain.NextGenResult, error)
ParseNextGenResult reads and parses a nextgen wave generation result JSON file.
func ParseScribeResult ¶
func ParseScribeResult(path string) (*domain.ScribeResponse, error)
ParseScribeResult reads and parses a scribe response JSON file.
func ParseWaveApplyResult ¶
func ParseWaveApplyResult(path string) (*domain.WaveApplyResult, error)
ParseWaveApplyResult reads and parses an apply_{wave_id}.json output file.
func ParseWaveGenerateResult ¶
func ParseWaveGenerateResult(path string) (*domain.WaveGenerateResult, error)
ParseWaveGenerateResult reads and parses a wave_{name}.json output file.
func PreflightCheck ¶
PreflightCheck verifies that required binaries are available in PATH. Uses platform.LookPathShell which handles shell-aware lookups.
func PromptCompletedWaveSelection ¶
func PromptCompletedWaveSelection(ctx context.Context, w io.Writer, s *bufio.Scanner, completed []domain.Wave) (domain.Wave, error)
PromptCompletedWaveSelection displays completed waves and reads the user's choice.
func PromptDiscussTopic ¶
PromptDiscussTopic reads a free-text discussion topic from the user.
func PromptResume ¶
func PromptResume(ctx context.Context, w io.Writer, s *bufio.Scanner, baseDir string, state *domain.SessionState) (domain.ResumeChoice, error)
PromptResume displays previous session info and asks the user to resume, start new, or re-scan.
func PromptSelectiveApproval ¶
func PromptSelectiveApproval(ctx context.Context, w io.Writer, s *bufio.Scanner, wave domain.Wave) ([]domain.WaveAction, []domain.WaveAction, error)
PromptSelectiveApproval displays wave actions with toggle checkboxes. Returns approved and rejected action lists.
func PromptWaveApproval ¶
func PromptWaveApproval(ctx context.Context, w io.Writer, s *bufio.Scanner, wave domain.Wave) (domain.ApprovalChoice, error)
PromptWaveApproval displays a wave proposal and reads approve/reject/discuss.
func PromptWaveSelection ¶
func PromptWaveSelection(ctx context.Context, w io.Writer, s *bufio.Scanner, waves []domain.Wave) (domain.Wave, error)
PromptWaveSelection displays available waves and reads the user's choice.
func PruneArchive ¶
PruneArchive deletes expired .md files from .siren/archive/ and returns the list of deleted filenames. Uses the same criteria as ListExpiredArchive. Returns an empty slice (not error) when the archive directory does not exist.
func PruneEventFiles ¶
PruneEventFiles deletes the specified event files.
func PruneFlushedOutbox ¶
PruneFlushedOutbox opens the outbox DB, deletes flushed rows, runs incremental vacuum, and closes the store. Returns 0 if the DB does not exist.
func ReadCLAUDEMD ¶ added in v0.0.3
ReadCLAUDEMD searches for CLAUDE.md starting from scanDir and walking up to 3 levels. Returns empty string if not found.
func ReadExistingADRs ¶
func ReadExistingADRs(adrDir string) ([]domain.ExistingADR, error)
ReadExistingADRs reads all NNNN-*.md files from adrDir and returns their content. Returns empty slice if directory doesn't exist or is empty.
func ReadyIssueIDs ¶
ReadyIssueIDs returns issue IDs where ALL waves targeting them are completed. Delegates to domain.ReadyIssueIDs.
func RecordScanState ¶
func RecordScanState(baseDir, sessionID string, result *domain.ScanResult, cfg *domain.Config, emitter port.SessionEventEmitter, scanTime time.Time, logger domain.Logger) string
RecordScanState caches the scan result and records session start + scan completed events via the SessionAggregate. This is the single authoritative path for scan state persistence — both the scan command and the run session converge here.
Returns the cached scan result path for downstream use (e.g. interactive loop).
func RenderADRFromDiscuss ¶
func RenderADRFromDiscuss(dr domain.DiscussResult, adrNum int) string
RenderADRFromDiscuss generates an ADR Markdown document from a domain.DiscussResult. This is a pure transformer — no Claude invocation needed.
func RenderMatrixNavigator ¶
func RenderMatrixNavigator(result *domain.ScanResult, projectName string, waves []domain.Wave, adrCount int, lastScanned *time.Time, strictnessLevel string, shibitoCount int) string
RenderMatrixNavigator renders the Link Navigator as a Pure ASCII matrix grid. Wave status symbols: [ ] available [x] locked [=] completed [?] unknown
func RenderNavigator ¶
func RenderNavigator(result *domain.ScanResult, projectName string) string
RenderNavigator produces an ASCII Link Navigator display inspired by the PS2 game SIREN's sight-jack interface. It visualises cluster completeness in a fixed-width text matrix.
func RenderProgressBar ¶
RenderProgressBar produces an ASCII progress bar: [====....] NN%
func ReportBody ¶
func ReportBody(wave domain.Wave, result *domain.WaveApplyResult) string
ReportBody formats wave apply results as Markdown body for a report d-mail.
func RescanCore ¶ added in v0.0.12
func RescanCore(ctx context.Context, cfg *domain.Config, baseDir, sessionID string, oldWaves []domain.Wave, oldCompleted map[string]bool, runner port.ClaudeRunner, onceRunner port.ClaudeRunner, emitter port.SessionEventEmitter, out io.Writer, logger domain.Logger, ) (scanDir, scanResultPath string, scanResult *domain.ScanResult, waves []domain.Wave, completed map[string]bool, adrCount int, scanTime time.Time, err error)
RescanCore performs the scan+wavegen+merge cycle without session setup (D-Mail monitoring, convergence gate, outbox). It is the reusable core shared by RunRescanSession (cmd-layer rescan) and the in-loop auto-rescan triggered by design-feedback D-Mail arrival.
func ResolveMCPConfigPath ¶ added in v0.0.12
ResolveMCPConfigPath returns the active MCP config path, preferring the new .mcp.json location and falling back to the legacy .run/mcp-config.json.
func ResumeScanDir ¶
func ResumeScanDir(state *domain.SessionState, baseDir string) string
ResumeScanDir returns the scan directory for a resumed session. It derives the directory from state.ScanResultPath when available, preserving the original path even if the directory layout has changed (e.g. .siren/scans/ → .siren/.run/). Falls back to ScanDir() when ScanResultPath is empty.
func ResumeSession ¶
func ResumeSession(baseDir string, state *domain.SessionState) (*domain.ScanResult, []domain.Wave, map[string]bool, int, error)
ResumeSession loads a previous session's state and cached scan result, restoring waves and completed map for the interactive loop.
func RunArchitectDiscuss ¶
func RunArchitectDiscuss(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, topic string, strictness string, out io.Writer, runner port.ClaudeRunner, logger domain.Logger) (*domain.ArchitectResponse, error)
RunArchitectDiscuss executes a single-turn architect discussion via Claude subprocess.
func RunArchitectDiscussDryRun ¶
func RunArchitectDiscussDryRun(cfg *domain.Config, scanDir string, wave domain.Wave, topic string, strictness string, logger domain.Logger) error
RunArchitectDiscussDryRun saves the architect prompt to a file instead of executing Claude.
func RunAutoDiscuss ¶ added in v0.0.3
func RunAutoDiscuss(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, feedback []*DMail, adrDir string, strictness string, out io.Writer, runner port.ClaudeRunner, logger domain.Logger) (*domain.AutoDiscussResult, error)
RunAutoDiscuss orchestrates the Devil's Advocate debate for auto-approve mode. Returns nil result (not error) when auto_discuss_rounds is 0.
func RunClaudeDryRun ¶
func RunClaudeDryRun(cfg *domain.Config, prompt, outputPath string, name string, logger domain.Logger) error
RunClaudeDryRun saves the prompt to a file instead of executing the provider CLI, useful for previewing what would be sent. The name parameter makes each prompt file unique within the output directory (e.g. "classify", "wave_00_auth").
func RunConvergenceGate ¶
func RunConvergenceGate(ctx context.Context, dmails []*DMail, notifier port.Notifier, approver port.Approver, logger domain.Logger) (bool, error)
RunConvergenceGate checks for convergence D-Mails and runs the notify + approve flow. Returns true if approved or no convergence found. Returns false if denied. Returns error on failure (fail-closed).
func RunDoctor ¶
func RunDoctor(ctx context.Context, configPath string, baseDir string, logger domain.Logger, repair bool, mode domain.TrackingMode) []domain.DoctorCheck
RunDoctor executes all health checks and returns the results. The configPath is loaded to obtain tool configuration; if loading fails the config check reports failure but other checks continue where possible. baseDir is used to verify the .siren/ state directory is writable.
func RunParallel ¶
func RunParallel[I, R any]( ctx context.Context, items []I, concurrency int, work func(ctx context.Context, index int, item I) (R, error), itemName func(I) string, logger domain.Logger, ) ([]R, []string)
RunParallel executes work for each item with bounded concurrency using a pond worker pool. Failed items produce warnings and are skipped; successful results are returned in the original item order.
Panics inside work are recovered and converted to warnings (no deadlock).
func RunParallelDeepScan ¶
func RunParallelDeepScan(ctx context.Context, cfg *domain.Config, scanDir string, clusters []domain.ClusterScanResult, scanFn DeepScanFunc, logger domain.Logger) ([]domain.ClusterScanResult, []string)
RunParallelDeepScan executes deep scan across clusters with bounded concurrency. Delegates to RunParallel for pond-based parallel orchestration. Failed clusters produce warnings and are skipped; successful results preserve order.
func RunReadyLabel ¶
func RunReadyLabel(ctx context.Context, cfg *domain.Config, readyIssueIDs string, out io.Writer, runner port.ClaudeRunner, logger domain.Logger) error
RunReadyLabel applies the ready label to issues whose all waves have completed. This must only be called after a successful wave apply.
func RunRescanSession ¶
func RunRescanSession(ctx context.Context, cfg *domain.Config, baseDir string, oldState *domain.SessionState, sessionID string, input io.Reader, out io.Writer, emitter port.SessionEventEmitter, logger domain.Logger) error
RunRescanSession performs a fresh scan then merges completed status from old state.
func RunResumeSession ¶
func RunResumeSession(ctx context.Context, cfg *domain.Config, baseDir string, state *domain.SessionState, input io.Reader, out io.Writer, emitter port.SessionEventEmitter, logger domain.Logger) error
RunResumeSession resumes an existing session from saved state.
func RunReviewGate ¶
func RunReviewGate(ctx context.Context, gate domain.GateConfig, cfg *domain.Config, runner port.ClaudeRunner, dir string, logger domain.Logger, reviewGate ...port.ReviewGateRunner) (bool, error)
RunReviewGate runs the review-fix cycle with OTel spans. When a ReviewGateRunner is provided (variadic), delegates cycle control to it. Otherwise runs cycle control inline (backward compatibility for integration tests).
func RunScan ¶
func RunScan(ctx context.Context, cfg *domain.Config, baseDir string, sessionID string, dryRun bool, out io.Writer, runner port.ClaudeRunner, onceRunner port.ClaudeRunner, logger domain.Logger) (*domain.ScanResult, error)
RunScan executes the full two-pass scan. Pass 1: Classify all issues into clusters. Pass 2: Deep scan each cluster in parallel.
func RunScribeADR ¶
func RunScribeADR(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, architectResp *domain.ArchitectResponse, adrDir string, strictness string, out io.Writer, runner port.ClaudeRunner, logger domain.Logger) (*domain.ScribeResponse, error)
RunScribeADR executes the Scribe Agent via Claude subprocess to generate an ADR.
func RunScribeADRDryRun ¶
func RunScribeADRDryRun(cfg *domain.Config, scanDir string, wave domain.Wave, architectResp *domain.ArchitectResponse, adrDir string, strictness string, logger domain.Logger) error
RunScribeADRDryRun saves the scribe prompt to a file instead of executing Claude.
func RunSession ¶
func RunSession(ctx context.Context, cfg *domain.Config, baseDir string, sessionID string, dryRun bool, input io.Reader, out io.Writer, emitter port.SessionEventEmitter, logger domain.Logger) error
RunSession runs the full session: Pass 1-3 (auto), then interactive wave loop.
func RunWaveApply ¶
func RunWaveApply(ctx context.Context, cfg *domain.Config, scanDir string, wave domain.Wave, strictness string, out io.Writer, runner port.ClaudeRunner, logger domain.Logger) (*domain.WaveApplyResult, error)
RunWaveApply executes Pass 4: apply a single approved wave via Claude Code. It writes the apply result to a JSON file and returns the parsed result.
func RunWaveGenerate ¶
func RunWaveGenerate(ctx context.Context, cfg *domain.Config, scanDir string, clusters []domain.ClusterScanResult, dryRun bool, runner port.ClaudeRunner, logger domain.Logger, extraPROpenIssues ...map[string]bool) ([]domain.Wave, []string, map[string]bool, error)
RunWaveGenerate executes Pass 3: generate waves for each cluster in parallel. Failed clusters are skipped with warnings (partial success), matching the fault-tolerance pattern of RunParallelDeepScan. Returns an error only when ALL clusters fail. RunWaveGenerate generates waves for all clusters. Optional extraPROpenIssues provides session-level knowledge of issues with spec D-Mails already sent (covers the race window before paintress applies the pr-open label).
func SanitizeADRTitle ¶
SanitizeADRTitle ensures an ADR title is safe for use in filenames. Prevents path traversal by stripping everything except [a-z0-9-_]. Returns "untitled" for empty input.
func ScanLine ¶
ScanLine reads one line from s, returning early if ctx is cancelled. The goroutine blocked on s.Scan() may outlive the call when the context fires first; this is acceptable for a CLI tool that exits shortly after.
func ScribeFileName ¶
ScribeFileName returns the output filename for a scribe run.
func SessionEventsDir ¶
SessionEventsDir returns the events directory for a specific session. Callers use this to compute the stateDir parameter for NewEventStore.
func SetCircuitBreaker ¶ added in v0.0.12
func SetCircuitBreaker(cb *platform.CircuitBreaker)
SetCircuitBreaker sets the process-wide circuit breaker for all provider calls. Call this once during startup before any provider invocations.
func ShellQuote ¶
ShellQuote quotes s for safe interpolation into shell commands. Uses single-quote escaping on Unix and double-quote escaping on Windows.
func ShellQuoteCmd ¶
ShellQuoteCmd wraps a string in double quotes with proper escaping for cmd.exe. Double quotes are escaped as "" and percent signs as %%.
func ShellQuoteUnix ¶
ShellQuoteUnix wraps a string in single quotes with proper escaping for sh. Single quotes within the string are escaped by ending the current quote, inserting an escaped single quote, and reopening the quote.
func SpecificationBody ¶
SpecificationBody formats wave actions as Markdown body for a specification d-mail.
func Status ¶
func Status(ctx context.Context, baseDir string) domain.StatusReport
Status collects current operational status from the event store and filesystem. baseDir is the repository root (e.g. the directory containing .siren/).
func SupersedeADR ¶ added in v0.0.11
SupersedeADR patches the **Status:** line of the ADR file at adrPath, replacing it with "Superseded by [supersededBy]". Returns an error if the file cannot be read/written or if no Status line is found.
func ToApplyResult ¶
func ToApplyResult(wave domain.Wave, internal *domain.WaveApplyResult) domain.ApplyResult
ToApplyResult converts the internal domain.WaveApplyResult to the pipe wire format domain.ApplyResult. Delegates to domain.ToApplyResult.
func ToDiscussResult ¶
func ToDiscussResult(wave domain.Wave, resp *domain.ArchitectResponse, topic string) domain.DiscussResult
ToDiscussResult converts an domain.ArchitectResponse to the pipe wire format domain.DiscussResult. It compares original and modified wave actions to build the modifications list, detecting changed, added, and removed actions.
func TryLockDaemon ¶ added in v0.0.12
TryLockDaemon acquires an exclusive advisory lock on daemon.lock in the given directory. If another process holds the lock, it returns an error immediately (LOCK_NB). The returned function releases the lock. The OS automatically releases the lock if the process crashes.
func UpdateConfig ¶ added in v0.0.3
UpdateConfig reads a config file, updates a single key, validates, and writes back. Supported keys: tracker.team, tracker.project, tracker.cycle, lang, strictness.default, scan.chunk_size, scan.max_concurrency, assistant.model, assistant.timeout_sec, gate.auto_approve, labels.enabled, labels.prefix, labels.ready_label.
func ValidateDMail ¶
ValidateDMail checks required fields and kind validity.
func WaveApplyFileName ¶
WaveApplyFileName returns the output filename for a wave apply result. Includes cluster name to avoid collisions when wave IDs are duplicated across clusters.
func WaveIssueIDs ¶
func WriteClaudeLog ¶ added in v0.0.12
WriteClaudeLog persists raw stream-json events to .run/claude-logs/.
func WriteEstimatedStrictness ¶ added in v0.0.3
func WriteEstimatedStrictness(path string, estimated map[string]domain.StrictnessLevel) error
WriteEstimatedStrictness reads the config, replaces the estimated strictness map, and writes back. Called after scan to persist LLM-estimated values.
func WriteGitIgnore ¶
WriteGitIgnore ensures a .gitignore inside .siren/ excludes ephemeral files from version control. Uses append-only pattern: existing user entries are preserved.
func WriteScanResult ¶
func WriteScanResult(path string, result *domain.ScanResult) error
WriteScanResult serializes a ScanResult to a JSON file for session resume caching.
func WriteShibitoInsights ¶ added in v0.0.4
func WriteShibitoInsights(w *InsightWriter, warnings []domain.ShibitoWarning, sessionID string, logger domain.Logger)
WriteShibitoInsights generates insight entries from ShibitoWarnings and appends them to the shibito.md insight file. Skips if there are no warnings. Errors are logged but do not propagate — insight writing is best-effort.
func WriteStrictnessInsights ¶ added in v0.0.4
func WriteStrictnessInsights(w *InsightWriter, clusters []domain.ClusterScanResult, sessionID string, logger domain.Logger)
WriteStrictnessInsights generates insight entries from cluster scan results that have EstimatedStrictness set. Appends to strictness.md insight file. Clusters without an estimate are skipped. Errors are best-effort.
Types ¶
type ClaudeAdapter ¶ added in v0.0.5
type ClaudeAdapter struct {
ClaudeCmd string
Model string
TimeoutSec int
Logger domain.Logger
ToolName string // CLI tool name for stream events (e.g. "sightjack")
StreamBus port.SessionStreamPublisher // optional: live session event streaming
// NewCmd overrides command creation. If nil, platform.NewShellCmd is used.
NewCmd func(ctx context.Context, name string, args ...string) *exec.Cmd
// CancelFunc sets cmd.Cancel for graceful shutdown. If nil, default (process kill) is used.
CancelFunc func(cmd *exec.Cmd) func() error
}
ClaudeAdapter implements port.ClaudeRunner by executing the Claude CLI as a subprocess with streaming (--output-format stream-json). It does NOT retry; wrap with RetryRunner for that.
func NewClaudeAdapter ¶ added in v0.0.5
func NewClaudeAdapter(cfg *domain.Config, logger domain.Logger) *ClaudeAdapter
NewClaudeAdapter creates a ClaudeAdapter implementing port.ClaudeRunner.
type CmdApprover ¶
type CmdApprover struct {
// contains filtered or unexported fields
}
CmdApprover runs an external command for approval. Exit 0 = approve, non-zero ExitError = deny, other error = fail.
func NewCmdApprover ¶
func NewCmdApprover(cmdTemplate string) *CmdApprover
NewCmdApprover creates a CmdApprover from a shell command template.
func (*CmdApprover) RequestApproval ¶
type CmdNotifier ¶
type CmdNotifier struct {
// contains filtered or unexported fields
}
CmdNotifier runs a user-provided shell command with {title} and {message} placeholders.
func NewCmdNotifier ¶
func NewCmdNotifier(cmdTemplate string) *CmdNotifier
NewCmdNotifier creates a CmdNotifier from a shell command template.
type DMail ¶
type DMail struct {
Name string `yaml:"name"`
Kind DMailKind `yaml:"kind"`
Description string `yaml:"description"`
SchemaVersion string `yaml:"dmail-schema-version,omitempty"`
Issues []string `yaml:"issues,omitempty"`
Severity string `yaml:"severity,omitempty"`
Action string `yaml:"action,omitempty"`
Priority int `yaml:"priority,omitempty"`
Wave *domain.WaveReference `yaml:"wave,omitempty"`
Metadata map[string]string `yaml:"metadata,omitempty"`
Context *domain.InsightContext `yaml:"context,omitempty" json:"context,omitempty"`
Body string `yaml:"-"`
}
DMail represents a d-mail message: YAML frontmatter + Markdown body.
func DrainInboxFeedback ¶
DrainInboxFeedback reads all currently buffered d-mails (feedback and convergence) from the monitor channel and logs them. Returns the drained messages for downstream use.
func FilterConvergence ¶
FilterConvergence returns convergence-kind D-Mails from the slice.
func ParseDMail ¶
ParseDMail parses YAML frontmatter + Markdown body from bytes.
func ReceiveDMail ¶
ReceiveDMail reads a d-mail from inbox/, parses it, and moves it to archive/.
func RunConvergenceGateWithRedrain ¶
func RunConvergenceGateWithRedrain(ctx context.Context, initial []*DMail, inboxCh <-chan *DMail, notifier port.Notifier, approver port.Approver, logger domain.Logger) (dmails []*DMail, approved bool, err error)
RunConvergenceGateWithRedrain runs the convergence gate in a loop, re-draining the inbox channel after each approval to catch late-arriving convergence D-Mails. Returns the accumulated D-Mails, approval status, and any error. The loop exits when no new convergence D-Mails arrived during the approval prompt, or when maxRedrainCycles is reached (fail-closed: approved=false).
type DMailKind ¶
type DMailKind string
DMailKind is the message type for d-mails.
const DMailStallEscalation DMailKind = "stall-escalation"
DMailStallEscalation is the d-mail kind for stall escalation messages. Sent when a wave is detected as stalled due to repeated structural errors.
type DeepScanFunc ¶
type DeepScanFunc func(ctx context.Context, cfg *domain.Config, scanDir string, index int, cluster domain.ClusterScanResult) (domain.ClusterScanResult, error)
DeepScanFunc is the function signature for scanning a single cluster. The index parameter identifies the cluster's position in the original slice, enabling safe lookup even when duplicate cluster names exist.
type DispatchingRecorder ¶
type DispatchingRecorder struct {
// contains filtered or unexported fields
}
DispatchingRecorder wraps a Recorder and dispatches events to an EventDispatcher. Record is delegated to inner first; then the event is dispatched best-effort.
func NewDispatchingRecorder ¶
func NewDispatchingRecorder(inner port.Recorder, dispatcher port.EventDispatcher, logger domain.Logger) *DispatchingRecorder
NewDispatchingRecorder creates a DispatchingRecorder. If dispatcher is nil, Record simply delegates to inner.
type EnterConfig ¶ added in v0.0.12
type EnterConfig struct {
ProviderCmd string // CLI command (from config.claude_cmd)
ProviderSessionID string // provider native session ID
WorkDir string // working directory (from session record)
ConfigBase string // base directory for resolving stateDir settings
Stdin io.Reader // injected by cmd layer (typically os.Stdin)
Stdout io.Writer // injected by cmd layer (typically os.Stdout)
Stderr io.Writer // injected by cmd layer (typically os.Stderr)
}
EnterConfig holds configuration for interactive session re-entry.
type FeedbackCollector ¶
type FeedbackCollector struct {
// contains filtered or unexported fields
}
FeedbackCollector accumulates feedback d-mails from both the initial drain and late-arriving items on the monitor channel. It replaces LogInboxFeedbackAsync by both displaying AND storing late arrivals, so they can be included in nextgen prompts. Convergence d-mails are tracked separately for journaling.
func CollectFeedback ¶
func CollectFeedback(initial []*DMail, ch <-chan *DMail, notifier port.Notifier, logger domain.Logger) *FeedbackCollector
CollectFeedback creates a FeedbackCollector seeded with initial feedback and starts a background goroutine to accumulate late-arriving items from the channel. Convergence d-mails trigger a notification via notifier. Safe to call with nil initial, nil channel, or nil notifier.
func (*FeedbackCollector) All ¶
func (c *FeedbackCollector) All() []*DMail
All returns a copy of all accumulated feedback (initial + late arrivals). Non-destructive: repeated calls return the same data plus any new arrivals.
func (*FeedbackCollector) ConvergenceNames ¶
func (c *FeedbackCollector) ConvergenceNames() []string
ConvergenceNames returns a copy of convergence d-mail names received mid-session. Used for journaling/state persistence.
func (*FeedbackCollector) FeedbackOnly ¶
func (c *FeedbackCollector) FeedbackOnly() []*DMail
FeedbackOnly returns a copy of accumulated d-mails filtered to feedback kind only (excludes convergence). Use this for nextgen prompt injection where only feedback d-mails are relevant.
func (*FeedbackCollector) NewSinceSnapshot ¶ added in v0.0.3
func (c *FeedbackCollector) NewSinceSnapshot() []*DMail
NewSinceSnapshot returns D-Mails received since the last Snapshot call.
func (*FeedbackCollector) NotifyCh ¶ added in v0.0.3
func (c *FeedbackCollector) NotifyCh() <-chan struct{}
NotifyCh returns a channel that receives a signal when new D-Mails arrive. Used by the waiting phase to wake up when inbox content changes.
func (*FeedbackCollector) ReportsOnly ¶
func (c *FeedbackCollector) ReportsOnly() []*DMail
ReportsOnly returns a copy of accumulated d-mails filtered to report kind only (excludes feedback and convergence). Use this for nextgen prompt injection where cross-tool reports (e.g. amadeus check results) should inform wave planning.
func (*FeedbackCollector) Snapshot ¶ added in v0.0.3
func (c *FeedbackCollector) Snapshot()
Snapshot marks the current position in the collected items. Call before entering the waiting phase.
type FileHandoverWriter ¶ added in v0.0.7
type FileHandoverWriter struct{}
FileHandoverWriter writes a handover markdown document to the state directory.
func (*FileHandoverWriter) WriteHandover ¶ added in v0.0.7
func (w *FileHandoverWriter) WriteHandover(ctx context.Context, stateDir string, state domain.HandoverState) error
WriteHandover renders state to markdown and writes it to {stateDir}/handover.md. The file is always overwritten (latest only). Respects context cancellation.
type IndexWriter ¶ added in v0.0.8
type IndexWriter struct{}
IndexWriter writes domain.IndexEntry records to a JSONL index file.
func (*IndexWriter) Append ¶ added in v0.0.8
func (w *IndexWriter) Append(indexPath string, entries []domain.IndexEntry) error
Append appends entries to the index file using flock for concurrency safety.
type InitAdapter ¶
type InitAdapter struct {
Force bool // When true, overwrite existing config.yaml
}
InitAdapter implements port.InitRunner by orchestrating project initialization I/O.
func (*InitAdapter) InitProject ¶
func (a *InitAdapter) InitProject(baseDir, team, project, lang, strictness string) ([]string, error)
InitProject creates .siren/config.yaml and supporting files. Returns warnings for non-fatal errors (skill install, mail dirs).
type InsightWriter ¶ added in v0.0.4
type InsightWriter struct {
// contains filtered or unexported fields
}
InsightWriter provides atomic read/write access to insight ledger files. It uses flock-based locking for concurrent safety and temp-file-rename for atomicity. Title-based dedup ensures idempotent appends.
func NewInsightWriter ¶ added in v0.0.4
func NewInsightWriter(insightsDir, runDir string) *InsightWriter
NewInsightWriter creates an InsightWriter for the given directories.
func (*InsightWriter) Append ¶ added in v0.0.4
func (w *InsightWriter) Append(filename, kind, tool string, entry domain.InsightEntry) error
Append adds a new InsightEntry to the named file, creating it if needed. Uses flock + atomic rename for concurrent safety. Idempotent: skips if an entry with the same title already exists.
func (*InsightWriter) Read ¶ added in v0.0.4
func (w *InsightWriter) Read(filename string) (*domain.InsightFile, error)
Read parses an insight file. Safe without locking due to atomic rename writes.
type LocalNotifier ¶
type LocalNotifier struct {
// contains filtered or unexported fields
}
LocalNotifier sends desktop notifications using OS-native tools. darwin: osascript with Funk sound, linux: notify-send.
type LoggingRecorder ¶
type LoggingRecorder struct {
// contains filtered or unexported fields
}
LoggingRecorder wraps a Recorder and logs errors instead of propagating them. This ensures callers never need to handle Record errors at every call site.
func NewLoggingRecorder ¶
func NewLoggingRecorder(inner port.Recorder, logger domain.Logger) *LoggingRecorder
NewLoggingRecorder creates a LoggingRecorder that wraps the given Recorder. If inner is nil, NopRecorder is used to prevent panics.
type MCPConfig ¶ added in v0.0.12
type MCPConfig struct {
MCPServers map[string]MCPServerEntry `json:"mcpServers"`
}
MCPConfig is the JSON structure for --mcp-config.
type MCPServerEntry ¶ added in v0.0.12
MCPServerEntry defines a single MCP server.
type RecorderFactoryAdapter ¶
type RecorderFactoryAdapter struct{}
RecorderFactoryAdapter implements port.RecorderFactory by delegating to session package functions.
func NewRecorderFactoryAdapter ¶
func NewRecorderFactoryAdapter() *RecorderFactoryAdapter
NewRecorderFactoryAdapter creates a new RecorderFactoryAdapter.
func (*RecorderFactoryAdapter) NewEventStore ¶
func (f *RecorderFactoryAdapter) NewEventStore(stateDir string, logger domain.Logger) port.EventStore
func (*RecorderFactoryAdapter) NewSessionRecorder ¶
func (*RecorderFactoryAdapter) SessionEventsDir ¶
func (f *RecorderFactoryAdapter) SessionEventsDir(baseDir, sessionID string) string
type RetryRunner ¶ added in v0.0.5
type RetryRunner struct {
Inner port.ClaudeRunner
MaxAttempts int
BaseDelay time.Duration
Timeout time.Duration
Logger domain.Logger
CircuitBreaker *platform.CircuitBreaker // optional: skip retries when circuit is open
}
RetryRunner wraps a provider runner (ClaudeRunner) with exponential backoff retry. Use the inner runner directly for non-idempotent operations. Timeout bounds the entire retry loop (not per-attempt).
func NewRetryRunner ¶ added in v0.0.5
func NewRetryRunner(inner port.ClaudeRunner, cfg *domain.Config, logger domain.Logger) *RetryRunner
NewRetryRunner creates a RetryRunner wrapping the given ClaudeRunner.
type SQLiteCodingSessionStore ¶ added in v0.0.12
type SQLiteCodingSessionStore struct {
// contains filtered or unexported fields
}
SQLiteCodingSessionStore implements CodingSessionStore using SQLite.
func NewSQLiteCodingSessionStore ¶ added in v0.0.12
func NewSQLiteCodingSessionStore(dbPath string) (*SQLiteCodingSessionStore, error)
NewSQLiteCodingSessionStore opens or creates a SQLite database at dbPath.
func (*SQLiteCodingSessionStore) Close ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) Close() error
func (*SQLiteCodingSessionStore) FindByProviderSessionID ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) FindByProviderSessionID(ctx context.Context, provider domain.Provider, pid string) ([]domain.CodingSessionRecord, error)
func (*SQLiteCodingSessionStore) LatestByProviderSessionID ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) LatestByProviderSessionID(ctx context.Context, provider domain.Provider, pid string) (domain.CodingSessionRecord, error)
func (*SQLiteCodingSessionStore) List ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) List(ctx context.Context, opts port.ListSessionOpts) ([]domain.CodingSessionRecord, error)
func (*SQLiteCodingSessionStore) Load ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) Load(ctx context.Context, id string) (domain.CodingSessionRecord, error)
func (*SQLiteCodingSessionStore) Save ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) Save(ctx context.Context, record domain.CodingSessionRecord) error
func (*SQLiteCodingSessionStore) UpdateStatus ¶ added in v0.0.12
func (s *SQLiteCodingSessionStore) UpdateStatus(ctx context.Context, id string, status domain.SessionStatus, providerSessionID string, metadata map[string]string) error
type SQLiteOutboxStore ¶
type SQLiteOutboxStore struct {
// contains filtered or unexported fields
}
SQLiteOutboxStore implements OutboxStore using a SQLite database as the transactional write-ahead log. Staged D-Mails are flushed to archive/ and outbox/ using atomic file writes (temp file + rename).
func NewOutboxStoreForDir ¶
func NewOutboxStoreForDir(baseDir string) (*SQLiteOutboxStore, error)
NewOutboxStoreForDir creates a SQLiteOutboxStore using conventional paths derived from baseDir: DB at .siren/.run/outbox.db, targets at .siren/archive/ and .siren/outbox/.
func NewSQLiteOutboxStore ¶
func NewSQLiteOutboxStore(dbPath, archiveDir, outboxDir string) (*SQLiteOutboxStore, error)
NewSQLiteOutboxStore opens (or creates) a SQLite database at dbPath and initialises the schema. archiveDir and outboxDir are the target directories for flushed D-Mail files.
func (*SQLiteOutboxStore) Close ¶
func (s *SQLiteOutboxStore) Close() error
Close closes the underlying database connection.
func (*SQLiteOutboxStore) Flush ¶
func (s *SQLiteOutboxStore) Flush(ctx context.Context) (int, error)
Flush writes all unflushed D-Mails to archive/ and outbox/ using atomic file writes, then marks them as flushed in the database. The entire flush is wrapped in a BEGIN IMMEDIATE transaction so that concurrent CLI processes wait (up to busy_timeout) instead of deadlocking. A partial failure leaves items eligible for retry on the next Flush call.
func (*SQLiteOutboxStore) IncrementalVacuum ¶
func (s *SQLiteOutboxStore) IncrementalVacuum() error
IncrementalVacuum reclaims free pages without acquiring an exclusive lock. Call after bulk deletes (e.g., archive-prune) to shrink the DB file. Requires PRAGMA auto_vacuum=INCREMENTAL set at DB open time.
func (*SQLiteOutboxStore) PruneFlushed ¶
func (s *SQLiteOutboxStore) PruneFlushed(ctx context.Context) (int, error)
PruneFlushed deletes all flushed rows from the staging table and runs incremental vacuum to reclaim disk space. Returns the number of deleted rows.
type ScanRunnerAdapter ¶
type ScanRunnerAdapter struct{}
ScanRunnerAdapter implements port.ScanRunner by delegating to session package functions.
func NewScanRunnerAdapter ¶
func NewScanRunnerAdapter() *ScanRunnerAdapter
NewScanRunnerAdapter creates a new ScanRunnerAdapter.
func (*ScanRunnerAdapter) RecordScanState ¶
func (a *ScanRunnerAdapter) RecordScanState(baseDir, sessionID string, result *domain.ScanResult, cfg *domain.Config, emitter port.SessionEventEmitter, ts time.Time, logger domain.Logger)
type SessionRunnerAdapter ¶
type SessionRunnerAdapter struct {
// contains filtered or unexported fields
}
SessionRunnerAdapter implements port.SessionRunner by delegating to session package functions.
func NewSessionRunnerAdapter ¶
func NewSessionRunnerAdapter() *SessionRunnerAdapter
NewSessionRunnerAdapter creates a new SessionRunnerAdapter.
func (*SessionRunnerAdapter) BuildNotifier ¶
func (a *SessionRunnerAdapter) BuildNotifier(gate domain.GateConfig) port.Notifier
func (*SessionRunnerAdapter) NewDispatchingRecorder ¶
func (a *SessionRunnerAdapter) NewDispatchingRecorder(inner port.Recorder, dispatcher port.EventDispatcher, logger domain.Logger) port.Recorder
func (*SessionRunnerAdapter) ReviewGateRunner ¶ added in v0.0.11
func (a *SessionRunnerAdapter) ReviewGateRunner() port.ReviewGateRunner
ReviewGateRunner returns the injected ReviewGateRunner (nil if not set).
func (*SessionRunnerAdapter) RunRescanSession ¶
func (*SessionRunnerAdapter) RunResumeSession ¶
func (*SessionRunnerAdapter) RunSession ¶
func (*SessionRunnerAdapter) SetReviewGateRunner ¶ added in v0.0.11
func (a *SessionRunnerAdapter) SetReviewGateRunner(runner port.ReviewGateRunner)
SetReviewGateRunner injects the review gate runner (usecase-layer logic).
type SessionTrackingAdapter ¶ added in v0.0.12
type SessionTrackingAdapter struct {
// contains filtered or unexported fields
}
SessionTrackingAdapter wraps a DetailedRunner with provider-agnostic session persistence. It creates a CodingSessionRecord before each invocation, captures the provider's session ID from the result, updates the record in the store, and records circuit breaker state from stderr.
func NewSessionTrackingAdapter ¶ added in v0.0.12
func NewSessionTrackingAdapter(inner port.DetailedRunner, store port.CodingSessionStore, provider domain.Provider) *SessionTrackingAdapter
NewSessionTrackingAdapter creates a new adapter.
func (*SessionTrackingAdapter) Run ¶ added in v0.0.12
func (a *SessionTrackingAdapter) Run(ctx context.Context, prompt string, w io.Writer, opts ...port.RunOption) (string, error)
Run implements the provider runner interface, enabling drop-in replacement of plain adapters.
func (*SessionTrackingAdapter) RunSession ¶ added in v0.0.12
func (a *SessionTrackingAdapter) RunSession(ctx context.Context, prompt string, w io.Writer, opts ...port.RunOption) (domain.CodingSessionRecord, string, error)
RunSession executes the inner runner and persists session metadata.
type SpanEventStore ¶
type SpanEventStore struct {
// contains filtered or unexported fields
}
SpanEventStore wraps a port.EventStore with OTEL span instrumentation. Each operation is wrapped in a span with event count and stats attributes.
func (*SpanEventStore) Append ¶
func (s *SpanEventStore) Append(events ...domain.Event) (domain.AppendResult, error)
func (*SpanEventStore) LoadAll ¶
func (s *SpanEventStore) LoadAll() ([]domain.Event, domain.LoadResult, error)
func (*SpanEventStore) LoadSince ¶
func (s *SpanEventStore) LoadSince(after time.Time) ([]domain.Event, domain.LoadResult, error)
type StateLoaderAdapter ¶
type StateLoaderAdapter struct{}
StateLoaderAdapter implements port.StateLoader by delegating to session package functions.
func NewStateLoaderAdapter ¶
func NewStateLoaderAdapter() *StateLoaderAdapter
NewStateLoaderAdapter creates a new StateLoaderAdapter.
func (*StateLoaderAdapter) CanResume ¶
func (l *StateLoaderAdapter) CanResume(baseDir string, state *domain.SessionState) bool
func (*StateLoaderAdapter) LoadLatestResumableState ¶
func (l *StateLoaderAdapter) LoadLatestResumableState(ctx context.Context, baseDir string, match func(*domain.SessionState) bool) (*domain.SessionState, string, error)
func (*StateLoaderAdapter) LoadLatestState ¶
func (l *StateLoaderAdapter) LoadLatestState(ctx context.Context, baseDir string) (*domain.SessionState, string, error)
type StdinApprover ¶
type StdinApprover struct {
// contains filtered or unexported fields
}
StdinApprover prompts the user on a terminal and reads y/n. Uses goroutine + channel for context cancellation support. Safe default: empty or non-y input = deny.
func NewStdinApprover ¶
func NewStdinApprover(r io.Reader, w io.Writer) *StdinApprover
NewStdinApprover creates a StdinApprover with the given reader and writer.
func (*StdinApprover) RequestApproval ¶
Source Files
¶
- adapters.go
- approve.go
- architect.go
- archive.go
- archive_index.go
- auto_discuss.go
- claude.go
- claude_adapter.go
- claude_log.go
- cli.go
- coding_session_store.go
- config.go
- daemon_lock_unix.go
- dmail.go
- dmail_compose.go
- dmail_stall.go
- doctor.go
- doctor_claude.go
- flock_unix.go
- gate.go
- handoff.go
- handover.go
- init_adapter.go
- insight_lock_unix.go
- insight_scan.go
- insight_writer.go
- json_normalize.go
- loop.go
- mcp_config.go
- navigator.go
- notify.go
- outbox_store.go
- phases.go
- preflight.go
- ready_label_wave.go
- recorder.go
- retry_runner.go
- review.go
- review_adapters.go
- review_gate.go
- scan_state.go
- scanner.go
- scribe.go
- scribe_conflict.go
- scribe_supersede.go
- session.go
- session_enter.go
- session_rescan.go
- session_tracking_adapter.go
- shell_quote.go
- shell_unix.go
- signal_unix.go
- skills.go
- span_event_store.go
- state_io.go
- status.go
- store_factory.go
- waiting.go
- wave.go
- wave_generator.go