You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -84,25 +84,25 @@ Environment variables:
84
84
85
85
# Output Routing and Events
86
86
87
-
- Emit typed events through `internal/output` (`EmitInfo`, `EmitSuccess`, `EmitNote`, `EmitWarning`, `EmitStatus`, `EmitProgress`, etc.) instead of printing from domain/command handlers.
88
-
-Keep `output.Sink` sealed (unexported `emit`); sink implementations belong in `internal/output`.
89
-
- Reuse `FormatEventLine(event any)` for all line-oriented rendering so plain and TUI output stay consistent.
87
+
- Emit typed events via `sink.Emit(output.XxxEvent{...})` instead of printing from domain/command handlers. For simple messages use `output.MessageEvent{Severity: output.SeverityInfo, Text: "..."}` (severities: `SeverityInfo`, `SeveritySuccess`, `SeverityNote`, `SeverityWarning`, `SeveritySecondary`).
88
+
- Sink implementations belong in `internal/output`; do not implement `output.Sink` outside that package.
89
+
- Reuse `FormatEventLine(event Event)` for all line-oriented rendering so plain and TUI output stay consistent.
90
90
- Select output mode at the command boundary in `cmd/`: interactive TTY runs Bubble Tea, non-interactive mode uses `output.NewPlainSink(...)`.
91
91
- Keep non-TTY mode non-interactive (no stdin prompts or input waits).
92
92
- Domain packages must not import Bubble Tea or UI packages.
93
93
- Any feature/workflow package that produces user-visible progress should accept an `output.Sink` dependency and emit events through `internal/output`.
94
94
- Do not pass UI callbacks like `onProgress func(...)` through domain layers; prefer typed output events.
95
95
- Event payloads should be domain facts (phase/status/progress), not pre-rendered UI strings.
96
96
- When adding a new event type, update all of:
97
-
-`internal/output/events.go` (event type + `Event` union constraint + emit helper)
output.EmitNote(a.sink, "Authenticated via LOCALSTACK_AUTH_TOKEN environment variable; unset it to log out")
74
+
a.sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: "Authenticated via LOCALSTACK_AUTH_TOKEN environment variable; unset it to log out"})
75
75
returnnil
76
76
}
77
77
if!errors.Is(err, ErrTokenNotFound) {
78
78
returnfmt.Errorf("failed to read auth token: %w", err)
79
79
}
80
-
output.EmitNote(a.sink, "Not currently logged in")
80
+
a.sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: "Not currently logged in"})
Preamble: "Welcome to lstk, a command-line interface for LocalStack",
45
45
Code: authReq.Code,
46
46
URL: authURL,
47
47
})
48
48
browser.Stdout=io.Discard
49
49
browser.Stderr=io.Discard
50
50
iferr:=browser.OpenURL(authURL); err!=nil {
51
-
output.EmitWarning(l.sink, fmt.Sprintf("Failed to open browser automatically. Open this URL manually to continue: %s", authURL))
51
+
l.sink.Emit(output.MessageEvent{Severity: output.SeverityWarning, Text: fmt.Sprintf("Failed to open browser automatically. Open this URL manually to continue: %s", authURL)})
52
52
}
53
53
54
-
output.EmitSpinnerStart(l.sink, "Waiting for authorization...")
54
+
l.sink.Emit(output.SpinnerStart("Waiting for authorization..."))
0 commit comments