Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Gmail: keep label IDs case-sensitive during label resolution and duplicate-name checks while still matching label names case-insensitively.
- Gmail: clarify that `gmail drafts delete` permanently deletes drafts and cannot be recovered. (#656, #659) — thanks @chrischall.
- Sheets: add `--inherit-from-before` to `sheets insert` so callers can choose whether inserted rows/columns inherit formatting from the preceding or following neighbor. (#655, #658) — thanks @chrischall.
- Docs: update the bundled `gog` agent skill to preserve broad user OAuth scopes during reauth and rely on command guards for scoped execution.

## 0.19.0 - 2026-05-22
Expand Down
1 change: 1 addition & 0 deletions docs/commands/gog-sheets-insert.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ gog sheets (sheet) insert <spreadsheetId> <sheet> <dimension> <start> [flags]
| `--gmail-no-send` | `bool` | false | Block Gmail send operations (agent safety) |
| `-h`<br>`--help` | `kong.helpFlag` | | Show context-sensitive help. |
| `--home` | `string` | | Override gogcli config/data/state/cache root (equivalent to GOG_HOME) |
| `--inherit-from-before` | `*bool` | | Inherit number format / styling from the row/column before the insertion. Defaults to true with --after, false otherwise; false inherits from the row/column after the insertion. |
| `-j`<br>`--json`<br>`--machine` | `bool` | false | Output JSON to stdout (best for scripting) |
| `--no-input`<br>`--non-interactive`<br>`--noninteractive` | `bool` | | Never prompt; fail instead (useful for CI) |
| `-p`<br>`--plain`<br>`--tsv` | `bool` | false | Output stable, parseable text to stdout (TSV; no colors) |
Expand Down
11 changes: 11 additions & 0 deletions internal/cmd/sheets_insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ type SheetsInsertCmd struct {
Start int64 `arg:"" name:"start" help:"Position before which to insert (1-based; for cols 1=A, 2=B)"`
Count int64 `name:"count" help:"Number of rows/columns to insert" default:"1"`
After bool `name:"after" help:"Insert after the position instead of before"`
// *bool so an unset flag keeps the historical default (inherit only when
// --after); passing --inherit-from-before[=false] overrides it explicitly.
InheritFromBefore *bool `name:"inherit-from-before" help:"Inherit number format / styling from the row/column before the insertion. Defaults to true with --after, false otherwise; false inherits from the row/column after the insertion."`
}

func (c *SheetsInsertCmd) Run(ctx context.Context, flags *RootFlags) error {
Expand Down Expand Up @@ -58,7 +61,15 @@ func (c *SheetsInsertCmd) Run(ctx context.Context, flags *RootFlags) error {
startIndex = c.Start
}
endIndex := startIndex + c.Count
// Default: inherit formatting only when inserting after an existing line.
// An explicit --inherit-from-before[=false] overrides that default.
inheritFromBefore := c.After
if c.InheritFromBefore != nil {
inheritFromBefore = *c.InheritFromBefore
}
if inheritFromBefore && startIndex == 0 {
return usagef("cannot inherit from the previous %s when inserting at position 1", dimLabel)
}

if dryRunErr := dryRunExit(ctx, flags, "sheets.insert", map[string]any{
"spreadsheet_id": spreadsheetID,
Expand Down
52 changes: 52 additions & 0 deletions internal/cmd/sheets_insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,58 @@ func TestSheetsInsertCmd(t *testing.T) {
}
})

t.Run("insert after inheriting from following dimension", func(t *testing.T) {
gotInsert = nil
cmd := &SheetsInsertCmd{}
if err := runKong(t, cmd, []string{
"s1", "Data", "rows", "2", "--count", "1", "--after", "--inherit-from-before=false",
}, ctx, flags); err != nil {
t.Fatalf("insert rows: %v", err)
}
if gotInsert == nil {
t.Fatal("expected insertDimension request")
}
// --after would default inheritFromBefore=true; the explicit flag overrides it
// so the API inherits from the following adjacent row/column instead.
if gotInsert.InheritFromBefore {
t.Fatal("expected inheritFromBefore=false when --inherit-from-before=false overrides --after")
}
})

t.Run("insert before with explicit inherit", func(t *testing.T) {
gotInsert = nil
cmd := &SheetsInsertCmd{}
if err := runKong(t, cmd, []string{
"s1", "Data", "rows", "2", "--count", "1", "--inherit-from-before",
}, ctx, flags); err != nil {
t.Fatalf("insert rows: %v", err)
}
if gotInsert == nil {
t.Fatal("expected insertDimension request")
}
// before-insert defaults inheritFromBefore=false; the explicit flag overrides it.
if !gotInsert.InheritFromBefore {
t.Fatal("expected inheritFromBefore=true when --inherit-from-before is set")
}
})

t.Run("reject inherit from before at first row", func(t *testing.T) {
gotInsert = nil
cmd := &SheetsInsertCmd{}
err := runKong(t, cmd, []string{
"s1", "Data", "rows", "1", "--inherit-from-before",
}, ctx, flags)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "cannot inherit from the previous row") {
t.Fatalf("unexpected error: %v", err)
}
if gotInsert != nil {
t.Fatal("did not expect API request")
}
})

t.Run("insert cols before", func(t *testing.T) {
gotInsert = nil
cmd := &SheetsInsertCmd{}
Expand Down
Loading