Documentation
¶
Overview ¶
Package runlog writes the four PLAN-5 / C6 streams that surround the pipeline manifest:
hook-events.jsonl one JSON per ape-notify forward bridge-calls.jsonl one JSON per MCP tool call seen by the bridge checkpoints.jsonl ape stage events + skill reply() calls transcripts/ symlinks into ~/.claude/projects/<hash>/<sid>.jsonl
Pipeline runs use the existing PLAN-3 layout (<project>/_output/pipelines/<name>/<run_id>/) — runlog does not move the directory, it adds files alongside manifest.yaml.
`ape chat` writes to a separate convention (<project>/_output/ape/chats/<chat-id>/) with session.yaml in place of the PLAN-3 manifest.
Index ¶
- func ChatDir(projectRoot, chatID string) string
- func CopyFileAtomic(dst, src string) error
- func EnsureGitignore(projectRoot string, askPrompt func(question string) bool, warnTo io.Writer) (bool, error)
- func EnsureNoCollision(dir string) error
- func NewChatID(now time.Time, cwd string, pid int) string
- func PipelineRunDir(projectRoot, pipelineName, runID string) string
- func WriteSessionYAML(dir string, m SessionMeta) error
- type CallEntry
- type CheckpointEntry
- type HookEntry
- type SessionMeta
- type Writer
- func (w *Writer) Call(entry CallEntry) error
- func (w *Writer) Checkpoint(entry CheckpointEntry) error
- func (w *Writer) CheckpointKindStep(kind, step string, payload any, at time.Time)
- func (w *Writer) Close() error
- func (w *Writer) Dir() string
- func (w *Writer) Hook(entry HookEntry) error
- func (w *Writer) LinkTranscript(name, target string) error
- func (w *Writer) SnapshotTranscript(name, src string) (string, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CopyFileAtomic ¶ added in v0.0.32
CopyFileAtomic copies src to dst via a tmp file + rename. Replaces a pre-existing symlink at dst with a real file. Exported so `ape notify` can perform the hook-side transcript capture with the same primitive the run-dir snapshots use.
func EnsureGitignore ¶
func EnsureGitignore(projectRoot string, askPrompt func(question string) bool, warnTo io.Writer) (bool, error)
EnsureGitignore looks for `_output/` in <projectRoot>/.gitignore. If absent and stdin is a TTY (askPrompt provided), it asks the user; otherwise it warns to stderr but does not modify the file. PLAN-5 / C6 — first-run policy.
Returns true if the line was appended (or already present), false if the user declined or non-TTY warn path was taken.
func EnsureNoCollision ¶
EnsureNoCollision returns an error if dir already exists. PLAN-5 / C6: "fail loud" — no auto-disambiguate, no overwrite.
func NewChatID ¶
NewChatID generates a chat-id of the shape YYYYMMDD-HHMMSS-<7-char hash>. Hash mixes timestamp + cwd + pid for cross-process uniqueness. PLAN-5 / C6.
func PipelineRunDir ¶
PipelineRunDir returns <project>/_output/pipelines/<name>/<run_id>/. PLAN-3's path, extended in place by PLAN-5.
func WriteSessionYAML ¶
func WriteSessionYAML(dir string, m SessionMeta) error
WriteSessionYAML emits session.yaml at <dir>/session.yaml. Hand-rolled because the file is tiny and the rest of ape doesn't pull a YAML encoder for trivial structs.
Types ¶
type CallEntry ¶
type CallEntry struct {
Timestamp time.Time
Method string // "tools/call", "tools/list", "ping", "initialize"
Tool string
Params json.RawMessage
Result json.RawMessage
SessionID string
ID string
}
CallEntry mirrors an MCP tool call.
type CheckpointEntry ¶
type CheckpointEntry struct {
Timestamp time.Time
Kind string // stage-start, stage-end, commit-made, pipeline-end, reply, stopped, chat-start, chat-end
Step string
Payload any
}
CheckpointEntry is the typed input to Writer.Checkpoint.
type HookEntry ¶
type HookEntry struct {
Timestamp time.Time
Event string
Step string // empty → "step":null on the wire
SessionID string
AgentID string
Payload json.RawMessage
}
HookEntry is the typed input to Writer.Hook. The on-wire shape is stable but assembled by hookOnWire to keep nil pointers from producing `null` for fields PLAN-5 specifies as empty strings.
type SessionMeta ¶
type SessionMeta struct {
ChatID string
StartedAt time.Time
EndedAt time.Time
Model string
CostUSD float64
TokensIn int64
TokensOut int64
}
SessionMeta is the minimal chat-session record written to session.yaml when an `ape chat` run ends. PLAN-5 / C6 — chats are not pipelines, so no PLAN-3 manifest equivalent.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer is one open run-dir. Methods are safe for concurrent use.
func New ¶
New opens (or creates) the four streams under dir. Fails loud if the dir already exists and contains a non-empty manifest — that is the PLAN-5 / C6 run-id collision contract.
func (*Writer) Call ¶
Call writes one bridge-calls.jsonl entry. Captures every MCP tool call seen at the bridge stdio layer (including tools/list, ping, initialize, and await_message's deferred-entry + flush pair).
func (*Writer) Checkpoint ¶
func (w *Writer) Checkpoint(entry CheckpointEntry) error
Checkpoint writes one checkpoints.jsonl entry. Kinds: stage-start, stage-end, commit-made, pipeline-end, reply, stopped. PLAN-5 / C6.
func (*Writer) CheckpointKindStep ¶
CheckpointKindStep is the pipeline.RunLogger adapter shape: (kind, step, payload, at) → CheckpointEntry. Defined here so the runlog package owns its own wire shape; pipeline calls this via its narrow RunLogger interface to avoid a runlog import.
func (*Writer) Hook ¶
Hook writes one hook-events.jsonl entry. ts defaults to time.Now().UTC() if zero.
Schema (PLAN-5 / C6): {"ts","event","step","session_id","agent_id","payload"}. `step` is null for events whose session_id is not yet bound.
func (*Writer) LinkTranscript ¶
LinkTranscript creates the symlink <dir>/transcripts/<name> → target. Best-effort: returns nil if the link already exists at the same target, errors otherwise so the caller can decide. PLAN-5 / C6 — symlinks (not copies) keep the canonical ~/.claude/projects/ path authoritative.
func (*Writer) SnapshotTranscript ¶ added in v0.0.28
SnapshotTranscript copies src's bytes to <dir>/transcripts/<name> and returns the destination path. Unlike LinkTranscript, the result survives the source session file being rotated or removed — claude session .jsonl files under ~/.claude/projects/ have been observed gone by post-Stop scan time, which zeroed interactive telemetry. Idempotent: repeat calls refresh the copy (the session file is append-only, so a later copy strictly supersedes an earlier one). Replaces a pre-existing symlink of the same name.