diff --git a/README.md b/README.md index 2cab577..ebf22ca 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ irm https://raw.githubusercontent.com/Mapleeeeeeeeeee/cc-session-reader/main/ins | `list` | 瀏覽最近的 session(用過 cc-session 的標 `[refs]`) | `cc-session list -n 10 -p myproject` | | `read` | 完整對話 + inline tool 摘要 | `cc-session read -max-lines 200` | | `context` | 精簡注入格式,含 session metadata header | `cc-session context ` | -| `inject` | 分頁 context 注入(每頁 ≤20K chars,自動追蹤進度,`-reset` 重來) | `cc-session inject ` | +| `inherit` | 分頁 context 繼承(每頁 ≤20K chars,自動追蹤進度,`-reset` 重來) | `cc-session inherit ` | | `stats` | 字元與 token 分佈統計及壓縮比 | `cc-session stats -no-tokens` | | `audit` | 取樣被過濾的內容,確認沒漏掉重要資訊 | `cc-session audit -n 10` | | `expand` | 展開特定 tool call 的完整 input/result | `cc-session expand uCVa` | @@ -60,7 +60,7 @@ Session ID 支援 prefix match,通常前 8 碼就夠。`read` 和 `context` ## 壓縮邏輯 -工具呼叫、Bash 輸出、Agent 結果、thinking 都預設壓成摘要或一行 marker;User/Assistant 對話文字完整保留。當 session 內有 cc-session inject/read/context 呼叫時,連續呼叫壓成一行(如 `(cc-session#id: injected session X here, N lines omitted)`),`-verbose-bash` 跳過此壓縮。Skill injection、teammate warning、command injection、Context Usage 區塊、system-reminder 等 injection 類型會額外壓縮或整段移除,減少 context 噪音。詳細過濾規則見 [SKILL.md](SKILL.md)。 +工具呼叫、Bash 輸出、Agent 結果、thinking 都預設壓成摘要或一行 marker;User/Assistant 對話文字完整保留。當 session 內有 cc-session inherit/read/context 呼叫時,連續呼叫壓成一行(如 `(cc-session#id: inherited session X here, N lines omitted)`),`-verbose-bash` 跳過此壓縮。舊 session 裡的 `cc-session inject` 呼叫(改名前的舊命令名)也會比照壓成一行,維持 `injected session X here` 的措辭。Skill injection、teammate warning、command injection、Context Usage 區塊、system-reminder 等 injection 類型會額外壓縮或整段移除,減少 context 噪音。詳細過濾規則見 [SKILL.md](SKILL.md)。 ## Config 設定 diff --git a/SKILL.md b/SKILL.md index d4767dd..cef11b3 100644 --- a/SKILL.md +++ b/SKILL.md @@ -12,17 +12,17 @@ allowed-tools: ## 讀取 session 內容 read 預設截斷在 200 行——大多數 session 遠超這個長度,只看得到開頭一小段。 -inject 將完整 session 分頁載入(每頁 ≤20K chars),確保完整覆蓋。 +inherit 將完整 session 分頁載入(每頁 ≤20K chars),確保完整覆蓋。 -讀 session 時用 inject。只在使用者明確指名要看某段特定內容時用 read 搭配 `-offset` 跳讀。 +讀 session 時用 inherit。只在使用者明確指名要看某段特定內容時用 read 搭配 `-offset` 跳讀。 -### inject 操作方式 +### inherit 操作方式 -inject 記住讀取進度,重複呼叫同一個命令即自動翻頁: +inherit 記住讀取進度,重複呼叫同一個命令即自動翻頁: -1. `cc-session inject ` → 第 1 頁,標示 `[page 1/N | lines X-Y of Z]` -2. 再次呼叫 `cc-session inject `(同樣的命令,同樣的參數)→ 第 2 頁 -3. 持續呼叫,直到輸出包含 `[inject complete]` +1. `cc-session inherit ` → 第 1 頁,標示 `[page 1/N | lines X-Y of Z]` +2. 再次呼叫 `cc-session inherit `(同樣的命令,同樣的參數)→ 第 2 頁 +3. 持續呼叫,直到輸出包含 `[inherit complete]` 4. 所有頁面讀完後,分析內容並回答使用者 `-page N` 跳到指定頁。`-reset` 清除進度從頭開始。 @@ -32,7 +32,7 @@ inject 記住讀取進度,重複呼叫同一個命令即自動翻頁: | 意圖 | 命令 | |------|------| | 找目標 session | `cc-session list` — 列出最近 session,`-p` 過濾專案,用過 cc-session 的標 `[refs]` | -| 讀 session(預設) | `cc-session inject ` — 分頁載入,重複呼叫翻頁 | +| 讀 session(預設) | `cc-session inherit ` — 分頁載入,重複呼叫翻頁 | | 查特定片段 | `cc-session read ` — 預設 200 行,`-offset` 跳讀 | | 緊湊單次輸出 | `cc-session context ` — 同 read 但更緊湊,帶 metadata header | | 展開單一 tool call | `cc-session expand ` — tool-id 取自輸出中的 `[Tool#xxxx]` | @@ -45,8 +45,9 @@ Session ID 支援 prefix match,前 8 碼通常就夠。各子命令的 flags ## 輸出行為 -- 當 session 內有 `cc-session inject/read/context` 呼叫時,連續的同 session 呼叫會被壓成一行: - `(cc-session#Y1dg: injected session 16d06326 here, 1320 lines omitted)` +- 當 session 內有 `cc-session inherit/read/context` 呼叫時,連續的同 session 呼叫會被壓成一行: + `(cc-session#Y1dg: inherited session 16d06326 here, 1320 lines omitted)` +- 舊 session 裡的 `cc-session inject`(改名前的舊命令名)也會比照壓成一行,維持 `injected session X here` 的措辭 - tool ID(`#Y1dg`)保留,可用 `cc-session expand` 查看原始內容 - `-verbose-bash` 會跳過此壓縮,顯示完整 Bash 輸出 diff --git a/cmd/cc-session/e2e_test.go b/cmd/cc-session/e2e_test.go index 582da98..b303dff 100644 --- a/cmd/cc-session/e2e_test.go +++ b/cmd/cc-session/e2e_test.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "errors" "os" "os/exec" @@ -121,6 +122,35 @@ func TestCLI_WhenSessionExists_ThenListReadContextAndAuditWorkEndToEnd(t *testin } } +func TestCLI_GivenInjectAlias_WhenInvoked_ThenBehavesLikeInheritAndWarnsOnStderr(t *testing.T) { + root := t.TempDir() + bin := filepath.Join(root, binaryName()) + build := exec.Command("go", "build", "-o", bin, ".") + build.Dir = "." + if out, err := build.CombinedOutput(); err != nil { + t.Fatalf("build CLI: %v\n%s", err, out) + } + + sid := "12345678-1234-1234-1234-123456789abc" + writeE2EFixture(t, root, sid) + + var stdout, stderr bytes.Buffer + cmd := exec.Command(bin, "inject", sid) + cmd.Env = homeEnv(root) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Fatalf("cc-session inject %s failed: %v\nstderr:\n%s", sid, err, stderr.String()) + } + + if !strings.Contains(stderr.String(), "cc-session inject 已改名為 cc-session inherit") { + t.Fatalf("stderr missing deprecation notice, got: %q", stderr.String()) + } + if !strings.Contains(stdout.String(), "[page 1/1") || !strings.Contains(stdout.String(), "[inherit complete: 1 pages") { + t.Fatalf("stdout missing paginated session output, got: %q", stdout.String()) + } +} + // The cmdX wrappers funnel every error through a single contract: print // "Error: " to stderr and exit non-zero. This is the user's only signal // that a command failed. Tested out-of-process because the contract lives in diff --git a/cmd/cc-session/inject_cmd.go b/cmd/cc-session/inherit_cmd.go similarity index 75% rename from cmd/cc-session/inject_cmd.go rename to cmd/cc-session/inherit_cmd.go index 2ca244f..7fcba88 100644 --- a/cmd/cc-session/inject_cmd.go +++ b/cmd/cc-session/inherit_cmd.go @@ -12,12 +12,12 @@ import ( "github.com/Mapleeeeeeeeeee/cc-session-reader/internal/session" ) -func cmdInject(args []string, reader session.TranscriptReader) { - exitOnError(runInject(args, os.Stdout, os.Stderr, parser.DefaultStore(), reader)) +func cmdInherit(args []string, reader session.TranscriptReader) { + exitOnError(runInherit(args, os.Stdout, os.Stderr, parser.DefaultStore(), reader)) } -func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Store, reader session.TranscriptReader) error { - fs := flag.NewFlagSet("inject", flag.ContinueOnError) +func runInherit(args []string, out io.Writer, errOut io.Writer, store parser.Store, reader session.TranscriptReader) error { + fs := flag.NewFlagSet("inherit", flag.ContinueOnError) fs.SetOutput(errOut) pageFlag := fs.Int("page", 0, "jump to specific page (1-based; 0 = auto-advance)") resetFlag := fs.Bool("reset", false, "clear state and start from the beginning") @@ -25,7 +25,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor return err } if fs.NArg() < 1 { - return fmt.Errorf("usage: cc-session inject [--page N] [--reset]") + return fmt.Errorf("usage: cc-session inherit [--page N] [--reset]") } sessionPrefix := fs.Arg(0) @@ -36,7 +36,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor if resolved.Path == "" { return fmt.Errorf("transcript not found: %s", resolved.ID) } - logUsageAsync("inject", session.ShortID(resolved.ID, 8)) + logUsageAsync("inherit", session.ShortID(resolved.ID, 8)) if *resetFlag { if err := inject.ClearState(resolved.ID); err != nil { @@ -59,7 +59,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor pages := inject.SplitPages(allLines) totalPages := len(pages) if totalPages == 0 { - fmt.Fprintln(out, "[inject complete: 0 pages, 0 lines]") + fmt.Fprintln(out, "[inherit complete: 0 pages, 0 lines]") return nil } @@ -72,7 +72,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor } else { state, loadErr := inject.LoadState(resolved.ID) if loadErr != nil { - return fmt.Errorf("load inject state: %w", loadErr) + return fmt.Errorf("load inherit state: %w", loadErr) } if state == nil { pageNum = 1 @@ -82,7 +82,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor } if pageNum > totalPages { - fmt.Fprintf(out, "[inject complete: %d pages, %d lines] — use -reset to start over\n", totalPages, totalLines) + fmt.Fprintf(out, "[inherit complete: %d pages, %d lines] — use -reset to start over\n", totalPages, totalLines) return nil } if pageNum < 1 { @@ -110,7 +110,7 @@ func runInject(args []string, out io.Writer, errOut io.Writer, store parser.Stor } if err := inject.SaveState(newState); err != nil { // Non-fatal: output was already written. - fmt.Fprintf(errOut, "warning: could not save inject state: %v\n", err) + fmt.Fprintf(errOut, "warning: could not save inherit state: %v\n", err) } return nil } diff --git a/cmd/cc-session/main.go b/cmd/cc-session/main.go index e0b548a..431e265 100644 --- a/cmd/cc-session/main.go +++ b/cmd/cc-session/main.go @@ -1,5 +1,6 @@ // Package main is the CLI entry point for the Claude session reader. -// Subcommands: list, read, context, stats, audit, expand, usage, inject. +// Subcommands: list, read, context, stats, audit, expand, usage, inherit. +// "inject" is kept as a hidden, deprecated alias for "inherit". package main import ( @@ -62,8 +63,11 @@ func main() { cmdExpand(os.Args[2:], reader) case "usage": cmdUsage(os.Args[2:]) + case "inherit": + cmdInherit(os.Args[2:], reader) case "inject": - cmdInject(os.Args[2:], reader) + fmt.Fprintln(os.Stderr, "cc-session inject 已改名為 cc-session inherit,inject 別名將於未來版本移除,請改用 inherit。") + cmdInherit(os.Args[2:], reader) case "benchmark": cmdBenchmark(os.Args[2:], reader) default: @@ -84,7 +88,7 @@ func printUsage() { fmt.Fprintln(os.Stderr, " audit 檢視被過濾的內容取樣") fmt.Fprintln(os.Stderr, " expand 展開特定 tool call 完整內容") fmt.Fprintln(os.Stderr, " usage CLI 使用紀錄") - fmt.Fprintln(os.Stderr, " inject 分頁注入 session 到 context") + fmt.Fprintln(os.Stderr, " inherit 分頁繼承 session 到 context") fmt.Fprintln(os.Stderr, " benchmark 掃描近期 session,計算壓縮率與成本比較") fmt.Fprintln(os.Stderr, "") fmt.Fprintln(os.Stderr, "Run 'cc-session -h' for command-specific flags.") diff --git a/cmd/cc-session/main_test.go b/cmd/cc-session/main_test.go index 91ba94f..0fb73ff 100644 --- a/cmd/cc-session/main_test.go +++ b/cmd/cc-session/main_test.go @@ -1220,11 +1220,11 @@ func TestRunList_GivenHelpFlag_ThenReturnsErrHelp(t *testing.T) { } } -func TestRunInject_GivenHelpFlag_ThenReturnsErrHelp(t *testing.T) { +func TestRunInherit_GivenHelpFlag_ThenReturnsErrHelp(t *testing.T) { var stdout, stderr bytes.Buffer - err := runInject([]string{"-h"}, &stdout, &stderr, parser.Store{}, testReader) + err := runInherit([]string{"-h"}, &stdout, &stderr, parser.Store{}, testReader) if err == nil || err.Error() != "flag: help requested" { - t.Fatalf("runInject(-h) = %v, want flag.ErrHelp", err) + t.Fatalf("runInherit(-h) = %v, want flag.ErrHelp", err) } if !strings.Contains(stderr.String(), "page") { t.Fatalf("stderr should contain flag descriptions, got: %q", stderr.String()) diff --git a/docs/adr-001-collapse-cc-session-calls.md b/docs/adr-001-collapse-cc-session-calls.md index 3b648c5..a9a8eee 100644 --- a/docs/adr-001-collapse-cc-session-calls.md +++ b/docs/adr-001-collapse-cc-session-calls.md @@ -6,33 +6,34 @@ Accepted ## Context -When a Claude Code session uses `cc-session inject` to load another session's content, the JSONL records each inject page as a separate Bash tool call. A 4-page inject produces 4 lines like: +When a Claude Code session uses `cc-session inherit` (formerly `cc-session inject`, see the CLI rename) to load another session's content, the JSONL records each page as a separate Bash tool call. A 4-page inherit produces 4 lines like: ``` -[Bash#Y1dg] cc-session inject 16d06326-... -> ok: [page 1/4 | lines 1-377 of 1320] -[Bash#Ybwi] cc-session inject 16d06326-... -> ok: [page 2/4 | lines 378-720 of 1320] -[Bash#iNMY] cc-session inject 16d06326-... -> ok: [page 3/4 | lines 721-1051 of 1320] -[Bash#iMqP] cc-session inject 16d06326-... -> ok: [page 4/4 | lines 1052-1320 of 1320] +[Bash#Y1dg] cc-session inherit 16d06326-... -> ok: [page 1/4 | lines 1-377 of 1320] +[Bash#Ybwi] cc-session inherit 16d06326-... -> ok: [page 2/4 | lines 378-720 of 1320] +[Bash#iNMY] cc-session inherit 16d06326-... -> ok: [page 3/4 | lines 721-1051 of 1320] +[Bash#iMqP] cc-session inherit 16d06326-... -> ok: [page 4/4 | lines 1052-1320 of 1320] ``` These lines carry zero information for the reader — the injected content was consumed by the AI in that session, and its conclusions already appear in the subsequent assistant messages. Showing 4 redundant lines wastes output space and context tokens when the output is fed back into another session. ## Decision -Collapse consecutive `cc-session inject/read/context` Bash tool calls targeting the same session into a single descriptive line: +Collapse consecutive `cc-session inherit/read/context` Bash tool calls targeting the same session into a single descriptive line: ``` -(cc-session: injected session 16d06326 here, 1320 lines omitted) +(cc-session: inherited session 16d06326 here, 1320 lines omitted) ``` The collapsing is: - **Automatic** — no flag required. The original tool call details remain accessible via `cc-session expand `. - **Scoped to cc-session CLI calls only** — other Bash tool calls (including the model fumbling with `which cc-session`, `node cc-session.mjs`, etc.) render normally as one-line summaries. - **Applied in both `read` and `context` output formats** — the collapsing logic lives in a shared `collapseCCSessionTools()` function called by both renderers' flush paths. +- **Backward compatible with `inject`** — older transcripts recorded before the `inject` → `inherit` CLI rename still contain literal `cc-session inject` calls. Those still collapse the same way, keeping their historical "injected" wording so old sessions read naturally. ### Detection -`parseCCSessionCommand(cmd)` checks if a Bash command matches `cc-session {inject|read|context} `. It returns the subcommand and an 8-char session ID prefix. Args starting with `-` (flags like `-h`) are rejected to avoid false positives. +`parseCCSessionCommand(cmd)` checks if a Bash command matches `cc-session {inherit|inject|read|context} `. It returns the subcommand and an 8-char session ID prefix. Args starting with `-` (flags like `-h`) are rejected to avoid false positives. ### Total lines extraction @@ -40,7 +41,8 @@ The collapsing is: ### Verb selection -- `inject` → "injected session X here" +- `inherit` → "inherited session X here" +- `inject` (legacy) → "injected session X here" - `read` / `context` → "loaded session X here" ## Consequences diff --git a/internal/formatter/formatter_test.go b/internal/formatter/formatter_test.go index b51dbd7..4dacd4c 100644 --- a/internal/formatter/formatter_test.go +++ b/internal/formatter/formatter_test.go @@ -833,7 +833,13 @@ func TestParseCCSessionCommand(t *testing.T) { wantSession string }{ { - name: "given inject with full uuid then returns inject and 8-char prefix", + name: "given inherit with full uuid then returns inherit and 8-char prefix", + cmd: "cc-session inherit 16d06326-977b-4c82-a38f-9b2358aa80ca", + wantSub: "inherit", + wantSession: "16d06326", + }, + { + name: "given legacy inject with full uuid then returns inject and 8-char prefix", cmd: "cc-session inject 16d06326-977b-4c82-a38f-9b2358aa80ca", wantSub: "inject", wantSession: "16d06326", @@ -934,10 +940,13 @@ func TestParseTotalLines(t *testing.T) { } } -func makeInjectEvents(sessionID string, pages int) []session.Event { +// makeInjectEvents builds a sequence of Bash tool-use/result events for a +// paginated "cc-session " call, e.g. "inherit" (current) +// or "inject" (legacy, kept for old transcripts). +func makeCCSessionEvents(subcommand, sessionID string, pages int) []session.Event { events := make([]session.Event, 0, pages*2) for p := 1; p <= pages; p++ { - toolID := fmt.Sprintf("inject-tool-%d", p) + toolID := fmt.Sprintf("%s-tool-%d", subcommand, p) events = append(events, session.Event{ Kind: session.EventAssistantMessage, @@ -948,8 +957,8 @@ func makeInjectEvents(sessionID string, pages int) []session.Event { ID: toolID, Name: "Bash", Input: session.ToolInput{Raw: map[string]any{ - "command": "cc-session inject " + sessionID, - "description": "Inject session", + "command": fmt.Sprintf("cc-session %s %s", subcommand, sessionID), + "description": "Load session", }}, }, }, @@ -968,6 +977,12 @@ func makeInjectEvents(sessionID string, pages int) []session.Event { return events } +// makeInjectEvents is a convenience wrapper for the legacy "cc-session inject" +// verb, used by tests that specifically cover pre-rename transcripts. +func makeInjectEvents(sessionID string, pages int) []session.Event { + return makeCCSessionEvents("inject", sessionID, pages) +} + func TestFormatReadEvents_GivenConsecutiveInjectCalls_WhenRendered_ThenCollapsesIntoOneLine(t *testing.T) { sessionID := "16d06326-977b-4c82-a38f-9b2358aa80ca" events := makeInjectEvents(sessionID, 4) @@ -990,6 +1005,28 @@ func TestFormatReadEvents_GivenConsecutiveInjectCalls_WhenRendered_ThenCollapses } } +func TestFormatReadEvents_GivenConsecutiveInheritCalls_WhenRendered_ThenCollapsesWithInheritedVerb(t *testing.T) { + sessionID := "16d06326-977b-4c82-a38f-9b2358aa80ca" + events := makeCCSessionEvents("inherit", sessionID, 4) + + var out bytes.Buffer + if err := FormatReadEvents(events, nil, 0, 0, FormatOptions{}, &out); err != nil { + t.Fatalf("FormatReadEvents returned error: %v", err) + } + got := out.String() + + want := "(cc-session#ol-1: inherited session 16d06326 here, 400 lines omitted)" + if !strings.Contains(got, want) { + t.Fatalf("expected collapsed inherit line with 'inherited' verb\nwant substring: %q\ngot:\n%s", want, got) + } + if strings.Contains(got, "[Bash") { + t.Fatalf("individual inherit Bash entries must not appear in output\ngot:\n%s", got) + } + if strings.Count(got, "cc-session#") > 1 { + t.Fatalf("must collapse to exactly one inherit summary line\ngot:\n%s", got) + } +} + func TestFormatReadEvents_GivenMixedToolsWithInject_WhenRendered_ThenOnlyCollapsesInjectOnes(t *testing.T) { sessionID := "16d06326-977b-4c82-a38f-9b2358aa80ca" injectEvents := makeInjectEvents(sessionID, 2) diff --git a/internal/formatter/render.go b/internal/formatter/render.go index 30af94d..279bce4 100644 --- a/internal/formatter/render.go +++ b/internal/formatter/render.go @@ -83,9 +83,9 @@ type pendingTool struct { toolUseID string summary string name string // e.g. "Bash", "Read", "Edit" - injectSessionID string // non-empty when this is a cc-session inject/read/context call + injectSessionID string // non-empty when this is a cc-session inherit/inject/read/context call injectTotalLines int // total lines from the last page marker - ccSubcommand string // "inject", "read", or "context" + ccSubcommand string // "inherit", "inject" (legacy), "read", or "context" } func loadEvents(transcriptPath string, isVerboseAgents bool, reader session.TranscriptReader) ([]session.Event, map[string]bool, error) { @@ -207,8 +207,10 @@ func injectShortID(summary string, shortID string) string { return summary[:idx] + "#" + shortID + summary[idx:] } -// parseCCSessionCommand checks if cmd is a cc-session inject/read/context command -// and returns the subcommand and session ID prefix (first 8 chars). +// parseCCSessionCommand checks if cmd is a cc-session inherit/inject/read/context +// command and returns the subcommand and session ID prefix (first 8 chars). +// "inject" is the legacy name for "inherit" (kept for old transcripts) and is +// treated as an equivalent verb for collapsing purposes. // Returns ("", "") if not a cc-session command. func parseCCSessionCommand(cmd string) (subcommand string, sessionID string) { fields := strings.Fields(strings.TrimSpace(cmd)) @@ -216,7 +218,7 @@ func parseCCSessionCommand(cmd string) (subcommand string, sessionID string) { return "", "" } switch fields[1] { - case "inject", "read", "context": + case "inherit", "inject", "read", "context": default: return "", "" } @@ -283,7 +285,13 @@ func collapseCCSessionTools(tools []pendingTool) []pendingTool { } last := tools[j-1] verb := "loaded" - if pt.ccSubcommand == "inject" { + switch pt.ccSubcommand { + case "inherit": + verb = "inherited" + case "inject": + // Legacy verb: old transcripts recorded "cc-session inject" before + // the CLI rename to "inherit". Keep the historical wording so old + // sessions still read naturally. verb = "injected" } shortID := session.ToolShortID(pt.toolUseID) diff --git a/internal/inject/inject.go b/internal/inject/inject.go index 51518b1..9ef236a 100644 --- a/internal/inject/inject.go +++ b/internal/inject/inject.go @@ -1,4 +1,5 @@ -// Package inject implements paginated session output for the inject subcommand. +// Package inject implements paginated session output for the inherit subcommand +// (formerly named "inject"; the CLI-facing name changed, this package did not). // Each page stays under 20K chars so Claude Code's Bash tool returns it as // stdout rather than persisting it to a file. package inject @@ -138,7 +139,7 @@ func WritePage(pageLines []string, pageNum, totalPages, startLine, totalLines in fmt.Fprintln(out) } if pageNum == totalPages { - fmt.Fprintf(out, "[inject complete: %d pages, %d lines] — use -reset to start over\n", totalPages, totalLines) + fmt.Fprintf(out, "[inherit complete: %d pages, %d lines] — use -reset to start over\n", totalPages, totalLines) } else { fmt.Fprintf(out, "[page %d/%d complete — run again for next page]\n", pageNum, totalPages) } diff --git a/internal/inject/inject_test.go b/internal/inject/inject_test.go index dc6e911..8c745a6 100644 --- a/internal/inject/inject_test.go +++ b/internal/inject/inject_test.go @@ -178,7 +178,7 @@ func TestGivenMiddlePage_WhenWritePage_ThenContinueFooterAppears(t *testing.T) { if !strings.Contains(out, "[page 1/3 complete — run again for next page]") { t.Errorf("missing continue footer in: %q", out) } - if strings.Contains(out, "inject complete") { + if strings.Contains(out, "inherit complete") { t.Errorf("should not have complete footer for middle page") } } @@ -190,7 +190,7 @@ func TestGivenLastPage_WhenWritePage_ThenCompleteFooterAppears(t *testing.T) { if !strings.Contains(out, "[page 3/3 | lines 91-91 of 100]") { t.Errorf("missing header in: %q", out) } - if !strings.Contains(out, "[inject complete: 3 pages, 100 lines]") { + if !strings.Contains(out, "[inherit complete: 3 pages, 100 lines]") { t.Errorf("missing complete footer in: %q", out) } if !strings.Contains(out, "use -reset to start over") { @@ -202,7 +202,7 @@ func TestGivenOnlyOnePage_WhenWritePage_ThenCompleteFooterAppears(t *testing.T) var sb strings.Builder inject.WritePage([]string{"only line"}, 1, 1, 0, 1, &sb) out := sb.String() - if !strings.Contains(out, "[inject complete: 1 pages, 1 lines]") { + if !strings.Contains(out, "[inherit complete: 1 pages, 1 lines]") { t.Errorf("missing complete footer in: %q", out) } if !strings.Contains(out, "use -reset to start over") {