Documentation
¶
Overview ¶
Package sessiontext classifies and cleans the operational/meta blocks agents inject as user-role messages of a session. Centralized here so importers, renderers, and the store-level denoise mirror all share one source of truth — the master pattern list lives in Prefixes.
Two consumer shapes:
- CleanPrompt / IsBoilerplatePrompt / BuildFirstPrompt — used by importers to derive the FirstPrompt field shown on the timeline.
- ParseUserMessage — used by the panel to break a user turn into its semantic parts (slash command, system reminders, stdout, env context, …) so each can render as a discrete chip or disclosure instead of a wall of XML.
Index ¶
- Variables
- func BuildFirstPrompt(text string, maxRunes int) (string, bool)
- func CleanPrompt(s string) string
- func ExtractGoalBudget(s string) string
- func ExtractGoalObjective(s string) (string, bool)
- func FirstNonBoilerplate(candidates []string) string
- func IsBoilerplatePrompt(s string) bool
- func IsGoalWrapper(s string) bool
- func SanitizeForDisplay(s string) string
- type UserMessage
Constants ¶
This section is empty.
Variables ¶
var Prefixes = []string{
"# AGENTS.md instructions for ",
"<command-name>",
"<command-args>",
"<command-message>",
"<system-reminder>",
"<INSTRUCTIONS>",
"<environment_context>",
"<permissions instructions>",
"<collaboration_mode>",
"<local-command-caveat>",
"<local-command-stdout>",
"<local-command-stderr>",
"You are Codex, a coding agent",
"Knowledge cutoff:",
}
Prefixes is the master list of literal starts agents inject as user-role messages that should not be treated as real human prompts. Match is a plain case-sensitive HasPrefix after trimming leading whitespace.
The list is exported so the SQL mirror in internal/store.ListSessionsWithBoilerplatePrompt can iterate the same patterns instead of duplicating them.
Patterns observed in the wild:
- codex / claude-code: # AGENTS.md instructions for <path>
- claude-code: <command-name>…</command-name> harness wrappers.
- claude-code: <command-args>…</command-args> harness args.
- claude-code: <command-message>…</command-message> harness slug.
- claude-code: <system-reminder>…</system-reminder> meta blocks.
- claude-code: <INSTRUCTIONS> global instructions wrapper.
- claude-code: <environment_context> session environment dump.
- claude-code: <permissions instructions> permission preface.
- claude-code: <collaboration_mode> mode prefix.
- claude-code: <local-command-caveat> wrapper before slash-command body.
- claude-code: <local-command-stdout>…</local-command-stdout> captured stdout (often ANSI-laden).
- claude-code: <local-command-stderr>…</local-command-stderr> captured stderr.
- codex: You are Codex, a coding agent (system role leaking through).
- codex: Knowledge cutoff: <date> (system role leaking through).
Functions ¶
func BuildFirstPrompt ¶
BuildFirstPrompt returns the cleaned, whitespace-collapsed, rune- truncated form of text suitable for the timeline's FirstPrompt field. Returns ("", false) when text is empty, wholly boilerplate/meta, or becomes empty after sanitization. maxRunes <= 0 also returns false.
Each importer owns its own truncation limit (claude-code/codex use 200; cursor/gemini/hermes likewise) so it is passed explicitly here.
func CleanPrompt ¶
CleanPrompt strips leading wrapper blocks (tag-style: <foo>…</foo>) and returns the trimmed human portion that follows. ANSI escape sequences and control characters are removed first, so wrappers laden with terminal codes (e.g. <local-command-stdout>␛[1m…␛[22m</…>) are recognized.
Non-wrapper prefixes (e.g. "# AGENTS.md instructions for ", "You are Codex, …") have no closing marker, so the whole input is meta — the sanitized input is returned and the caller can detect that via IsBoilerplatePrompt and fall back to a placeholder.
Returns the sanitized input untouched when:
- the input does not start with any known prefix; or
- all that remains after stripping wrappers is empty.
func ExtractGoalBudget ¶
ExtractGoalBudget returns the "Budget:" block (header plus its bullet lines, up to the next blank line) from a goal wrapper. Empty when absent.
func ExtractGoalObjective ¶
ExtractGoalObjective returns the human <objective> buried inside a goal wrapper. ok is false when s is not a goal wrapper or carries no objective block.
func FirstNonBoilerplate ¶
FirstNonBoilerplate returns the first candidate whose cleaned form is not boilerplate. Returns "" when all candidates are meta.
func IsBoilerplatePrompt ¶
IsBoilerplatePrompt reports whether s, after best-effort cleaning, still classifies as one of the known meta prefixes.
func IsGoalWrapper ¶
IsGoalWrapper reports whether s is a Codex goal context block. Leading whitespace and control characters are tolerated.
func SanitizeForDisplay ¶
SanitizeForDisplay removes ANSI escape sequences and control characters from s.
Types ¶
type UserMessage ¶
type UserMessage struct {
Command string // <command-name> body
CommandArgs string // <command-args> body
CommandMessage string // <command-message> body
Reminders []string // one entry per <system-reminder>
EnvContext string // <environment_context> body
Instructions string // <INSTRUCTIONS> body
CollaborationMode string // <collaboration_mode> body
PermissionsInstructions string // <permissions instructions> body (no closing tag — captured raw)
LocalCommandCaveat string // <local-command-caveat> body
LocalCommandStdout string // <local-command-stdout> body
LocalCommandStderr string // <local-command-stderr> body
GoalObjective string // <objective> inside a Codex goal wrapper
GoalBudget string // "Budget:" block from a Codex goal wrapper
GoalScaffold string // rest of the goal wrapper (objective removed)
Body string // what's left after stripping wrappers
}
UserMessage is the structured shape of a user turn after the boilerplate wrappers agents inject have been peeled off. Body is the human portion; the other fields hold the meta wrappers so renderers can present them discretely (chip, collapsible details) instead of dumping the raw XML on screen.
Fields are populated only when the corresponding wrapper appears in the input. When a single wrapper type appears multiple times (e.g. several <system-reminder> blocks in one user turn), every occurrence is preserved in the slice fields.
func ParseUserMessage ¶
func ParseUserMessage(raw string) UserMessage
ParseUserMessage extracts every known wrapper from raw and returns what each carried plus the leftover Body. Order in the input is irrelevant — each wrapper is searched independently. On a malformed wrapper (open tag with no closing) the fragment is left in Body.
func (UserMessage) HasExtras ¶
func (m UserMessage) HasExtras() bool
HasExtras reports whether anything other than Body needs surfacing — the renderer uses this to decide if it should render the reminders/stdout/env_context disclosures at all.
func (UserMessage) IsEmpty ¶
func (m UserMessage) IsEmpty() bool
IsEmpty reports whether the message carries nothing the renderer would surface — useful as a guard for "skip the user bubble".