diff --git a/shortcuts/sheets/data/flag-defs.json b/shortcuts/sheets/data/flag-defs.json
new file mode 100644
index 000000000..7e8a0d2f1
--- /dev/null
+++ b/shortcuts/sheets/data/flag-defs.json
@@ -0,0 +1,4598 @@
+{
+ "+workbook-info": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet locator"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet locator"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "title",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "New sheet title"
+ },
+ {
+ "name": "index",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Insert position; appended to the end when omitted",
+ "default": "-1"
+ },
+ {
+ "name": "row-count",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Initial row count (default 200, max 50000)",
+ "default": "200"
+ },
+ {
+ "name": "col-count",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Initial column count (default 20, max 200)",
+ "default": "20"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm high-risk write (exit code 10 without this flag)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-rename": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "title",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "New title"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-move": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "index",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Target position (0-based)"
+ },
+ {
+ "name": "source-index",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Source position (0-based); optional. If omitted, the CLI runtime derives it from the current workbook index of `--sheet-id` / `--sheet-name`",
+ "default": "-1"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-copy": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "title",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Copy title; auto-generated by the server when omitted"
+ },
+ {
+ "name": "index",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Insert position for the copy (0-based); appended to the end when omitted",
+ "default": "-1"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-hide": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-unhide": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-set-tab-color": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "color",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Hex color like `#FF0000`; pass empty string `\"\"` to clear"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+workbook-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "title",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Spreadsheet title"
+ },
+ {
+ "name": "folder-token",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Target folder token; placed at the drive root when omitted"
+ },
+ {
+ "name": "headers",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Header row as a JSON array: `[\"Col A\",\"Col B\"]`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "values",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Initial data as a 2D JSON array: `[[\"alice\",95]]`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+workbook-export": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "file-extension",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Export file format; `csv` mode requires `--sheet-id`",
+ "default": "xlsx",
+ "enum": [
+ "xlsx",
+ "csv"
+ ]
+ },
+ {
+ "name": "sheet-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Required only in csv mode: the sheet reference_id to export"
+ },
+ {
+ "name": "output-path",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Local save path; export is triggered but not downloaded when omitted"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sheet-info": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "include",
+ "kind": "own",
+ "type": "string_slice",
+ "required": "optional",
+ "desc": "Comma-separated structure info categories to return",
+ "enum": [
+ "merges",
+ "row_heights",
+ "col_widths",
+ "hidden_rows",
+ "hidden_cols",
+ "groups",
+ "frozen"
+ ]
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Limit structure info to this A1 range; whole sheet when omitted"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-insert": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Insert start position (0-based)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Insert end position (exclusive)"
+ },
+ {
+ "name": "inherit-style",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Style inheritance for the new row/column: `before` (from preceding) / `after` (from following) / `none` (default)",
+ "default": "none",
+ "enum": [
+ "before",
+ "after",
+ "none"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start position (0-based)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End position (exclusive)"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); row/column deletion is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-hide": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start position (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End position (0-based, inclusive)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-unhide": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start position (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End position (0-based, inclusive)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-freeze": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "count",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Freeze the first N rows/columns; pass 0 to unfreeze"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-group": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start position (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End position (0-based, inclusive)"
+ },
+ {
+ "name": "depth",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Nesting level (used by `+dim-group`); default 1",
+ "default": "1"
+ },
+ {
+ "name": "group-state",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Initial group expand state",
+ "default": "expand",
+ "enum": [
+ "expand",
+ "fold"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-ungroup": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start position (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End position (0-based, inclusive)"
+ },
+ {
+ "name": "depth",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Nesting level (used by `+dim-group`); default 1",
+ "default": "1"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dim-move": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dimension",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Dimension (row or column)",
+ "enum": [
+ "row",
+ "column"
+ ]
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Source range start position (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Source range end position (0-based, inclusive)"
+ },
+ {
+ "name": "target",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Destination position (move target inserts before this index; 0-based)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-get": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string_array",
+ "required": "required",
+ "desc": "A1 range, e.g. `Sheet1!A1:F10`"
+ },
+ {
+ "name": "include",
+ "kind": "own",
+ "type": "string_slice",
+ "required": "optional",
+ "desc": "Comma-separated info categories to include",
+ "enum": [
+ "value",
+ "formula",
+ "style",
+ "comment",
+ "data_validation"
+ ]
+ },
+ {
+ "name": "cell-limit",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 5000",
+ "default": "5000",
+ "hidden": true
+ },
+ {
+ "name": "max-chars",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 200000",
+ "default": "200000",
+ "hidden": true
+ },
+ {
+ "name": "skip-hidden",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Skip hidden rows and columns; default `false`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dropdown-get": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target range (A1 notation; must include the sheet prefix, e.g. `sheet1!A2:A100`)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+csv-get": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "A1 range; reads the whole sheet's `current_region` when omitted"
+ },
+ {
+ "name": "value-render-option",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Cell value render mode",
+ "default": "formatted_value",
+ "enum": [
+ "formatted_value",
+ "raw_value",
+ "formula"
+ ]
+ },
+ {
+ "name": "max-rows",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 100000",
+ "default": "100000",
+ "hidden": true
+ },
+ {
+ "name": "max-chars",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 200000",
+ "default": "200000",
+ "hidden": true
+ },
+ {
+ "name": "include-row-prefix",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Whether to prefix each row with `[row=N]`; default `true`",
+ "default": "true"
+ },
+ {
+ "name": "skip-hidden",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Skip hidden rows and columns; default `false`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Print the request path and parameters without executing"
+ }
+ ]
+ },
+ "+cells-search": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "find",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Text to find (interpreted as regex when `--regex` is set)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Search range (A1 notation); whole sheet when omitted"
+ },
+ {
+ "name": "match-case",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Case-sensitive match"
+ },
+ {
+ "name": "match-entire-cell",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Match the entire cell content"
+ },
+ {
+ "name": "regex",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Interpret `--find` as a regex pattern"
+ },
+ {
+ "name": "include-formulas",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Also search within formula text"
+ },
+ {
+ "name": "max-matches",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 5000",
+ "default": "5000",
+ "hidden": true
+ },
+ {
+ "name": "offset",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Skip the first N matches (for pagination); default 0",
+ "default": "0"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-replace": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "find",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Text to find for replacement"
+ },
+ {
+ "name": "replacement",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Replacement text; pass empty string `\"\"` to delete matched content"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Replace range (A1 notation); whole sheet when omitted"
+ },
+ {
+ "name": "match-case",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Case-sensitive match"
+ },
+ {
+ "name": "match-entire-cell",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Match the entire cell content"
+ },
+ {
+ "name": "regex",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Interpret `--find` as a regex pattern"
+ },
+ {
+ "name": "include-formulas",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Also replace within formula text"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Required preflight: outputs `would_replace_count` for user confirmation before the actual replace"
+ }
+ ]
+ },
+ "+cells-set": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Write range (A1 notation)"
+ },
+ {
+ "name": "cells",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON 2D array `[[{cell},...],...]`, dimensions must match `--range`; each cell may carry `value` / `formula` / `cell_styles` / `note` / `rich_text` (incl. `type=\"embed-image\"` in-cell image); run `--print-schema` for full fields",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "allow-overwrite",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Allow overwriting non-empty cells (default true); set false to error if any target cell is non-empty",
+ "default": "true"
+ },
+ {
+ "name": "max-cells",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Safety cap; default 50000",
+ "default": "50000",
+ "hidden": true
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-set-style": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target range (A1 notation, e.g. `A1:B2`)"
+ },
+ {
+ "name": "background-color",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Background color (hex, e.g. `#ffffff`)"
+ },
+ {
+ "name": "font-color",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font color (hex, e.g. `#000000`)"
+ },
+ {
+ "name": "font-size",
+ "kind": "own",
+ "type": "float64",
+ "required": "optional",
+ "desc": "Font size in px (e.g. 10, 12, 14)"
+ },
+ {
+ "name": "font-style",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font style",
+ "enum": [
+ "normal",
+ "italic"
+ ]
+ },
+ {
+ "name": "font-weight",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font weight",
+ "enum": [
+ "normal",
+ "bold"
+ ]
+ },
+ {
+ "name": "font-line",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font line style",
+ "enum": [
+ "none",
+ "underline",
+ "line-through"
+ ]
+ },
+ {
+ "name": "horizontal-alignment",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Horizontal alignment",
+ "enum": [
+ "left",
+ "center",
+ "right"
+ ]
+ },
+ {
+ "name": "vertical-alignment",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Vertical alignment",
+ "enum": [
+ "top",
+ "middle",
+ "bottom"
+ ]
+ },
+ {
+ "name": "word-wrap",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Word-wrap strategy",
+ "enum": [
+ "overflow",
+ "auto-wrap",
+ "word-clip"
+ ]
+ },
+ {
+ "name": "number-format",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Number format pattern (e.g. text `@`, number `0.00`, currency `$#,##0.00`, date `mm/dd/yyyy`)"
+ },
+ {
+ "name": "border-styles",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Border config JSON: `{ top: {style,color,weight}, bottom: ..., left: ..., right: ... }`; same shape for all 4 sides",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-set-image": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target cell (A1 notation; must be a single cell, e.g. `A1`; start and end must be identical)"
+ },
+ {
+ "name": "image",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Local image path (PNG / JPEG / JPG / GIF / BMP / JFIF / EXIF / TIFF / BPG / HEIC)"
+ },
+ {
+ "name": "name",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Image file name (with extension); defaults to the basename of `--image`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dropdown-set": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target range (A1 notation, e.g. `A2:A100`)"
+ },
+ {
+ "name": "options",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Options as a JSON array, e.g. `[\"opt1\",\"opt2\"]`; up to 500 items, each ≤100 chars, no commas",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "colors",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "RGB hex color array (e.g. `[\"#1FB6C1\",\"#F006C2\"]`); length must equal `--options`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "multiple",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Enable multi-select; default `false`"
+ },
+ {
+ "name": "highlight",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Color-highlight options; default `false`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+csv-put": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "start-cell",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Top-left A1 anchor (e.g. `Sheet1!A1`); the bottom-right is inferred from CSV row/column counts",
+ "default": "A1"
+ },
+ {
+ "name": "csv",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "RFC 4180 CSV text; plain values only (no formulas / styles / comments)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "allow-overwrite",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Allow overwriting (default true); set false to error if any target cell is non-empty",
+ "default": "true"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-clear": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Range to clear (A1 notation)"
+ },
+ {
+ "name": "scope",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Clear scope: `content` (default, values only) / `formats` (formats only) / `all` (values and formats)",
+ "default": "content",
+ "enum": [
+ "content",
+ "formats",
+ "all"
+ ]
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); clear is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-merge": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Range to merge / unmerge (A1 notation)"
+ },
+ {
+ "name": "merge-type",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Merge direction (`+cells-merge` only)",
+ "default": "all",
+ "enum": [
+ "all",
+ "rows",
+ "columns"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cells-unmerge": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Range to merge / unmerge (A1 notation)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+rows-resize": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start row (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End row (0-based, inclusive)"
+ },
+ {
+ "name": "type",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Sizing mode: `pixel` (explicit px value, requires `--size`) / `standard` (reset to default row height) / `auto` (fit content)",
+ "enum": [
+ "pixel",
+ "standard",
+ "auto"
+ ]
+ },
+ {
+ "name": "size",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Row height in pixels (e.g. 30 / 40 / 60); required when `--type pixel`, ignored otherwise",
+ "default": "0"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cols-resize": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "start",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Start column (0-based, inclusive)"
+ },
+ {
+ "name": "end",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "End column (0-based, inclusive)"
+ },
+ {
+ "name": "type",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Sizing mode: `pixel` (explicit px value, requires `--size`) / `standard` (reset to default column width)",
+ "enum": [
+ "pixel",
+ "standard"
+ ]
+ },
+ {
+ "name": "size",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Column width in pixels (e.g. 80 / 120 / 200); required when `--type pixel`, ignored otherwise",
+ "default": "0"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+range-move": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "source-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Source A1 range"
+ },
+ {
+ "name": "target-sheet-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Destination sub-sheet id; defaults to the same sheet as the source"
+ },
+ {
+ "name": "target-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Destination A1 range (anchor cell is enough; size inferred from the source)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+range-copy": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "source-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Source A1 range"
+ },
+ {
+ "name": "target-sheet-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Destination sub-sheet id; defaults to the same sheet as the source"
+ },
+ {
+ "name": "target-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Destination A1 range (anchor cell is enough; size inferred from the source)"
+ },
+ {
+ "name": "paste-type",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Paste content type (`+range-copy` only)",
+ "default": "all",
+ "enum": [
+ "values",
+ "formulas",
+ "formats",
+ "all"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+range-fill": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "source-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Fill template range (seed cells for the series)"
+ },
+ {
+ "name": "target-range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Destination fill range (A1 notation)"
+ },
+ {
+ "name": "series-type",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Fill series type",
+ "default": "auto",
+ "enum": [
+ "auto",
+ "linear",
+ "growth",
+ "date",
+ "copy"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+range-sort": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Sort range (A1 notation; whether the header is included depends on `--has-header`)"
+ },
+ {
+ "name": "sort-keys",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON array: `[{\"column\":\"
\",\"ascending\":}, ...]`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "has-header",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Treat the first row as a header and exclude from sort; default `false`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+batch-update": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet locator (independent from per-operation sheet locator)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet locator (independent from per-operation sheet locator)"
+ },
+ {
+ "name": "operations",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON array: `[{\"tool_name\":\"set_cell_range\",\"input\":{...}}, ...]`, executed serially; `tool_name` is the underlying tool name (e.g. `set_cell_range` / `clear_cell_range` / `modify_sheet_structure`)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "continue-on-error",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Continue with remaining operations when a sub-operation fails; default false (abort on first failure)"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm high-risk write (exit code 10 without this flag)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Print the request template for each sub-operation; no network side effects"
+ }
+ ]
+ },
+ "+cells-batch-set-style": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "ranges",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target ranges as a JSON array (e.g. `[\"sheet1!A1:B2\",\"sheet1!D1:D10\"]`); each item must include the sheet prefix; the same style is applied to all ranges",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "background-color",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Background color (hex, e.g. `#ffffff`)"
+ },
+ {
+ "name": "font-color",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font color (hex, e.g. `#000000`)"
+ },
+ {
+ "name": "font-size",
+ "kind": "own",
+ "type": "float64",
+ "required": "optional",
+ "desc": "Font size in px (e.g. 10, 12, 14)"
+ },
+ {
+ "name": "font-style",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font style",
+ "enum": [
+ "normal",
+ "italic"
+ ]
+ },
+ {
+ "name": "font-weight",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font weight",
+ "enum": [
+ "normal",
+ "bold"
+ ]
+ },
+ {
+ "name": "font-line",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Font line style",
+ "enum": [
+ "none",
+ "underline",
+ "line-through"
+ ]
+ },
+ {
+ "name": "horizontal-alignment",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Horizontal alignment",
+ "enum": [
+ "left",
+ "center",
+ "right"
+ ]
+ },
+ {
+ "name": "vertical-alignment",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Vertical alignment",
+ "enum": [
+ "top",
+ "middle",
+ "bottom"
+ ]
+ },
+ {
+ "name": "word-wrap",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Word-wrap strategy",
+ "enum": [
+ "overflow",
+ "auto-wrap",
+ "word-clip"
+ ]
+ },
+ {
+ "name": "number-format",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Number format pattern (e.g. text `@`, number `0.00`, currency `$#,##0.00`, date `mm/dd/yyyy`)"
+ },
+ {
+ "name": "border-styles",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Border config JSON (same shape as in +cells-set-style)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dropdown-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "ranges",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target ranges as a JSON array (e.g. `[\"sheet1!A2:A100\"]`); each item must include the sheet prefix",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "options",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Options as a JSON array (e.g. `[\"opt1\",\"opt2\"]`)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "colors",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Color array (same length as `--options`)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "multiple",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Enable multi-select"
+ },
+ {
+ "name": "highlight",
+ "kind": "own",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Color-highlight options"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+dropdown-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "ranges",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target ranges as a JSON array (up to 100 items; each must include the sheet prefix)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm high-risk write (exit code 10 without this flag)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+chart-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "chart-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter to a single chart reference_id"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+chart-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Full chart config JSON (`position` / `data` / `properties` etc.); deeply nested, must be passed as JSON",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": "Print the request template; no side effects"
+ }
+ ]
+ },
+ "+chart-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "chart-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target chart reference_id"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Full or sufficiently complete chart config JSON (read back with `+chart-list` first, then patch)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+chart-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "chart-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target chart reference_id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+pivot-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "pivot-table-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter by id"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+pivot-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON: `{\"data_range\":\"Sheet1!A1:F1000\",\"rows\":[...],\"columns\":[...],\"values\":[...],\"filters\":[...],\"show_row_grand_total\":true,\"show_col_grand_total\":true}`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "target-sheet-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Destination sub-sheet id for the pivot table; auto-creates a new sub-sheet when omitted (recommended)"
+ },
+ {
+ "name": "target-position",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Destination anchor cell (A1 notation, e.g. `A1`); default `A1`",
+ "default": "A1"
+ },
+ {
+ "name": "source",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Pivot table source range (A1 notation; format `SheetName!StartCell:EndCell`, e.g. `Sheet1!A1:D100`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Pivot table placement (single A1 anchor for the top-left, e.g. `F1`); placed at the top-left of a newly created sub-sheet when omitted"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+pivot-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "pivot-table-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target pivot table id"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Full or sufficiently complete pivot config (read back with `+pivot-list --pivot-table-id ` first, then patch)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+pivot-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "pivot-table-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target pivot table id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cond-format-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "rule-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter by rule id"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cond-format-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Rule config JSON: `style` (required, applied on match), `attrs?` (rule-type-dependent params), `has_ref?`. `rule_type` and `ranges` are separate flags",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "rule-type",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Conditional format rule type; takes precedence over the same-named field inside `--properties`",
+ "enum": [
+ "cellValue",
+ "formula",
+ "duplicate",
+ "unique",
+ "topBottom",
+ "aboveBelowAverage",
+ "dataBar",
+ "colorScale",
+ "iconSet",
+ "textContains",
+ "dateOccurring",
+ "blankCell",
+ "errorCell"
+ ]
+ },
+ {
+ "name": "ranges",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "A1 ranges where the conditional format applies, as a JSON array (e.g. `[\"A1:A100\",\"C2:C50\"]`); takes precedence over the same-named field inside `--properties`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cond-format-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "rule-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target rule id"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Rule config JSON, same shape as `+cond-format-create --properties`; update overwrites the entire rule",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "rule-type",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Conditional format rule type; takes precedence over the same-named field inside `--properties`",
+ "enum": [
+ "cellValue",
+ "formula",
+ "duplicate",
+ "unique",
+ "topBottom",
+ "aboveBelowAverage",
+ "dataBar",
+ "colorScale",
+ "iconSet",
+ "textContains",
+ "dateOccurring",
+ "blankCell",
+ "errorCell"
+ ]
+ },
+ {
+ "name": "ranges",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "A1 ranges where the conditional format applies, as a JSON array (e.g. `[\"A1:A100\",\"C2:C50\"]`); takes precedence over the same-named field inside `--properties`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+cond-format-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "rule-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target rule id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Filter range (A1 notation, including header row, e.g. `A1:F1000`); do not duplicate the range field inside `--properties`"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter rule JSON: `rules` (required, per-column rule array), `filtered_columns?` (active column index hint). `range` is a separate flag (do not duplicate inside this JSON)",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Filter rule JSON: `rules` and `filtered_columns?`; update overwrites the entire rule set (pass `rules: []` to clear). `range` is a separate flag",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Range the filter applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-view-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "view-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter by filter-view reference_id (returns the matching single view)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-view-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Filter-view rule JSON: `rules?` (per-column rule array), `filtered_columns?`. `range` and `view_name` are separate flags",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Range the filter view applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`; required on create and must cover the header row"
+ },
+ {
+ "name": "view-name",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter-view name; auto-assigned by the server when omitted on create, kept unchanged when omitted on update; takes precedence over the same-named field inside `--properties`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-view-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "view-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target filter-view reference_id"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Filter-view rule JSON: `rules?`, `filtered_columns?`. `range` and `view_name` are separate flags; pass at least one of `--properties.rules` / `--range` / `--view-name`",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "range",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Range the filter view applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`; omit to keep the current range on update"
+ },
+ {
+ "name": "view-name",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter-view name; auto-assigned by the server when omitted on create, kept unchanged when omitted on update; takes precedence over the same-named field inside `--properties`"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+filter-view-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "view-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target filter-view reference_id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm high-risk write (exit code 10 without this flag)"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sparkline-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "group-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter by group_id"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sparkline-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON: `{config (shared style), sparklines (array of mini-charts)}`; run `--print-schema` for the full structure",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sparkline-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "group-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target group id"
+ },
+ {
+ "name": "properties",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "JSON: `{config, sparklines}`; read back with `+sparkline-list --group-id ` first, then patch; run `--print-schema` for the full structure",
+ "input": [
+ "file",
+ "stdin"
+ ]
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+sparkline-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "group-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target group id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+float-image-list": {
+ "risk": "read",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "float-image-id",
+ "kind": "own",
+ "type": "string",
+ "required": "optional",
+ "desc": "Filter by id; lists all float images on the sheet when omitted"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+float-image-create": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "image-name",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Image name, including extension (e.g. `logo.png`)"
+ },
+ {
+ "name": "image-token",
+ "kind": "own",
+ "type": "string",
+ "required": "xor",
+ "desc": "Image file_token (XOR with `--image-uri`). Common source: `image_token` returned by `+float-image-list`"
+ },
+ {
+ "name": "image-uri",
+ "kind": "own",
+ "type": "string",
+ "required": "xor",
+ "desc": "Image reference_id (XOR with `--image-token`); a prefixed string like `<|image|>:abcdef`"
+ },
+ {
+ "name": "position-row",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Row anchor of the image's top-left corner (0-based)"
+ },
+ {
+ "name": "position-col",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Column anchor of the image's top-left corner (column letter, e.g. `A` / `B`)"
+ },
+ {
+ "name": "size-width",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Image width in pixels"
+ },
+ {
+ "name": "size-height",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Image height in pixels"
+ },
+ {
+ "name": "offset-row",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Pixel offset within the anchor row, on top of `--position-row`"
+ },
+ {
+ "name": "offset-col",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Pixel offset within the anchor column, on top of `--position-col`"
+ },
+ {
+ "name": "z-index",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Image z-index controlling stacking order"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+float-image-update": {
+ "risk": "write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "float-image-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target float image id"
+ },
+ {
+ "name": "image-name",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Image name, including extension (e.g. `logo.png`)"
+ },
+ {
+ "name": "image-token",
+ "kind": "own",
+ "type": "string",
+ "required": "xor",
+ "desc": "Image file_token (XOR with `--image-uri`). Common source: `image_token` returned by `+float-image-list`"
+ },
+ {
+ "name": "image-uri",
+ "kind": "own",
+ "type": "string",
+ "required": "xor",
+ "desc": "Image reference_id (XOR with `--image-token`); a prefixed string like `<|image|>:abcdef`"
+ },
+ {
+ "name": "position-row",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Row anchor of the image's top-left corner (0-based)"
+ },
+ {
+ "name": "position-col",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Column anchor of the image's top-left corner (column letter, e.g. `A` / `B`)"
+ },
+ {
+ "name": "size-width",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Image width in pixels"
+ },
+ {
+ "name": "size-height",
+ "kind": "own",
+ "type": "int",
+ "required": "required",
+ "desc": "Image height in pixels"
+ },
+ {
+ "name": "offset-row",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Pixel offset within the anchor row, on top of `--position-row`"
+ },
+ {
+ "name": "offset-col",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Pixel offset within the anchor column, on top of `--position-col`"
+ },
+ {
+ "name": "z-index",
+ "kind": "own",
+ "type": "int",
+ "required": "optional",
+ "desc": "Image z-index controlling stacking order"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ },
+ "+float-image-delete": {
+ "risk": "high-risk-write",
+ "flags": [
+ {
+ "name": "url",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)"
+ },
+ {
+ "name": "spreadsheet-token",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Spreadsheet token (XOR with `--url`)"
+ },
+ {
+ "name": "sheet-id",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet reference_id (XOR with `--sheet-name`)"
+ },
+ {
+ "name": "sheet-name",
+ "kind": "public",
+ "type": "string",
+ "required": "xor",
+ "desc": "Sheet name (XOR with `--sheet-id`)"
+ },
+ {
+ "name": "float-image-id",
+ "kind": "own",
+ "type": "string",
+ "required": "required",
+ "desc": "Target float image id"
+ },
+ {
+ "name": "yes",
+ "kind": "system",
+ "type": "bool",
+ "required": "required",
+ "desc": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
+ },
+ {
+ "name": "dry-run",
+ "kind": "system",
+ "type": "bool",
+ "required": "optional",
+ "desc": ""
+ }
+ ]
+ }
+}
diff --git a/shortcuts/sheets/data/flag-descriptions.en.json b/shortcuts/sheets/data/flag-descriptions.en.json
deleted file mode 100644
index 22e25ce10..000000000
--- a/shortcuts/sheets/data/flag-descriptions.en.json
+++ /dev/null
@@ -1,634 +0,0 @@
-{
- "+workbook-info": {
- "--url": "Spreadsheet locator",
- "--spreadsheet-token": "Spreadsheet locator",
- "--include-properties": "Whether to include each sheet's extended properties; default `true`"
- },
- "+sheet-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--title": "New sheet title",
- "--index": "Insert position; appended to the end when omitted",
- "--row-count": "Initial row count; default 100",
- "--col-count": "Initial column count; default 26"
- },
- "+sheet-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--yes": "Confirm high-risk write (exit code 10 without this flag)"
- },
- "+sheet-rename": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--title": "New title"
- },
- "+sheet-move": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--index": "Target position (0-based)",
- "--source-index": "Source position (0-based); optional. If omitted, the CLI runtime derives it from the current workbook index of `--sheet-id` / `--sheet-name`"
- },
- "+sheet-copy": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--title": "Copy title; auto-generated by the server when omitted",
- "--index": "Insert position for the copy (0-based); appended to the end when omitted"
- },
- "+sheet-hide": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)"
- },
- "+sheet-unhide": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)"
- },
- "+sheet-set-tab-color": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--color": "Hex color like `#FF0000`; pass empty string `\"\"` to clear"
- },
- "+workbook-create": {
- "--title": "Spreadsheet title",
- "--folder-token": "Target folder token; placed at the drive root when omitted",
- "--headers": "Header row as a JSON array: `[\"Col A\",\"Col B\"]`",
- "--values": "Initial data as a 2D JSON array: `[[\"alice\",95]]`"
- },
- "+workbook-export": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--file-extension": "`xlsx` / `csv`; default `xlsx`. `csv` mode requires `--sheet-id`",
- "--sheet-id": "Required only in csv mode: the sheet reference_id to export",
- "--output-path": "Local save path; export is triggered but not downloaded when omitted"
- },
- "+sheet-info": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--include": "Comma-separated subset of `merges` / `row_heights` / `col_widths` / `hidden_rows` / `hidden_cols` / `groups` / `frozen`"
- },
- "+dim-insert": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "Insert start position (0-based)",
- "--end": "Insert end position (exclusive)",
- "--inherit-style": "Style inheritance for the new row/column: `before` (from preceding) / `after` (from following) / `none` (default)"
- },
- "+dim-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "Start position (0-based)",
- "--end": "End position (exclusive)",
- "--yes": "Confirm destructive write (exit code 10 without this flag); row/column deletion is irreversible"
- },
- "+dim-hide": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "End position (0-based, inclusive)",
- "--end": "End position (0-based, inclusive)"
- },
- "+dim-unhide": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "End position (0-based, inclusive)",
- "--end": "End position (0-based, inclusive)"
- },
- "+dim-freeze": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--count": "Freeze the first N rows/columns; pass 0 to unfreeze"
- },
- "+dim-group": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "End position (0-based, inclusive)",
- "--end": "End position (0-based, inclusive)",
- "--depth": "Nesting level (used by `+dim-group`); default 1"
- },
- "+dim-ungroup": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "End position (0-based, inclusive)",
- "--end": "End position (0-based, inclusive)",
- "--depth": "Nesting level (used by `+dim-group`); default 1"
- },
- "+dim-move": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--dimension": "`row` / `column`",
- "--start": "Source range start position (0-based, inclusive)",
- "--end": "Source range end position (0-based, inclusive)",
- "--target": "Destination position (move target inserts before this index; 0-based)"
- },
- "+cells-get": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "A1 range, e.g. `Sheet1!A1:F10`",
- "--include": "Comma-separated subset of `value` / `formula` / `style` / `comment` / `data_validation`",
- "--cell-limit": "Safety cap; default 5000",
- "--max-chars": "Safety cap; default 200000",
- "--skip-hidden": "Skip hidden rows and columns; default `false`"
- },
- "+dropdown-get": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--range": "Target range (A1 notation; must include the sheet prefix, e.g. `sheet1!A2:A100`)"
- },
- "+csv-get": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "A1 range; reads the whole sheet's `current_region` when omitted",
- "--value-render-option": "Cell value render mode: `ToString` / `FormattedValue` / `Formula` / `UnformattedValue`",
- "--max-rows": "Safety cap; default 100000",
- "--max-chars": "Safety cap; default 200000",
- "--include-row-prefix": "Whether to prefix each row with `[row=N]`; default `true`",
- "--skip-hidden": "Skip hidden rows and columns; default `false`",
- "--dry-run": "Print the request path and parameters without executing"
- },
- "+cells-search": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--find": "Text to find (interpreted as regex when `--regex` is set)",
- "--range": "Search range (A1 notation); whole sheet when omitted",
- "--match-case": "Case-sensitive match",
- "--match-entire-cell": "Match the entire cell content",
- "--regex": "Interpret `--find` as a regex pattern",
- "--include-formulas": "Also search within formula text",
- "--max-matches": "Safety cap; default 5000"
- },
- "+cells-replace": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--find": "Text to find for replacement",
- "--replacement": "Replacement text; pass empty string `\"\"` to delete matched content",
- "--range": "Replace range (A1 notation); whole sheet when omitted",
- "--match-case": "Also replace within formula text",
- "--match-entire-cell": "Also replace within formula text",
- "--regex": "Also replace within formula text",
- "--include-formulas": "Also replace within formula text",
- "--dry-run": "Required preflight: outputs `would_replace_count` for user confirmation before the actual replace"
- },
- "+cells-set": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Write range (A1 notation)",
- "--cells": "JSON: `{\"values\": [[...], ...]}`; may include `formula` / `cell_styles` / `comments` / `embed_image` rich-cell fields",
- "--allow-overwrite": "Allow overwriting non-empty cells; with default `false`, error if any target cell is non-empty",
- "--max-cells": "Safety cap; default 50000"
- },
- "+cells-set-style": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Target range (A1 notation, e.g. `A1:B2`)",
- "--background-color": "Background color (hex, e.g. `#ffffff`)",
- "--font-color": "Font color (hex, e.g. `#000000`)",
- "--font-size": "Font size in px (e.g. 10, 12, 14)",
- "--font-style": "Font style enum: `normal` / `italic`",
- "--font-weight": "Font weight enum: `normal` / `bold`",
- "--font-line": "Font line style enum: `none` / `underline` / `line-through`",
- "--horizontal-alignment": "Horizontal alignment enum: `left` / `center` / `right`",
- "--vertical-alignment": "Vertical alignment enum: `top` / `middle` / `bottom`",
- "--word-wrap": "Word-wrap strategy: `overflow` / `auto-wrap` / `word-clip`; default `overflow`",
- "--number-format": "Number format pattern (e.g. text `@`, number `0.00`, currency `$#,##0.00`, date `mm/dd/yyyy`)",
- "--border-styles": "Border config JSON: `{ top: {style,color,weight}, bottom: ..., left: ..., right: ... }`; same shape for all 4 sides"
- },
- "+cells-set-image": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Target cell (A1 notation; must be a single cell, e.g. `A1`; start and end must be identical)",
- "--image": "Local image path (PNG / JPEG / JPG / GIF / BMP / JFIF / EXIF / TIFF / BPG / HEIC)",
- "--name": "Image file name (with extension); defaults to the basename of `--image`"
- },
- "+dropdown-set": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Target range (A1 notation, e.g. `A2:A100`)",
- "--options": "Options as a JSON array, e.g. `[\"opt1\",\"opt2\"]`; up to 500 items, each ≤100 chars, no commas",
- "--colors": "RGB hex color array (e.g. `[\"#1FB6C1\",\"#F006C2\"]`); length must equal `--options`",
- "--multiple": "Enable multi-select; default `false`",
- "--highlight": "Color-highlight options; default `false`"
- },
- "+csv-put": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Top-left A1 anchor (e.g. `Sheet1!A1`); the bottom-right is inferred from CSV row/column counts",
- "--csv": "RFC 4180 CSV text; plain values only (no formulas / styles / comments)",
- "--allow-overwrite": "Allow overwriting; with default `false`, error if any target cell is non-empty"
- },
- "+cells-clear": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Range to clear (A1 notation)",
- "--scope": "Clear scope: `content` (default, values only) / `formats` (formats only) / `all` (values and formats)",
- "--yes": "Confirm destructive write (exit code 10 without this flag); clear is irreversible"
- },
- "+cells-merge": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Range to merge / unmerge (A1 notation)",
- "--merge-type": "Merge direction (`+cells-merge` only): `all` / `rows` / `columns`; default `all`"
- },
- "+cells-unmerge": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Range to merge / unmerge (A1 notation)",
- "--merge-type": "Merge direction (`+cells-merge` only): `all` / `rows` / `columns`; default `all`"
- },
- "+rows-resize": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--start": "Start row (0-based, inclusive)",
- "--end": "End row (0-based, inclusive)",
- "--type": "Sizing mode: `pixel` (explicit px value, requires `--size`) / `standard` (reset to default row height) / `auto` (fit content)",
- "--size": "Row height in pixels (e.g. 30 / 40 / 60); required when `--type pixel`, ignored otherwise"
- },
- "+cols-resize": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--start": "Start column (0-based, inclusive)",
- "--end": "End column (0-based, inclusive)",
- "--type": "Sizing mode: `pixel` (explicit px value, requires `--size`) / `standard` (reset to default column width)",
- "--size": "Column width in pixels (e.g. 80 / 120 / 200); required when `--type pixel`, ignored otherwise"
- },
- "+range-move": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--source-range": "Source A1 range",
- "--target-sheet-id": "Destination sub-sheet id; defaults to the same sheet as the source",
- "--target-range": "Destination A1 range (anchor cell is enough; size inferred from the source)",
- "--paste-type": "Paste content type (`+range-copy` only): `values` / `formulas` / `formats` / `all`; default `all`"
- },
- "+range-copy": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--source-range": "Source A1 range",
- "--target-sheet-id": "Destination sub-sheet id; defaults to the same sheet as the source",
- "--target-range": "Destination A1 range (anchor cell is enough; size inferred from the source)",
- "--paste-type": "Paste content type (`+range-copy` only): `values` / `formulas` / `formats` / `all`; default `all`"
- },
- "+range-fill": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--source-range": "Fill template range (seed cells for the series)",
- "--target-range": "Destination fill range (A1 notation)",
- "--series-type": "Fill series type: `auto` / `linear` / `growth` / `date` / `copy`; default `auto`"
- },
- "+range-sort": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Sort range (A1 notation; whether the header is included depends on `--has-header`)",
- "--sort-keys": "Sort keys JSON: `[{\"col\":\"B\",\"order\":\"asc\"},{\"col\":\"D\",\"order\":\"desc\"}]`",
- "--has-header": "Treat the first row as a header and exclude from sort; default `false`"
- },
- "+batch-update": {
- "--url": "Spreadsheet locator (independent from per-operation sheet locator)",
- "--spreadsheet-token": "Spreadsheet locator (independent from per-operation sheet locator)",
- "--operations": "JSON: `{\"operations\":[{\"tool\":\"set_cell_range\",\"params\":{...}}, ...]}`; executed serially in array order",
- "--yes": "Confirm high-risk write (exit code 10 without this flag)",
- "--dry-run": "Print the request template for each sub-operation; no network side effects"
- },
- "+cells-batch-set-style": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--ranges": "Target ranges as a JSON array (e.g. `[\"sheet1!A1:B2\",\"sheet1!D1:D10\"]`); each item must include the sheet prefix; the same style is applied to all ranges",
- "--background-color": "Background color (hex, e.g. `#ffffff`)",
- "--font-color": "Font color (hex, e.g. `#000000`)",
- "--font-size": "Font size in px (e.g. 10, 12, 14)",
- "--font-style": "Font style enum: `normal` / `italic`",
- "--font-weight": "Font weight enum: `normal` / `bold`",
- "--font-line": "Font line style enum: `none` / `underline` / `line-through`",
- "--horizontal-alignment": "Horizontal alignment enum: `left` / `center` / `right`",
- "--vertical-alignment": "Vertical alignment enum: `top` / `middle` / `bottom`",
- "--word-wrap": "Word-wrap strategy: `overflow` / `auto-wrap` / `word-clip`; default `overflow`",
- "--number-format": "Number format pattern (e.g. text `@`, number `0.00`, currency `$#,##0.00`, date `mm/dd/yyyy`)",
- "--border-styles": "Border config JSON (same shape as in +cells-set-style)"
- },
- "+dropdown-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--ranges": "Target ranges as a JSON array (e.g. `[\"sheet1!A2:A100\"]`); each item must include the sheet prefix",
- "--options": "Options as a JSON array (e.g. `[\"opt1\",\"opt2\"]`)",
- "--colors": "Color array (same length as `--options`)",
- "--multiple": "Enable multi-select",
- "--highlight": "Color-highlight options"
- },
- "+dropdown-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--ranges": "Target ranges as a JSON array (up to 100 items; each must include the sheet prefix)",
- "--yes": "Confirm high-risk write (exit code 10 without this flag)"
- },
- "+chart-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--chart-id": "Filter to a single chart reference_id"
- },
- "+chart-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "Full chart config JSON (`position` / `data` / `properties` etc.); deeply nested, must be passed as JSON",
- "--dry-run": "Print the request template; no side effects"
- },
- "+chart-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--chart-id": "Target chart reference_id",
- "--properties": "Full or sufficiently complete chart config JSON (read back with `+chart-list` first, then patch)"
- },
- "+chart-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--chart-id": "Target chart reference_id",
- "--yes": "Confirm destructive write (exit code 10 without this flag)"
- },
- "+pivot-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--pivot-table-id": "Filter by id"
- },
- "+pivot-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "JSON: `{\"data_range\":\"Sheet1!A1:F1000\",\"rows\":[...],\"columns\":[...],\"values\":[...],\"filters\":[...],\"show_row_grand_total\":true,\"show_col_grand_total\":true}`",
- "--target-sheet-id": "Destination sub-sheet id for the pivot table; auto-creates a new sub-sheet when omitted (recommended)",
- "--target-position": "Destination anchor cell (A1 notation, e.g. `A1`); default `A1`",
- "--source": "Pivot table source range (A1 notation; format `SheetName!StartCell:EndCell`, e.g. `Sheet1!A1:D100`)",
- "--range": "Pivot table placement (single A1 anchor for the top-left, e.g. `F1`); placed at the top-left of a newly created sub-sheet when omitted"
- },
- "+pivot-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--pivot-table-id": "Target pivot table id",
- "--properties": "Full or sufficiently complete pivot config (read back with `+pivot-list --pivot-table-id ` first, then patch)"
- },
- "+pivot-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--pivot-table-id": "Target pivot table id",
- "--yes": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
- },
- "+cond-format-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--rule-id": "Filter by rule id"
- },
- "+cond-format-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "Rule config JSON: `style` (required, applied on match), `attrs?` (rule-type-dependent params), `has_ref?`. `rule_type` and `ranges` are separate flags",
- "--rule-type": "Conditional format rule type (13 values): `cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`; takes precedence over the same-named field inside `--properties`",
- "--ranges": "A1 ranges where the conditional format applies, as a JSON array (e.g. `[\"A1:A100\",\"C2:C50\"]`); takes precedence over the same-named field inside `--properties`"
- },
- "+cond-format-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--rule-id": "Target rule id",
- "--properties": "Rule config JSON, same shape as `+cond-format-create --properties`; update overwrites the entire rule",
- "--rule-type": "Conditional format rule type (13 values): `cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`; takes precedence over the same-named field inside `--properties`",
- "--ranges": "A1 ranges where the conditional format applies, as a JSON array (e.g. `[\"A1:A100\",\"C2:C50\"]`); takes precedence over the same-named field inside `--properties`"
- },
- "+cond-format-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--rule-id": "Target rule id",
- "--yes": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
- },
- "+filter-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)"
- },
- "+filter-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--range": "Filter range (A1 notation, including header row, e.g. `A1:F1000`); do not duplicate the range field inside `--properties`",
- "--properties": "Filter rule JSON: `rules` (required, per-column rule array), `filtered_columns?` (active column index hint). `range` is a separate flag (do not duplicate inside this JSON)"
- },
- "+filter-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "Filter rule JSON: `rules` and `filtered_columns?`; update overwrites the entire rule set (pass `rules: []` to clear). `range` is a separate flag",
- "--range": "Range the filter applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`"
- },
- "+filter-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--yes": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
- },
- "+filter-view-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--view-id": "Filter by filter-view reference_id (returns the matching single view)"
- },
- "+filter-view-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "Filter-view rule JSON: `rules?` (per-column rule array), `filtered_columns?`. `range` and `view_name` are separate flags",
- "--range": "Range the filter view applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`; required on create and must cover the header row",
- "--view-name": "Filter-view name; auto-assigned by the server when omitted on create, kept unchanged when omitted on update; takes precedence over the same-named field inside `--properties`"
- },
- "+filter-view-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--view-id": "Target filter-view reference_id",
- "--properties": "Filter-view rule JSON: `rules?`, `filtered_columns?`. `range` and `view_name` are separate flags; pass at least one of `--properties.rules` / `--range` / `--view-name`",
- "--range": "Range the filter view applies to (A1 notation, e.g. `A1:F1000`); takes precedence over the same-named field inside `--properties`; omit to keep the current range on update",
- "--view-name": "Filter-view name; auto-assigned by the server when omitted on create, kept unchanged when omitted on update; takes precedence over the same-named field inside `--properties`"
- },
- "+filter-view-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--view-id": "Target filter-view reference_id",
- "--yes": "Confirm high-risk write (exit code 10 without this flag)"
- },
- "+sparkline-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--group-id": "Filter by group_id"
- },
- "+sparkline-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--properties": "JSON: `{\"type\":\"line|column|winLoss\",\"data_range\":\"A2:F10\",\"target_range\":\"G2:G10\",\"style\":{...},\"special_points\":{...}}`; `type` is a 3-value enum; row/column counts of `data_range` must match `target_range`"
- },
- "+sparkline-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--group-id": "Target group id",
- "--properties": "Full or sufficiently complete sparkline config (read back with `+sparkline-list --group-id ` first, then patch); supports updating `type` / `data_range` / `target_range` / `style` / `special_points` etc."
- },
- "+sparkline-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--group-id": "Target group id",
- "--yes": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
- },
- "+float-image-list": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--float-image-id": "Filter by id; lists all float images on the sheet when omitted"
- },
- "+float-image-create": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--image-name": "Image name, including extension (e.g. `logo.png`)",
- "--image-token": "Image file_token (XOR with `--image-uri`). Common source: `image_token` returned by `+float-image-list`",
- "--image-uri": "Image reference_id (XOR with `--image-token`); a prefixed string like `<|image|>:abcdef`",
- "--position-row": "Row anchor of the image's top-left corner (0-based)",
- "--position-col": "Column anchor of the image's top-left corner (column letter, e.g. `A` / `B`)",
- "--size-width": "Image width in pixels",
- "--size-height": "Image height in pixels",
- "--offset-row": "Pixel offset within the anchor row, on top of `--position-row`",
- "--offset-col": "Pixel offset within the anchor column, on top of `--position-col`",
- "--z-index": "Image z-index controlling stacking order"
- },
- "+float-image-update": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--float-image-id": "Target float image id",
- "--image-name": "Image name, including extension (e.g. `logo.png`)",
- "--image-token": "Image file_token (XOR with `--image-uri`). Common source: `image_token` returned by `+float-image-list`",
- "--image-uri": "Image reference_id (XOR with `--image-token`); a prefixed string like `<|image|>:abcdef`",
- "--position-row": "Row anchor of the image's top-left corner (0-based)",
- "--position-col": "Column anchor of the image's top-left corner (column letter, e.g. `A` / `B`)",
- "--size-width": "Image width in pixels",
- "--size-height": "Image height in pixels",
- "--offset-row": "Pixel offset within the anchor row, on top of `--position-row`",
- "--offset-col": "Pixel offset within the anchor column, on top of `--position-col`",
- "--z-index": "Image z-index controlling stacking order"
- },
- "+float-image-delete": {
- "--url": "Spreadsheet URL (XOR with `--spreadsheet-token`)",
- "--spreadsheet-token": "Spreadsheet token (XOR with `--url`)",
- "--sheet-id": "Sheet reference_id (XOR with `--sheet-name`)",
- "--sheet-name": "Sheet name (XOR with `--sheet-id`)",
- "--float-image-id": "Target float image id",
- "--yes": "Confirm destructive write (exit code 10 without this flag); delete is irreversible"
- }
-}
diff --git a/shortcuts/sheets/execute_paths_test.go b/shortcuts/sheets/execute_paths_test.go
index b484d1b79..4de3b2997 100644
--- a/shortcuts/sheets/execute_paths_test.go
+++ b/shortcuts/sheets/execute_paths_test.go
@@ -99,7 +99,7 @@ func TestExecute_CellsGet(t *testing.T) {
t.Parallel()
stub := toolOutputStub(testToken, "read", `{"ranges":[{"range":"A1:B2","cells":[[{"value":1}]]}]}`)
out, err := runShortcutWithStubs(t, CellsGet,
- []string{"--url", testURL, "--sheet-id", testSheetID, "--ranges", "A1:B2"}, stub)
+ []string{"--url", testURL, "--sheet-id", testSheetID, "--range", "A1:B2"}, stub)
if err != nil {
t.Fatalf("execute failed: %v\nout=%s", err, out)
}
diff --git a/shortcuts/sheets/flag_defs.go b/shortcuts/sheets/flag_defs.go
new file mode 100644
index 000000000..f16f19eb8
--- /dev/null
+++ b/shortcuts/sheets/flag_defs.go
@@ -0,0 +1,94 @@
+// Copyright (c) 2026 Lark Technologies Pte. Ltd.
+// SPDX-License-Identifier: MIT
+
+package sheets
+
+import (
+ _ "embed"
+ "encoding/json"
+ "fmt"
+ "sync"
+
+ "github.com/larksuite/cli/shortcuts/common"
+)
+
+// ─── flag definitions, sourced from sheet-skill-spec ───────────────────
+//
+// data/flag-defs.json is the canonical, full definition of every CLI flag
+// (name, type, default, desc, enum, input, hidden, required, kind),
+// generated by sheet-skill-spec's sync script. We embed it and build each
+// shortcut's []common.Flag from it at assembly time, so flag metadata never
+// has to be hand-written in Go.
+//
+// Flags with kind == "system" (--dry-run, --yes, ...) are NOT materialized
+// here: the framework auto-injects them based on Risk / DryRun / HasFormat.
+// Do not hand-edit data/flag-defs.json; regenerate via the sync script.
+
+//go:embed data/flag-defs.json
+var flagDefsJSON []byte
+
+type flagDef struct {
+ Name string `json:"name"`
+ Kind string `json:"kind"` // "public" | "own" | "system"
+ Type string `json:"type"` // string | bool | int | int64 | float64 | string_array | string_slice
+ Required string `json:"required"` // "required" | "optional" | "xor"
+ Desc string `json:"desc"`
+ Default string `json:"default"`
+ Hidden bool `json:"hidden"`
+ Enum []string `json:"enum"`
+ Input []string `json:"input"`
+}
+
+type commandDef struct {
+ Risk string `json:"risk"`
+ Flags []flagDef `json:"flags"`
+}
+
+var (
+ flagDefsOnce sync.Once
+ flagDefs map[string]commandDef
+ flagDefsErr error
+)
+
+func loadFlagDefs() (map[string]commandDef, error) {
+ flagDefsOnce.Do(func() {
+ flagDefs = make(map[string]commandDef)
+ if err := json.Unmarshal(flagDefsJSON, &flagDefs); err != nil {
+ flagDefsErr = fmt.Errorf("flag-defs.json: %w", err)
+ }
+ })
+ return flagDefs, flagDefsErr
+}
+
+// flagsFor builds the []common.Flag for a shortcut command directly from
+// flag-defs.json. System-kind flags are skipped (the framework injects
+// them). Panics if the command is absent or the JSON is malformed — this
+// is a build-time data contract, so a missing entry is a programming error
+// surfaced loudly at startup rather than a silent empty flag set.
+func flagsFor(command string) []common.Flag {
+ defs, err := loadFlagDefs()
+ if err != nil {
+ panic(fmt.Sprintf("sheets: %v", err))
+ }
+ spec, ok := defs[command]
+ if !ok {
+ panic(fmt.Sprintf("sheets: no flag-defs.json entry for %q", command))
+ }
+ out := make([]common.Flag, 0, len(spec.Flags))
+ for _, df := range spec.Flags {
+ if df.Kind == "system" {
+ continue
+ }
+ out = append(out, common.Flag{
+ Name: df.Name,
+ Type: df.Type,
+ Default: df.Default,
+ Desc: df.Desc,
+ Hidden: df.Hidden,
+ Required: df.Required == "required",
+ Enum: df.Enum,
+ Input: df.Input,
+ })
+ }
+ return out
+}
diff --git a/shortcuts/sheets/flag_defs_test.go b/shortcuts/sheets/flag_defs_test.go
new file mode 100644
index 000000000..a4c47fdf3
--- /dev/null
+++ b/shortcuts/sheets/flag_defs_test.go
@@ -0,0 +1,142 @@
+// Copyright (c) 2026 Lark Technologies Pte. Ltd.
+// SPDX-License-Identifier: MIT
+
+package sheets
+
+import (
+ "testing"
+
+ "github.com/larksuite/cli/shortcuts/common"
+)
+
+// TestFlagDefs_EmbedParses asserts the embedded flag-defs.json blob is valid
+// JSON with at least one command entry.
+func TestFlagDefs_EmbedParses(t *testing.T) {
+ t.Parallel()
+ defs, err := loadFlagDefs()
+ if err != nil {
+ t.Fatalf("loadFlagDefs error: %v", err)
+ }
+ if len(defs) == 0 {
+ t.Fatal("flag-defs.json has no command entries")
+ }
+}
+
+// TestFlagsFor_SkipsSystemFlags verifies system-kind flags (--dry-run, --yes)
+// are never materialized into a shortcut's Flags slice — the framework injects
+// those based on Risk / DryRun.
+func TestFlagsFor_SkipsSystemFlags(t *testing.T) {
+ t.Parallel()
+ for _, cmd := range []string{"+sheet-delete", "+batch-update", "+csv-get"} {
+ for _, f := range flagsFor(cmd) {
+ if f.Name == "dry-run" || f.Name == "yes" {
+ t.Errorf("%s: system flag --%s leaked into Flags", cmd, f.Name)
+ }
+ }
+ }
+}
+
+// TestFlagsFor_MapsAllFields spot-checks that name/type/default/enum/input/
+// required/hidden are carried over from the JSON correctly.
+func TestFlagsFor_MapsAllFields(t *testing.T) {
+ t.Parallel()
+ byName := func(cmd, name string) *common.Flag {
+ flags := flagsFor(cmd)
+ for i := range flags {
+ if flags[i].Name == name {
+ return &flags[i]
+ }
+ }
+ return nil
+ }
+
+ // enum + default
+ rt := byName("+dim-insert", "inherit-style")
+ if rt == nil || len(rt.Enum) != 3 || rt.Default != "none" {
+ t.Errorf("+dim-insert --inherit-style not mapped: %+v", rt)
+ }
+ // required
+ title := byName("+sheet-create", "title")
+ if title == nil || !title.Required {
+ t.Errorf("+sheet-create --title should be required: %+v", title)
+ }
+ // xor is NOT cobra-required (enforced by Validate hooks)
+ url := byName("+sheet-create", "url")
+ if url == nil || url.Required {
+ t.Errorf("+sheet-create --url should not be cobra-required: %+v", url)
+ }
+ // hidden + int default
+ cap := byName("+cells-get", "cell-limit")
+ if cap == nil || !cap.Hidden || cap.Default != "5000" {
+ t.Errorf("+cells-get --cell-limit not mapped: %+v", cap)
+ }
+ // input sources
+ cells := byName("+cells-set", "cells")
+ if cells == nil || len(cells.Input) != 2 {
+ t.Errorf("+cells-set --cells should support file+stdin: %+v", cells)
+ }
+ // float64 type
+ fs := byName("+cells-set-style", "font-size")
+ if fs == nil || fs.Type != "float64" {
+ t.Errorf("+cells-set-style --font-size should be float64: %+v", fs)
+ }
+}
+
+// TestFlagsFor_EveryRegisteredCommandHasDefs ensures every shortcut returned by
+// Shortcuts() has a flag-defs.json entry and that its flags match the JSON's
+// non-system flags exactly (name + type + required + default + hidden). This is
+// the contract that lets shortcuts drop hand-written flag literals.
+func TestFlagsFor_EveryRegisteredCommandHasDefs(t *testing.T) {
+ t.Parallel()
+ defs, err := loadFlagDefs()
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, s := range Shortcuts() {
+ spec, ok := defs[s.Command]
+ if !ok {
+ t.Errorf("%s has no flag-defs.json entry", s.Command)
+ continue
+ }
+ want := map[string]flagDef{}
+ for _, df := range spec.Flags {
+ if df.Kind != "system" {
+ want[df.Name] = df
+ }
+ }
+ got := map[string]bool{}
+ for _, f := range s.Flags {
+ got[f.Name] = true
+ df, ok := want[f.Name]
+ if !ok {
+ t.Errorf("%s --%s present in Go but not in JSON (non-system)", s.Command, f.Name)
+ continue
+ }
+ ft := f.Type
+ if ft == "" {
+ ft = "string"
+ }
+ jt := df.Type
+ if jt == "" {
+ jt = "string"
+ }
+ if ft != jt {
+ t.Errorf("%s --%s type: go=%s json=%s", s.Command, f.Name, ft, jt)
+ }
+ if f.Required != (df.Required == "required") {
+ t.Errorf("%s --%s required: go=%v json=%s", s.Command, f.Name, f.Required, df.Required)
+ }
+ if f.Default != df.Default {
+ t.Errorf("%s --%s default: go=%q json=%q", s.Command, f.Name, f.Default, df.Default)
+ }
+ if f.Hidden != df.Hidden {
+ t.Errorf("%s --%s hidden: go=%v json=%v", s.Command, f.Name, f.Hidden, df.Hidden)
+ }
+ }
+ for name := range want {
+ if !got[name] {
+ t.Errorf("%s --%s in JSON but missing from Go Flags", s.Command, name)
+ }
+ }
+ }
+}
diff --git a/shortcuts/sheets/flag_desc.go b/shortcuts/sheets/flag_desc.go
deleted file mode 100644
index 863af7dae..000000000
--- a/shortcuts/sheets/flag_desc.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2026 Lark Technologies Pte. Ltd.
-// SPDX-License-Identifier: MIT
-
-package sheets
-
-import (
- _ "embed"
- "encoding/json"
- "fmt"
- "sync"
-
- "github.com/larksuite/cli/shortcuts/common"
-)
-
-//go:embed data/flag-descriptions.en.json
-var flagDescsJSON []byte
-
-var (
- flagDescsOnce sync.Once
- flagDescs map[string]map[string]string
- flagDescsErr error
-)
-
-func loadFlagDescs() (map[string]map[string]string, error) {
- flagDescsOnce.Do(func() {
- flagDescs = make(map[string]map[string]string)
- flagDescsErr = json.Unmarshal(flagDescsJSON, &flagDescs)
- if flagDescsErr != nil {
- flagDescsErr = fmt.Errorf("flag-descriptions.en.json: %w", flagDescsErr)
- }
- })
- return flagDescs, flagDescsErr
-}
-
-// flagDesc returns the description for a flag from the embedded
-// flag-descriptions.en.json. command is e.g. "+workbook-info",
-// flagName is e.g. "url" (without "--" prefix). Returns "" when
-// no entry exists.
-func flagDesc(command, flagName string) string {
- descs, err := loadFlagDescs()
- if err != nil || descs == nil {
- return ""
- }
- cmd, ok := descs[command]
- if !ok {
- return ""
- }
- return cmd["--"+flagName]
-}
-
-// applyFlagDescs patches all Flag.Desc fields in the given shortcut
-// slice with values from flag-descriptions.en.json. Flags without a
-// JSON entry keep their existing Desc unchanged.
-func applyFlagDescs(shortcuts []common.Shortcut) {
- descs, err := loadFlagDescs()
- if err != nil || descs == nil {
- return
- }
- for i := range shortcuts {
- cmd, ok := descs[shortcuts[i].Command]
- if !ok {
- continue
- }
- for j := range shortcuts[i].Flags {
- key := "--" + shortcuts[i].Flags[j].Name
- if desc, found := cmd[key]; found {
- shortcuts[i].Flags[j].Desc = desc
- }
- }
- }
-}
diff --git a/shortcuts/sheets/flag_desc_test.go b/shortcuts/sheets/flag_desc_test.go
deleted file mode 100644
index e30d02bc6..000000000
--- a/shortcuts/sheets/flag_desc_test.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2026 Lark Technologies Pte. Ltd.
-// SPDX-License-Identifier: MIT
-
-package sheets
-
-import (
- "testing"
-)
-
-func TestFlagDescs_EmbedParses(t *testing.T) {
- t.Parallel()
- descs, err := loadFlagDescs()
- if err != nil {
- t.Fatalf("loadFlagDescs error: %v", err)
- }
- if len(descs) == 0 {
- t.Fatal("flag-descriptions.en.json has no entries")
- }
-}
-
-func TestFlagDescs_SpotCheck(t *testing.T) {
- t.Parallel()
- cases := []struct {
- command string
- flagName string
- }{
- {"+workbook-info", "url"},
- {"+cells-set", "range"},
- {"+csv-get", "range"},
- {"+batch-update", "operations"},
- {"+chart-create", "properties"},
- }
- for _, tc := range cases {
- desc := flagDesc(tc.command, tc.flagName)
- if desc == "" {
- t.Errorf("flagDesc(%q, %q) = empty; want a description", tc.command, tc.flagName)
- }
- }
-}
-
-func TestFlagDescs_UnknownReturnsEmpty(t *testing.T) {
- t.Parallel()
- if got := flagDesc("+no-such-cmd", "no-flag"); got != "" {
- t.Errorf("expected empty for unknown command; got %q", got)
- }
-}
-
-func TestApplyFlagDescs_OverridesHardcodedDesc(t *testing.T) {
- t.Parallel()
- all := Shortcuts()
- descs, err := loadFlagDescs()
- if err != nil {
- t.Fatalf("loadFlagDescs: %v", err)
- }
- for _, s := range all {
- cmd, ok := descs[s.Command]
- if !ok {
- continue
- }
- for _, f := range s.Flags {
- key := "--" + f.Name
- want, exists := cmd[key]
- if !exists {
- continue
- }
- if f.Desc != want {
- t.Errorf("%s %s: Desc=%q, want=%q", s.Command, key, f.Desc, want)
- }
- }
- }
-}
-
-func TestApplyFlagDescs_Coverage(t *testing.T) {
- t.Parallel()
- all := Shortcuts()
- descs, err := loadFlagDescs()
- if err != nil {
- t.Fatalf("loadFlagDescs: %v", err)
- }
-
- // Framework-injected flags are not in the Flags slice but may
- // appear in the JSON as documentation. Skip them.
- frameworkFlags := map[string]bool{
- "--yes": true,
- "--dry-run": true,
- }
-
- // Every non-framework flag in the JSON should appear in the shortcut list.
- for cmd, flags := range descs {
- for flagKey := range flags {
- if frameworkFlags[flagKey] {
- continue
- }
- found := false
- for _, s := range all {
- if s.Command != cmd {
- continue
- }
- for _, f := range s.Flags {
- if "--"+f.Name == flagKey {
- found = true
- break
- }
- }
- break
- }
- if !found {
- t.Logf("JSON has %s %s but no matching flag in shortcut list (naming mismatch or not yet implemented)", cmd, flagKey)
- }
- }
- }
-}
diff --git a/shortcuts/sheets/flag_schema.go b/shortcuts/sheets/flag_schema.go
index b61abd8f7..03bf0b65d 100644
--- a/shortcuts/sheets/flag_schema.go
+++ b/shortcuts/sheets/flag_schema.go
@@ -96,9 +96,9 @@ func printFlagSchemaFor(command string) func(flagName string) ([]byte, error) {
}
sort.Strings(flags)
return json.MarshalIndent(map[string]interface{}{
- "shortcut": command,
- "introspectable_flags": flags,
- "hint": "run again with --flag-name to dump the JSON Schema for that flag",
+ "shortcut": command,
+ "introspectable_flags": flags,
+ "hint": "run again with --flag-name to dump the JSON Schema for that flag",
}, "", " ")
}
schema, ok := entry[flagName]
diff --git a/shortcuts/sheets/helpers.go b/shortcuts/sheets/helpers.go
index 931f3eb5c..53e53be95 100644
--- a/shortcuts/sheets/helpers.go
+++ b/shortcuts/sheets/helpers.go
@@ -57,26 +57,6 @@ func extractSpreadsheetToken(input string) string {
return input
}
-// publicTokenFlags is the leading pair of every canonical sheets shortcut.
-// Shortcuts targeting a single sheet append the public sheet-id / sheet-name
-// XOR pair on top of this; workbook-level shortcuts use this pair only.
-func publicTokenFlags() []common.Flag {
- return []common.Flag{
- {Name: "url", Desc: "spreadsheet URL (XOR --spreadsheet-token)"},
- {Name: "spreadsheet-token", Desc: "spreadsheet token (XOR --url)"},
- }
-}
-
-// publicSheetFlags extends publicTokenFlags with the sheet selector pair.
-// Use for any +sheet-* / +cells-* / +dim-* / object shortcut that operates
-// on an existing single sub-sheet.
-func publicSheetFlags() []common.Flag {
- return append(publicTokenFlags(),
- common.Flag{Name: "sheet-id", Desc: "sheet reference_id (XOR --sheet-name)"},
- common.Flag{Name: "sheet-name", Desc: "sheet title (XOR --sheet-id)"},
- )
-}
-
// resolveSheetSelector validates the --sheet-id / --sheet-name XOR and
// returns whichever was supplied. Network-free.
//
@@ -169,35 +149,6 @@ func requireJSONArray(runtime *common.RuntimeContext, name string) ([]interface{
// ─── style flags (shared by +cells-set-style and +cells-batch-set-style) ─
-var (
- fontStyleEnum = []string{"normal", "italic"}
- fontWeightEnum = []string{"normal", "bold"}
- fontLineEnum = []string{"none", "underline", "line-through"}
- hAlignEnum = []string{"left", "center", "right"}
- vAlignEnum = []string{"top", "middle", "bottom"}
- wordWrapEnum = []string{"overflow", "auto-wrap", "word-clip"}
-)
-
-// styleFlatFlags returns the 11 flat style flags + --border-styles that both
-// +cells-set-style and +cells-batch-set-style expose. Keeping them in one
-// place stops the two shortcuts from drifting apart.
-func styleFlatFlags() []common.Flag {
- return []common.Flag{
- {Name: "background-color", Desc: "hex background color (e.g. #ffffff)"},
- {Name: "font-color", Desc: "hex font color (e.g. #000000)"},
- {Name: "font-size", Type: "int", Desc: "font size in pixels (e.g. 10, 12, 14)"},
- {Name: "font-style", Enum: fontStyleEnum, Desc: "normal / italic"},
- {Name: "font-weight", Enum: fontWeightEnum, Desc: "normal / bold"},
- {Name: "font-line", Enum: fontLineEnum, Desc: "none / underline / line-through"},
- {Name: "horizontal-alignment", Enum: hAlignEnum, Desc: "left / center / right"},
- {Name: "vertical-alignment", Enum: vAlignEnum, Desc: "top / middle / bottom"},
- {Name: "word-wrap", Enum: wordWrapEnum, Desc: "overflow (default) / auto-wrap / word-clip"},
- {Name: "number-format", Desc: "number format string (e.g. @, 0.00, $#,##0.00, mm/dd/yyyy)"},
- {Name: "border-styles", Input: []string{common.File, common.Stdin},
- Desc: "border JSON: { top, bottom, left, right } each = { color, style, weight }"},
- }
-}
-
// buildCellStyleFromFlags reads the 11 flat style flags and returns the
// cell_styles map expected by set_cell_range. Skips any flag the user
// didn't set so partial styles work.
@@ -209,8 +160,8 @@ func buildCellStyleFromFlags(runtime *common.RuntimeContext) map[string]interfac
if v := runtime.Str("font-color"); v != "" {
style["font_color"] = v
}
- if runtime.Changed("font-size") && runtime.Int("font-size") > 0 {
- style["font_size"] = runtime.Int("font-size")
+ if runtime.Changed("font-size") && runtime.Float64("font-size") > 0 {
+ style["font_size"] = runtime.Float64("font-size")
}
if v := runtime.Str("font-style"); v != "" {
style["font_style"] = v
diff --git a/shortcuts/sheets/lark_sheet_batch_update.go b/shortcuts/sheets/lark_sheet_batch_update.go
index d91d34cee..364a11ddd 100644
--- a/shortcuts/sheets/lark_sheet_batch_update.go
+++ b/shortcuts/sheets/lark_sheet_batch_update.go
@@ -40,11 +40,7 @@ var BatchUpdate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "operations", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "operations JSON array: [{tool_name, input}, ...] (or an envelope object with operations / continue_on_error)"},
- common.Flag{Name: "continue-on-error", Type: "bool", Desc: "flip the default strict transaction off; partial success is kept on disk"},
- ),
+ Flags: flagsFor("+batch-update"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -142,12 +138,7 @@ var CellsBatchSetStyle = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(
- append(publicTokenFlags(),
- common.Flag{Name: "ranges", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "JSON array of sheet-prefixed A1 ranges (e.g. [\"sheet1!A1:B2\", \"sheet1!D1:E2\"])"}),
- styleFlatFlags()...,
- ),
+ Flags: flagsFor("+cells-batch-set-style"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -240,16 +231,7 @@ var DropdownUpdate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "ranges", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "JSON array of sheet-prefixed A1 ranges (e.g. [\"sheet1!A2:A100\"])"},
- common.Flag{Name: "options", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "options JSON array (e.g. [\"alpha\",\"beta\"])"},
- common.Flag{Name: "colors", Input: []string{common.File, common.Stdin},
- Desc: "optional RGB hex color array (must equal --options length)"},
- common.Flag{Name: "multiple", Type: "bool", Desc: "enable multi-select"},
- common.Flag{Name: "highlight", Type: "bool", Desc: "color-highlight options"},
- ),
+ Flags: flagsFor("+dropdown-update"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -294,10 +276,7 @@ var DropdownDelete = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "ranges", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "JSON array of sheet-prefixed A1 ranges (max 100)"},
- ),
+ Flags: flagsFor("+dropdown-delete"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_object_crud.go b/shortcuts/sheets/lark_sheet_object_crud.go
index 96910fa59..4457188b2 100644
--- a/shortcuts/sheets/lark_sheet_object_crud.go
+++ b/shortcuts/sheets/lark_sheet_object_crud.go
@@ -33,14 +33,10 @@ import (
// idFlag / idField empty → no per-object id flag (only filter uses that
// today, and it has its own bespoke shortcuts further down).
type objectCRUDSpec struct {
- commandPrefix string // e.g. "+chart" → +chart-create / -update / -delete
- toolName string // e.g. "manage_chart_object"
- idFlag string // e.g. "chart-id"
- idField string // e.g. "chart_id"
- createDataDesc string // help text for --properties on create
- updateDataDesc string // help text for --properties on update
- createExtraFlags []common.Flag
- updateExtraFlags []common.Flag
+ commandPrefix string // e.g. "+chart" → +chart-create / -update / -delete
+ toolName string // e.g. "manage_chart_object"
+ idFlag string // e.g. "chart-id"
+ idField string // e.g. "chart_id"
// enhanceCreateInput / enhanceUpdateInput, when set, mutate the tool
// input after the standard fields are written. Used to inject
// shortcut-specific flat flags into the input (typically into the
@@ -51,10 +47,7 @@ type objectCRUDSpec struct {
}
func newObjectCreateShortcut(spec objectCRUDSpec) common.Shortcut {
- flags := append(publicSheetFlags(),
- common.Flag{Name: "properties", Input: []string{common.File, common.Stdin}, Required: true, Desc: spec.createDataDesc},
- )
- flags = append(flags, spec.createExtraFlags...)
+ flags := flagsFor(spec.commandPrefix + "-create")
return common.Shortcut{
Service: "sheets",
Command: spec.commandPrefix + "-create",
@@ -121,18 +114,7 @@ func objectCreateInput(runtime *common.RuntimeContext, token, sheetID, sheetName
}
func newObjectUpdateShortcut(spec objectCRUDSpec) common.Shortcut {
- flags := publicSheetFlags()
- if spec.idFlag != "" {
- flags = append(flags, common.Flag{
- Name: spec.idFlag, Required: true,
- Desc: "target object reference_id (maps to " + spec.idField + " on the wire)",
- })
- }
- flags = append(flags, common.Flag{
- Name: "properties", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: spec.updateDataDesc,
- })
- flags = append(flags, spec.updateExtraFlags...)
+ flags := flagsFor(spec.commandPrefix + "-update")
return common.Shortcut{
Service: "sheets",
Command: spec.commandPrefix + "-update",
@@ -205,13 +187,7 @@ func objectUpdateInput(runtime *common.RuntimeContext, token, sheetID, sheetName
}
func newObjectDeleteShortcut(spec objectCRUDSpec) common.Shortcut {
- flags := publicSheetFlags()
- if spec.idFlag != "" {
- flags = append(flags, common.Flag{
- Name: spec.idFlag, Required: true,
- Desc: "target object reference_id (maps to " + spec.idField + " on the wire)",
- })
- }
+ flags := flagsFor(spec.commandPrefix + "-delete")
return common.Shortcut{
Service: "sheets",
Command: spec.commandPrefix + "-delete",
@@ -273,12 +249,10 @@ func objectDeleteInput(runtime *common.RuntimeContext, token, sheetID, sheetName
// chart
var chartSpec = objectCRUDSpec{
- commandPrefix: "+chart",
- toolName: "manage_chart_object",
- idFlag: "chart-id",
- idField: "chart_id",
- createDataDesc: "chart properties JSON (position / data / properties etc.); see lark-sheets-chart.md for the shape",
- updateDataDesc: "full or partial chart properties JSON (`+chart-list --chart-id ` first, then patch)",
+ commandPrefix: "+chart",
+ toolName: "manage_chart_object",
+ idFlag: "chart-id",
+ idField: "chart_id",
}
var ChartCreate = newObjectCreateShortcut(chartSpec)
var ChartUpdate = newObjectUpdateShortcut(chartSpec)
@@ -287,18 +261,10 @@ var ChartDelete = newObjectDeleteShortcut(chartSpec)
// pivot — create exposes --target-sheet-id / --target-position (top-level
// of the tool input) plus --source / --range hoisted from properties.
var pivotSpec = objectCRUDSpec{
- commandPrefix: "+pivot",
- toolName: "manage_pivot_table_object",
- idFlag: "pivot-table-id",
- idField: "pivot_table_id",
- createDataDesc: "pivot table properties JSON: { rows, columns, values, filters, show_row_grand_total, ... }; --source / --range cover the common scalar fields",
- updateDataDesc: "full or partial pivot properties JSON (`+pivot-list --pivot-table-id ` first, then patch)",
- createExtraFlags: []common.Flag{
- {Name: "target-sheet-id", Desc: "destination sheet id for the pivot table; omit to auto-create a fresh sheet (recommended)"},
- {Name: "target-position", Default: "A1", Desc: "destination start cell, default A1"},
- {Name: "source", Required: true, Desc: "pivot source range, e.g. Sheet1!A1:D100 (--source overrides any properties.source)"},
- {Name: "range", Desc: "destination top-left A1 cell, e.g. F1 (--range overrides any properties.range)"},
- },
+ commandPrefix: "+pivot",
+ toolName: "manage_pivot_table_object",
+ idFlag: "pivot-table-id",
+ idField: "pivot_table_id",
enhanceCreateInput: func(rt *common.RuntimeContext, input map[string]interface{}) {
if v := strings.TrimSpace(rt.Str("target-sheet-id")); v != "" {
input["target_sheet_id"] = v
@@ -325,17 +291,6 @@ var PivotDelete = newObjectDeleteShortcut(pivotSpec)
// conditional format — CLI surface uses --rule-id (short), wired to the
// tool's conditional_format_id on the wire. --rule-type and --ranges are
// hoisted out of properties (both required, set on every CRUD write).
-var condFormatRuleTypeEnum = []string{
- "cellValue", "formula", "duplicate", "unique",
- "topBottom", "aboveBelowAverage", "dataBar", "colorScale",
- "iconSet", "textContains", "dateOccurring", "blankCell", "errorCell",
-}
-var condFormatExtraFlags = []common.Flag{
- {Name: "rule-type", Required: true, Enum: condFormatRuleTypeEnum,
- Desc: "rule type enum (cellValue / formula / duplicate / ...); merged into properties.rule.type"},
- {Name: "ranges", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "A1 ranges JSON array (e.g. [\"A1:A100\",\"C2:C50\"]); merged into properties.ranges"},
-}
var condFormatEnhance = func(rt *common.RuntimeContext, input map[string]interface{}) {
props, _ := input["properties"].(map[string]interface{})
if props == nil {
@@ -361,10 +316,6 @@ var condFormatSpec = objectCRUDSpec{
toolName: "manage_conditional_format_object",
idFlag: "rule-id",
idField: "conditional_format_id",
- createDataDesc: "rule JSON: { rule: { operator, value, style, ... }, ... }; --rule-type and --ranges cover the common scalar fields",
- updateDataDesc: "full or partial rule JSON (`+cond-format-list --rule-id ` first, then patch); --rule-type and --ranges still required",
- createExtraFlags: condFormatExtraFlags,
- updateExtraFlags: condFormatExtraFlags,
enhanceCreateInput: condFormatEnhance,
enhanceUpdateInput: condFormatEnhance,
}
@@ -374,12 +325,10 @@ var CondFormatDelete = newObjectDeleteShortcut(condFormatSpec)
// sparkline — CLI uses --group-id (higher level) as the object selector.
var sparklineSpec = objectCRUDSpec{
- commandPrefix: "+sparkline",
- toolName: "manage_sparkline_object",
- idFlag: "group-id",
- idField: "group_id",
- createDataDesc: "sparkline group JSON: { type: line|column|winLoss, source_range, target_range, ... }",
- updateDataDesc: "full or partial sparkline group JSON (`+sparkline-list --group-id ` first, then patch)",
+ commandPrefix: "+sparkline",
+ toolName: "manage_sparkline_object",
+ idFlag: "group-id",
+ idField: "group_id",
}
var SparklineCreate = newObjectCreateShortcut(sparklineSpec)
var SparklineUpdate = newObjectUpdateShortcut(sparklineSpec)
@@ -389,19 +338,6 @@ var SparklineDelete = newObjectDeleteShortcut(sparklineSpec)
// the tool's properties is composed entirely from the position / size /
// offset / image_token / image_uri / z_index flat flags.
-var floatImageFlatFlags = []common.Flag{
- {Name: "image-name", Required: true, Desc: "image file name with extension (e.g. logo.png)"},
- {Name: "image-token", Desc: "image file_token (XOR --image-uri); commonly returned by +float-image-list"},
- {Name: "image-uri", Desc: "image reference_id (XOR --image-token); upstream-supplied like \"<|image|>:abcdef\""},
- {Name: "position-row", Type: "int", Required: true, Desc: "top-left row index (0-based)"},
- {Name: "position-col", Required: true, Desc: "top-left column letter (e.g. A, B)"},
- {Name: "size-width", Type: "int", Required: true, Desc: "image width in pixels"},
- {Name: "size-height", Type: "int", Required: true, Desc: "image height in pixels"},
- {Name: "offset-row", Type: "int", Desc: "in-cell row offset in pixels (optional)"},
- {Name: "offset-col", Type: "int", Desc: "in-cell column offset in pixels (optional)"},
- {Name: "z-index", Type: "int", Desc: "z-order layer for overlapping images (optional)"},
-}
-
// floatImageProperties assembles the tool's properties object from the
// 10 flat flags. Caller is responsible for marking required flags via
// cobra Required:true; this function only enforces the image_token XOR
@@ -452,11 +388,7 @@ func newFloatImageWriteShortcut(command, description, op string, withIDFlag, isH
if isHighRisk {
risk = "high-risk-write"
}
- flags := publicSheetFlags()
- if withIDFlag {
- flags = append(flags, common.Flag{Name: "float-image-id", Required: true, Desc: "target image reference_id"})
- }
- flags = append(flags, floatImageFlatFlags...)
+ flags := flagsFor(command)
return common.Shortcut{
Service: "sheets",
Command: command,
@@ -550,10 +482,6 @@ var FloatImageDelete = newObjectDeleteShortcut(floatImageDeleteSpec)
// it dispatches via the same One-OpenAPI endpoint as every other shortcut.
// --view-name and --range are hoisted out of properties (optional on both
// create and update; they always win over properties.{view_name, range}).
-var filterViewExtraFlags = []common.Flag{
- {Name: "range", Desc: "filter view range (A1 covering the header, e.g. A1:F1000); overrides properties.range"},
- {Name: "view-name", Desc: "view title; create omits → server-generated, update omits → keep current. Overrides properties.view_name"},
-}
var filterViewEnhance = func(rt *common.RuntimeContext, input map[string]interface{}) {
props, _ := input["properties"].(map[string]interface{})
if props == nil {
@@ -572,10 +500,6 @@ var filterViewSpec = objectCRUDSpec{
toolName: "manage_filter_view_object",
idFlag: "view-id",
idField: "view_id",
- createDataDesc: "filter view JSON: { rules?: [...] , filtered_columns?: [...] }; --range / --view-name cover the scalar fields",
- updateDataDesc: "partial update JSON: any of { rules, filtered_columns }; `+filter-view-list --view-id ` first",
- createExtraFlags: filterViewExtraFlags,
- updateExtraFlags: filterViewExtraFlags,
enhanceCreateInput: filterViewEnhance,
enhanceUpdateInput: filterViewEnhance,
}
@@ -600,11 +524,7 @@ var FilterCreate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "filter range including the header row (e.g. A1:F1000)"},
- common.Flag{Name: "properties", Input: []string{common.File, common.Stdin},
- Desc: "optional rules JSON: { rules: [...], filtered_columns?: [...] }; empty filter when omitted"},
- ),
+ Flags: flagsFor("+filter-create"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -686,11 +606,7 @@ var FilterUpdate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "properties", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "patch JSON: { rules: [...], filtered_columns?: [...] } — read with +filter-list first"},
- common.Flag{Name: "range", Required: true, Desc: "filter range A1 (e.g. A1:F1000); overrides properties.range"},
- ),
+ Flags: flagsFor("+filter-update"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -757,7 +673,7 @@ var FilterDelete = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: publicSheetFlags(),
+ Flags: flagsFor("+filter-delete"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_object_crud_test.go b/shortcuts/sheets/lark_sheet_object_crud_test.go
index 933da4a38..88c610159 100644
--- a/shortcuts/sheets/lark_sheet_object_crud_test.go
+++ b/shortcuts/sheets/lark_sheet_object_crud_test.go
@@ -152,7 +152,7 @@ func TestObjectCRUDShortcuts_DryRun(t *testing.T) {
{
name: "+filter-view-create",
sc: FilterViewCreate,
- args: []string{"--url", testURL, "--sheet-id", testSheetID, "--properties", `{"view_name":"v1","range":"A1:Z100"}`},
+ args: []string{"--url", testURL, "--sheet-id", testSheetID, "--range", "A1:Z100", "--properties", `{"view_name":"v1"}`},
toolName: "manage_filter_view_object",
wantInput: map[string]interface{}{
"excel_id": testToken,
diff --git a/shortcuts/sheets/lark_sheet_object_list.go b/shortcuts/sheets/lark_sheet_object_list.go
index cb2bc0d82..7c3b442ca 100644
--- a/shortcuts/sheets/lark_sheet_object_list.go
+++ b/shortcuts/sheets/lark_sheet_object_list.go
@@ -31,17 +31,10 @@ type objectListSpec struct {
// Optional id filter. Empty filterFlag → no filter flag exposed.
filterFlag string // CLI flag name (without leading --), e.g. "chart-id"
filterField string // tool input key, e.g. "chart_id"
- filterDesc string // flag help text
}
func newObjectListShortcut(spec objectListSpec) common.Shortcut {
- flags := publicSheetFlags()
- if spec.filterFlag != "" {
- flags = append(flags, common.Flag{
- Name: spec.filterFlag,
- Desc: spec.filterDesc,
- })
- }
+ flags := flagsFor(spec.command)
return common.Shortcut{
Service: "sheets",
Command: spec.command,
@@ -102,7 +95,6 @@ var ChartList = newObjectListShortcut(objectListSpec{
toolName: "get_chart_objects",
filterFlag: "chart-id",
filterField: "chart_id",
- filterDesc: "optional chart reference_id; returns just that chart when set",
})
// PivotList — list pivot tables on a sheet.
@@ -112,7 +104,6 @@ var PivotList = newObjectListShortcut(objectListSpec{
toolName: "get_pivot_table_objects",
filterFlag: "pivot-table-id",
filterField: "pivot_table_id",
- filterDesc: "optional pivot table reference_id; returns just that pivot when set",
})
// CondFormatList — list conditional format rules. CLI's --rule-id maps to
@@ -123,7 +114,6 @@ var CondFormatList = newObjectListShortcut(objectListSpec{
toolName: "get_conditional_format_objects",
filterFlag: "rule-id",
filterField: "conditional_format_id",
- filterDesc: "optional rule reference_id (maps to conditional_format_id server-side)",
})
// FilterList — list active sheet-level filters. No id filter because each
@@ -143,7 +133,6 @@ var FilterViewList = newObjectListShortcut(objectListSpec{
toolName: "get_filter_view_objects",
filterFlag: "view-id",
filterField: "view_id",
- filterDesc: "optional filter-view reference_id; returns just that view when set",
})
// SparklineList — list sparkline groups on a sheet. The tool also accepts
@@ -155,7 +144,6 @@ var SparklineList = newObjectListShortcut(objectListSpec{
toolName: "get_sparkline_objects",
filterFlag: "group-id",
filterField: "group_id",
- filterDesc: "optional sparkline group reference_id; returns all sparklines in that group",
})
// FloatImageList — list floating images on a sheet (vs. embedded
@@ -166,5 +154,4 @@ var FloatImageList = newObjectListShortcut(objectListSpec{
toolName: "get_float_image_objects",
filterFlag: "float-image-id",
filterField: "float_image_id",
- filterDesc: "optional floating-image reference_id; returns just that image when set",
})
diff --git a/shortcuts/sheets/lark_sheet_range_operations.go b/shortcuts/sheets/lark_sheet_range_operations.go
index f249f317a..2910712a1 100644
--- a/shortcuts/sheets/lark_sheet_range_operations.go
+++ b/shortcuts/sheets/lark_sheet_range_operations.go
@@ -35,11 +35,7 @@ var CellsClear = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "A1 range to clear (e.g. A1:C10 / D3:D / 3:3)"},
- common.Flag{Name: "scope", Enum: []string{"content", "formats", "all"}, Default: "content",
- Desc: "what to clear: content (values+formulas only, default) / formats / all"},
- ),
+ Flags: flagsFor("+cells-clear"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -107,15 +103,7 @@ var CellsUnmerge = newMergeShortcut(
)
func newMergeShortcut(command, desc, op string, withMergeType bool) common.Shortcut {
- flags := append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "A1 range to merge / unmerge (e.g. A1:C3)"},
- )
- if withMergeType {
- flags = append(flags, common.Flag{
- Name: "merge-type", Enum: []string{"all", "rows", "columns"}, Default: "all",
- Desc: "merge strategy: all (one cell) / rows / columns",
- })
- }
+ flags := flagsFor(command)
return common.Shortcut{
Service: "sheets",
Command: command,
@@ -191,9 +179,6 @@ func mergeInput(runtime *common.RuntimeContext, token, sheetID, sheetName, op st
// Both shortcuts share the underlying resize_range tool; --end is inclusive
// in the new CLI surface (was exclusive in the legacy +dim-resize).
-var rowsResizeTypeEnum = []string{"pixel", "standard", "auto"}
-var colsResizeTypeEnum = []string{"pixel", "standard"}
-
// RowsResize wraps resize_range for row heights. --type auto enables
// auto-fit (rows only); --type pixel requires --size.
var RowsResize = common.Shortcut{
@@ -204,14 +189,8 @@ var RowsResize = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start row (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end row (inclusive)"},
- common.Flag{Name: "type", Required: true, Enum: rowsResizeTypeEnum,
- Desc: "sizing mode: `pixel` (needs --size) / `standard` (reset to default) / `auto` (auto-fit row height)"},
- common.Flag{Name: "size", Type: "int", Default: "0", Desc: "row height in pixels (e.g. 30); required with --type pixel, ignored otherwise"},
- ),
- Validate: validateResize("row"),
+ Flags: flagsFor("+rows-resize"),
+ Validate: validateResize("row"),
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
token, _ := resolveSpreadsheetToken(runtime)
sheetID, sheetName, _ := resolveSheetSelector(runtime)
@@ -245,14 +224,8 @@ var ColsResize = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start column (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end column (inclusive)"},
- common.Flag{Name: "type", Required: true, Enum: colsResizeTypeEnum,
- Desc: "sizing mode: `pixel` (needs --size) / `standard` (reset to default); `auto` is rows-only"},
- common.Flag{Name: "size", Type: "int", Default: "0", Desc: "column width in pixels (e.g. 120); required with --type pixel, ignored otherwise"},
- ),
- Validate: validateResize("column"),
+ Flags: flagsFor("+cols-resize"),
+ Validate: validateResize("column"),
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
token, _ := resolveSpreadsheetToken(runtime)
sheetID, sheetName, _ := resolveSheetSelector(runtime)
@@ -358,11 +331,7 @@ var RangeMove = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "source-range", Required: true, Desc: "source A1 range (e.g. A1:C5)"},
- common.Flag{Name: "target-range", Required: true, Desc: "target A1 starting cell (size derived from source)"},
- common.Flag{Name: "target-sheet-id", Desc: "destination sheet id (cross-sheet); omit for same sheet"},
- ),
+ Flags: flagsFor("+range-move"),
Validate: validateRangeMoveOrCopy,
DryRun: transformDryRunFn("move", false, false),
Execute: transformExecuteFn("move", false, false),
@@ -378,13 +347,7 @@ var RangeCopy = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "source-range", Required: true, Desc: "source A1 range"},
- common.Flag{Name: "target-range", Required: true, Desc: "target A1 starting cell"},
- common.Flag{Name: "target-sheet-id", Desc: "destination sheet id (cross-sheet); omit for same sheet"},
- common.Flag{Name: "paste-type", Enum: []string{"values", "formulas", "formats", "all"}, Default: "all",
- Desc: "what to copy: values / formulas / formats / all (default)"},
- ),
+ Flags: flagsFor("+range-copy"),
Validate: validateRangeMoveOrCopy,
DryRun: transformDryRunFn("copy", true, false),
Execute: transformExecuteFn("copy", true, false),
@@ -402,12 +365,7 @@ var RangeFill = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "source-range", Required: true, Desc: "template A1 range with seed cells"},
- common.Flag{Name: "target-range", Required: true, Desc: "target fill range (must be disjoint from source)"},
- common.Flag{Name: "series-type", Enum: []string{"auto", "linear", "growth", "date", "copy"}, Default: "auto",
- Desc: "auto / linear / growth / date → tool fillSeries; copy → tool copyCells"},
- ),
+ Flags: flagsFor("+range-fill"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -455,12 +413,7 @@ var RangeSort = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "A1 range to sort"},
- common.Flag{Name: "sort-keys", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "sort keys JSON, e.g. [{\"col\":\"B\",\"order\":\"asc\"},{\"col\":\"D\",\"order\":\"desc\"}]"},
- common.Flag{Name: "has-header", Type: "bool", Desc: "treat first row as header (excluded from sort); default false"},
- ),
+ Flags: flagsFor("+range-sort"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -613,10 +566,10 @@ func rangeSortInput(runtime *common.RuntimeContext, token, sheetID, sheetName st
return nil, err
}
input := map[string]interface{}{
- "excel_id": token,
- "operation": "sort",
- "range": strings.TrimSpace(runtime.Str("range")),
- "sort_conditions": keys,
+ "excel_id": token,
+ "operation": "sort",
+ "range": strings.TrimSpace(runtime.Str("range")),
+ "sort_conditions": keys,
}
sheetSelectorForToolInput(input, sheetID, sheetName)
if runtime.Bool("has-header") {
diff --git a/shortcuts/sheets/lark_sheet_read_data.go b/shortcuts/sheets/lark_sheet_read_data.go
index 428c209ab..4c87c5f1b 100644
--- a/shortcuts/sheets/lark_sheet_read_data.go
+++ b/shortcuts/sheets/lark_sheet_read_data.go
@@ -19,8 +19,6 @@ import (
// The sandbox tool (export_sheet_to_sandbox) is Sheet-Tool-only and has no
// CLI surface here.
-var cellsGetIncludeEnum = []string{"value", "formula", "style", "comment", "data_validation"}
-
// CellsGet wraps get_cell_ranges: read multiple A1 ranges and return per-cell
// values, formulas, styles, and other metadata as requested via --include.
var CellsGet = common.Shortcut{
@@ -31,13 +29,7 @@ var CellsGet = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "ranges", Type: "string_array", Required: true, Desc: "A1 ranges (repeat: --ranges A1:B2 --ranges D1:E5)"},
- common.Flag{Name: "include", Type: "string_slice", Enum: cellsGetIncludeEnum, Desc: "categories to include (default: value+style). value|formula|style|comment|data_validation"},
- common.Flag{Name: "skip-hidden", Type: "bool", Desc: "skip hidden rows/cols"},
- common.Flag{Name: "cell-limit", Type: "int", Default: "5000", Hidden: true, Desc: "anti-burst cell scan cap"},
- common.Flag{Name: "max-chars", Type: "int", Default: "200000", Hidden: true, Desc: "anti-burst response char cap"},
- ),
+ Flags: flagsFor("+cells-get"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -45,8 +37,8 @@ var CellsGet = common.Shortcut{
if _, _, err := resolveSheetSelector(runtime); err != nil {
return err
}
- if len(runtime.StrArray("ranges")) == 0 {
- return common.FlagErrorf("--ranges is required")
+ if len(runtime.StrArray("range")) == 0 {
+ return common.FlagErrorf("--range is required")
}
return nil
},
@@ -76,7 +68,7 @@ var CellsGet = common.Shortcut{
func cellsGetInput(runtime *common.RuntimeContext, token, sheetID, sheetName string) map[string]interface{} {
input := map[string]interface{}{
"excel_id": token,
- "ranges": runtime.StrArray("ranges"),
+ "ranges": runtime.StrArray("range"),
}
sheetSelectorForToolInput(input, sheetID, sheetName)
applyIncludeToCellsGet(input, runtime.StrSlice("include"))
@@ -129,17 +121,7 @@ var CsvGet = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Desc: "A1 range; omit for the sheet's current_region"},
- common.Flag{
- Name: "value-render-option", Enum: []string{"formatted_value", "raw_value", "formula"},
- Desc: "value rendering: formatted_value (default) / raw_value / formula",
- },
- common.Flag{Name: "include-row-prefix", Type: "bool", Default: "true", Desc: "keep [row=N] line prefix; pass --include-row-prefix=false to strip"},
- common.Flag{Name: "skip-hidden", Type: "bool", Desc: "skip hidden rows/cols"},
- common.Flag{Name: "max-rows", Type: "int", Default: "100000", Hidden: true, Desc: "anti-burst row cap"},
- common.Flag{Name: "max-chars", Type: "int", Default: "200000", Hidden: true, Desc: "anti-burst char cap"},
- ),
+ Flags: flagsFor("+csv-get"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -228,9 +210,7 @@ var DropdownGet = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "range", Required: true, Desc: "A1 range with sheet prefix (e.g. sheet1!A2:A100)"},
- ),
+ Flags: flagsFor("+dropdown-get"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_read_data_test.go b/shortcuts/sheets/lark_sheet_read_data_test.go
index c59441417..ea57d1762 100644
--- a/shortcuts/sheets/lark_sheet_read_data_test.go
+++ b/shortcuts/sheets/lark_sheet_read_data_test.go
@@ -23,7 +23,7 @@ func TestReadDataShortcuts_DryRun(t *testing.T) {
{
name: "+cells-get multi-range + include=style,formula",
sc: CellsGet,
- args: []string{"--url", testURL, "--sheet-id", testSheetID, "--ranges", "A1:B2", "--ranges", "D1:E5", "--include", "style,formula"},
+ args: []string{"--url", testURL, "--sheet-id", testSheetID, "--range", "A1:B2", "--range", "D1:E5", "--include", "style,formula"},
toolName: "get_cell_ranges",
wantInput: map[string]interface{}{
"excel_id": testToken,
diff --git a/shortcuts/sheets/lark_sheet_search_replace.go b/shortcuts/sheets/lark_sheet_search_replace.go
index a6d94db98..3c6f79ebd 100644
--- a/shortcuts/sheets/lark_sheet_search_replace.go
+++ b/shortcuts/sheets/lark_sheet_search_replace.go
@@ -27,16 +27,7 @@ var CellsSearch = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "find", Required: true, Desc: "text to search for (regex when --regex is set)"},
- common.Flag{Name: "range", Desc: "optional A1 range to scope the search"},
- common.Flag{Name: "match-case", Type: "bool", Desc: "case-sensitive match"},
- common.Flag{Name: "match-entire-cell", Type: "bool", Desc: "match the entire cell content only"},
- common.Flag{Name: "regex", Type: "bool", Desc: "treat --find as a regular expression"},
- common.Flag{Name: "include-formulas", Type: "bool", Desc: "also search inside formula text"},
- common.Flag{Name: "offset", Type: "int", Default: "0", Desc: "pagination offset (use next_offset from previous page)"},
- common.Flag{Name: "max-matches", Type: "int", Default: "5000", Hidden: true, Desc: "anti-burst match cap"},
- ),
+ Flags: flagsFor("+cells-search"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -122,15 +113,7 @@ var CellsReplace = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "find", Required: true, Desc: "text to find (regex when --regex is set)"},
- common.Flag{Name: "replacement", Required: true, Desc: "replacement text (empty string deletes the match)"},
- common.Flag{Name: "range", Desc: "optional A1 range to scope the replace"},
- common.Flag{Name: "match-case", Type: "bool", Desc: "case-sensitive match"},
- common.Flag{Name: "match-entire-cell", Type: "bool", Desc: "match the entire cell content only"},
- common.Flag{Name: "regex", Type: "bool", Desc: "treat --find as a regular expression"},
- common.Flag{Name: "include-formulas", Type: "bool", Desc: "also replace inside formula text"},
- ),
+ Flags: flagsFor("+cells-replace"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_sheet_structure.go b/shortcuts/sheets/lark_sheet_sheet_structure.go
index acfe1feeb..2b10f0819 100644
--- a/shortcuts/sheets/lark_sheet_sheet_structure.go
+++ b/shortcuts/sheets/lark_sheet_sheet_structure.go
@@ -33,15 +33,7 @@ var SheetInfo = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Desc: "optional A1-style range to scope the query (e.g. A1:C20 / 3:6 / C:E); omit for whole sheet"},
- common.Flag{
- Name: "include",
- Type: "string_slice",
- Enum: []string{"merges", "row_heights", "col_widths", "hidden_rows", "hidden_cols", "groups", "frozen"},
- Desc: "filter returned categories (comma-separated). Omit for all.",
- },
- ),
+ Flags: flagsFor("+sheet-info"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -121,9 +113,6 @@ func infoTypeFromInclude(include []string) string {
// ─── +dim-* (modify_sheet_structure) ──────────────────────────────────
-// dimEnum bounds the allowed values for --dimension across every +dim-* shortcut.
-var dimEnum = []string{"row", "column"}
-
// DimInsert inserts blank rows / columns and optionally inherits style from
// the adjacent dimension.
var DimInsert = common.Shortcut{
@@ -134,13 +123,8 @@ var DimInsert = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start position (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end position (exclusive)"},
- common.Flag{Name: "inherit-style", Enum: []string{"before", "after", "none"}, Default: "none", Desc: "inherit cell style from the row/column before, after, or neither"},
- ),
- Validate: validateDimRange,
+ Flags: flagsFor("+dim-insert"),
+ Validate: validateDimRange,
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
token, _ := resolveSpreadsheetToken(runtime)
sheetID, sheetName, _ := resolveSheetSelector(runtime)
@@ -193,12 +177,8 @@ var DimDelete = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start position (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end position (exclusive)"},
- ),
- Validate: validateDimRange,
+ Flags: flagsFor("+dim-delete"),
+ Validate: validateDimRange,
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
token, _ := resolveSpreadsheetToken(runtime)
sheetID, sheetName, _ := resolveSheetSelector(runtime)
@@ -251,10 +231,7 @@ var DimFreeze = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "count", Type: "int", Required: true, Desc: "number of leading rows/columns to freeze; 0 unfreezes the chosen dimension"},
- ),
+ Flags: flagsFor("+dim-freeze"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -363,12 +340,8 @@ func newDimRangeOpShortcut(command, desc, op, risk string) common.Shortcut {
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start position (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end position (exclusive)"},
- ),
- Validate: validateDimRange,
+ Flags: flagsFor(command),
+ Validate: validateDimRange,
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
token, _ := resolveSpreadsheetToken(runtime)
sheetID, sheetName, _ := resolveSheetSelector(runtime)
@@ -397,17 +370,7 @@ func newDimRangeOpShortcut(command, desc, op, risk string) common.Shortcut {
// --depth (currently unused server-side — accepted for forward-compat per
// the canonical spec) and --group-state (group only, defaults to expand).
func newDimGroupShortcut(command, desc, op string) common.Shortcut {
- flags := append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "0-based start position (inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "0-based end position (exclusive)"},
- common.Flag{Name: "depth", Type: "int", Default: "1", Desc: "nesting level (currently honored only when the server-side endpoint supports it)"},
- )
- if op == "group" {
- flags = append(flags,
- common.Flag{Name: "group-state", Enum: []string{"expand", "fold"}, Default: "expand", Desc: "initial state of the new group"},
- )
- }
+ flags := flagsFor(command)
return common.Shortcut{
Service: "sheets",
Command: command,
@@ -512,12 +475,7 @@ var DimMove = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only", "sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "dimension", Required: true, Enum: dimEnum, Desc: "`row` or `column`"},
- common.Flag{Name: "start", Type: "int", Required: true, Desc: "source start (0-indexed, inclusive)"},
- common.Flag{Name: "end", Type: "int", Required: true, Desc: "source end (0-indexed, inclusive)"},
- common.Flag{Name: "target", Type: "int", Required: true, Desc: "destination index (0-indexed); rows/cols move to land BEFORE this index"},
- ),
+ Flags: flagsFor("+dim-move"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_workbook.go b/shortcuts/sheets/lark_sheet_workbook.go
index cdfe6bcd6..17fd39e72 100644
--- a/shortcuts/sheets/lark_sheet_workbook.go
+++ b/shortcuts/sheets/lark_sheet_workbook.go
@@ -46,7 +46,7 @@ var WorkbookInfo = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: publicTokenFlags(),
+ Flags: flagsFor("+workbook-info"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
_, err := resolveSpreadsheetToken(runtime)
return err
@@ -88,12 +88,7 @@ var SheetCreate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "title", Desc: "new sheet title", Required: true},
- common.Flag{Name: "index", Type: "int", Default: "-1", Desc: "insertion position (0-based); omit to append"},
- common.Flag{Name: "row-count", Type: "int", Default: "0", Desc: "initial row count; omit for tool default (200)"},
- common.Flag{Name: "col-count", Type: "int", Default: "0", Desc: "initial column count; omit for tool default (20)"},
- ),
+ Flags: flagsFor("+sheet-create"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -155,7 +150,7 @@ var SheetDelete = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: publicSheetFlags(),
+ Flags: flagsFor("+sheet-delete"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -202,9 +197,7 @@ var SheetRename = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "title", Desc: "new sheet title", Required: true},
- ),
+ Flags: flagsFor("+sheet-rename"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -269,10 +262,7 @@ var SheetMove = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read", "sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "index", Type: "int", Required: true, Desc: "target position (0-based)"},
- common.Flag{Name: "source-index", Type: "int", Default: "-1", Desc: "source position (0-based); omitted → auto-derived from --sheet-id/--sheet-name's current workbook position"},
- ),
+ Flags: flagsFor("+sheet-move"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -367,10 +357,7 @@ var SheetCopy = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "title", Desc: "title for the duplicated sheet (server-generated when omitted)"},
- common.Flag{Name: "index", Type: "int", Default: "-1", Desc: "insertion position for the copy (0-based); omit to append"},
- ),
+ Flags: flagsFor("+sheet-copy"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -432,7 +419,7 @@ func newSheetVisibilityShortcut(command, desc, op string) common.Shortcut {
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: publicSheetFlags(),
+ Flags: flagsFor(command),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -477,9 +464,7 @@ var SheetSetTabColor = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "color", Desc: "hex color like #FF0000; pass empty string to clear"},
- ),
+ Flags: flagsFor("+sheet-set-tab-color"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -545,12 +530,7 @@ var WorkbookCreate = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:create", "sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: []common.Flag{
- {Name: "title", Required: true, Desc: "spreadsheet title"},
- {Name: "folder-token", Desc: "destination folder token; omit to land at the drive root"},
- {Name: "headers", Input: []string{common.File, common.Stdin}, Desc: "header row JSON array, e.g. [\"列A\",\"列B\"]"},
- {Name: "values", Input: []string{common.File, common.Stdin}, Desc: "initial data JSON 2D array, e.g. [[\"alice\",95]]"},
- },
+ Flags: flagsFor("+workbook-create"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("title")) == "" {
return common.FlagErrorf("--title is required")
@@ -707,11 +687,7 @@ var WorkbookExport = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:read", "docs:document:export", "drive:drive.metadata:readonly"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicTokenFlags(),
- common.Flag{Name: "file-extension", Enum: []string{"xlsx", "csv"}, Default: "xlsx", Desc: "xlsx (whole workbook) or csv (one sheet via --sheet-id)"},
- common.Flag{Name: "sheet-id", Desc: "csv mode only: target sheet reference_id to export"},
- common.Flag{Name: "output-path", Desc: "local file path to save into; omit to just trigger and report the file_token"},
- ),
+ Flags: flagsFor("+workbook-export"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/lark_sheet_workbook_test.go b/shortcuts/sheets/lark_sheet_workbook_test.go
index eaa49d16c..f7b257fc2 100644
--- a/shortcuts/sheets/lark_sheet_workbook_test.go
+++ b/shortcuts/sheets/lark_sheet_workbook_test.go
@@ -159,10 +159,10 @@ func TestSheetMove_DryRunResolvePlaceholders(t *testing.T) {
t.Parallel()
cases := []struct {
- name string
- args []string
- wantSheetID string
- wantSourceIdx interface{}
+ name string
+ args []string
+ wantSheetID string
+ wantSourceIdx interface{}
}{
{
name: "id only, no source-index → both literal + placeholder",
diff --git a/shortcuts/sheets/lark_sheet_write_cells.go b/shortcuts/sheets/lark_sheet_write_cells.go
index 7d61f5a95..527d6d5f8 100644
--- a/shortcuts/sheets/lark_sheet_write_cells.go
+++ b/shortcuts/sheets/lark_sheet_write_cells.go
@@ -42,13 +42,7 @@ var CellsSet = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "target A1 range (e.g. A1:C10); cells dimensions must match"},
- common.Flag{Name: "cells", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "JSON 2D matrix of cell objects, e.g. [[{\"value\":\"a\"},{\"value\":\"b\"}],[{\"value\":1},{\"value\":2}]]; dimensions must match --range"},
- common.Flag{Name: "allow-overwrite", Type: "bool", Default: "true", Desc: "allow overwriting non-empty cells (default true)"},
- common.Flag{Name: "max-cells", Type: "int", Default: "50000", Hidden: true, Desc: "anti-burst cells write cap"},
- ),
+ Flags: flagsFor("+cells-set"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -123,11 +117,7 @@ var CellsSetStyle = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(
- append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "target A1 range (e.g. A1:B2)"}),
- styleFlatFlags()...,
- ),
+ Flags: flagsFor("+cells-set-style"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -223,13 +213,7 @@ var CsvPut = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "csv", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "CSV text (RFC 4180); supports @file or stdin via -"},
- common.Flag{Name: "start-cell", Default: "A1", Required: true, Desc: "single A1 anchor cell, e.g. A1 / B5"},
- common.Flag{Name: "allow-overwrite", Type: "bool", Default: "true",
- Desc: "allow overwriting non-empty cells (default true); false errors if any target cell is non-empty"},
- ),
+ Flags: flagsFor("+csv-put"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -300,15 +284,7 @@ var DropdownSet = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "target A1 range (e.g. A2:A100)"},
- common.Flag{Name: "options", Input: []string{common.File, common.Stdin}, Required: true,
- Desc: "options JSON array (e.g. [\"opt1\",\"opt2\"]); ≤500 items, ≤100 chars each, no commas"},
- common.Flag{Name: "colors", Input: []string{common.File, common.Stdin},
- Desc: "optional RGB hex array (e.g. [\"#1FB6C1\",\"#F006C2\"]); length must equal --options"},
- common.Flag{Name: "multiple", Type: "bool", Desc: "enable multi-select; default false"},
- common.Flag{Name: "highlight", Type: "bool", Desc: "color-highlight options; default false"},
- ),
+ Flags: flagsFor("+dropdown-set"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
@@ -551,11 +527,7 @@ var CellsSetImage = common.Shortcut{
Scopes: []string{"sheets:spreadsheet:write_only", "drive:file:upload"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
- Flags: append(publicSheetFlags(),
- common.Flag{Name: "range", Required: true, Desc: "single target cell (e.g. A1; start/end must equal)"},
- common.Flag{Name: "image", Required: true, Desc: "local image path (PNG/JPEG/JPG/GIF/BMP/JFIF/EXIF/TIFF/BPG/HEIC)"},
- common.Flag{Name: "name", Desc: "uploaded file name (with extension); defaults to basename(--image)"},
- ),
+ Flags: flagsFor("+cells-set-image"),
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if _, err := resolveSpreadsheetToken(runtime); err != nil {
return err
diff --git a/shortcuts/sheets/shortcuts.go b/shortcuts/sheets/shortcuts.go
index 8c7a5c708..c71ef5572 100644
--- a/shortcuts/sheets/shortcuts.go
+++ b/shortcuts/sheets/shortcuts.go
@@ -14,7 +14,6 @@ import "github.com/larksuite/cli/shortcuts/common"
// `--print-schema --flag-name ` locally.
func Shortcuts() []common.Shortcut {
all := shortcutList()
- applyFlagDescs(all)
withSchema := commandsWithFlagSchema()
for i := range all {
if _, ok := withSchema[all[i].Command]; ok {
diff --git a/skills/lark-sheets/references/lark-sheets-batch-update.md b/skills/lark-sheets/references/lark-sheets-batch-update.md
index 0590be694..1fdd28a73 100644
--- a/skills/lark-sheets/references/lark-sheets-batch-update.md
+++ b/skills/lark-sheets/references/lark-sheets-batch-update.md
@@ -37,7 +37,8 @@ _公共:URL/token(无 sheet 定位) · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--operations` | string + File + Stdin(复合 JSON) | 是 | JSON:`{"operations":[{"tool":"`+cells-set`","params":{...}}, ...]}`;按数组顺序串行执行 |
+| `--operations` | string + File + Stdin(复合 JSON) | required | JSON 数组:`[{"tool_name":"`+cells-set`","input":{...}}, ...]`,按声明顺序串行执行;`tool_name` 为底层工具名(如 `+cells-set` / `+cells-clear` / `+dim-{insert|delete|hide|unhide|freeze|group|ungroup}`),`input` 结构与单独调用该工具一致 |
+| `--continue-on-error` | bool | optional | 遇子操作失败时继续执行剩余操作;默认 false(首个失败即整批中断) |
### `+cells-batch-set-style`
@@ -45,18 +46,18 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--ranges` | string + File + Stdin(简单 JSON) | 是 | 目标范围 JSON 数组,每项必须带 sheet 前缀(如 `["sheet1!A1:B2","sheet1!D1:D10"]`);所有 range 应用同一组 style |
-| `--background-color` | string | 否 | 背景颜色(十六进制,如 `#ffffff`) |
-| `--font-color` | string | 否 | 字体颜色(十六进制,如 `#000000`) |
-| `--font-size` | number | 否 | 字体大小(px,例:10、12、14) |
-| `--font-style` | string + Enum | 否 | 字体样式 enum:`normal` / `italic` |
-| `--font-weight` | string + Enum | 否 | 字重 enum:`normal` / `bold` |
-| `--font-line` | string + Enum | 否 | 字体线条样式 enum:`none` / `underline` / `line-through` |
-| `--horizontal-alignment` | string + Enum | 否 | 水平对齐 enum:`left` / `center` / `right` |
-| `--vertical-alignment` | string + Enum | 否 | 垂直对齐 enum:`top` / `middle` / `bottom` |
-| `--word-wrap` | string + Enum | 否 | 换行策略 enum:`overflow` / `auto-wrap` / `word-clip`,默认 `overflow` |
-| `--number-format` | string | 否 | 数字格式(例:文本 `@`、数字 `0.00`、货币 `$#,##0.00`、日期 `mm/dd/yyyy`) |
-| `--border-styles` | string + File + Stdin(复合 JSON) | 否 | 边框配置 JSON(结构同 +cells-set-style) |
+| `--ranges` | string + File + Stdin(简单 JSON) | required | 目标范围 JSON 数组,每项必须带 sheet 前缀(如 `["sheet1!A1:B2","sheet1!D1:D10"]`);所有 range 应用同一组 style |
+| `--background-color` | string | optional | 背景颜色(十六进制,如 `#ffffff`) |
+| `--font-color` | string | optional | 字体颜色(十六进制,如 `#000000`) |
+| `--font-size` | float64 | optional | 字体大小(px,例:10、12、14) |
+| `--font-style` | string | optional | 字体样式(可选值:`normal` / `italic`) |
+| `--font-weight` | string | optional | 字重(可选值:`normal` / `bold`) |
+| `--font-line` | string | optional | 字体线条样式(可选值:`none` / `underline` / `line-through`) |
+| `--horizontal-alignment` | string | optional | 水平对齐(可选值:`left` / `center` / `right`) |
+| `--vertical-alignment` | string | optional | 垂直对齐(可选值:`top` / `middle` / `bottom`) |
+| `--word-wrap` | string | optional | 换行策略(可选值:`overflow` / `auto-wrap` / `word-clip`) |
+| `--number-format` | string | optional | 数字格式(例:文本 `@`、数字 `0.00`、货币 `$#,##0.00`、日期 `mm/dd/yyyy`) |
+| `--border-styles` | string + File + Stdin(复合 JSON) | optional | 边框配置 JSON(结构同 +cells-set-style) |
### `+dropdown-update`
@@ -64,11 +65,11 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--ranges` | string + File + Stdin(简单 JSON) | 是 | 目标范围 JSON 数组(如 `["sheet1!A2:A100"]`),每项必须带 sheet 前缀 |
-| `--options` | string + File + Stdin(复合 JSON) | 是 | 选项 JSON 数组(如 `["opt1","opt2"]`) |
-| `--colors` | string + File + Stdin(简单 JSON) | 否 | 颜色数组(与 `--options` 等长) |
-| `--multiple` | bool | 否 | 启用多选 |
-| `--highlight` | bool | 否 | 选项配色 |
+| `--ranges` | string + File + Stdin(简单 JSON) | required | 目标范围 JSON 数组(如 `["sheet1!A2:A100"]`),每项必须带 sheet 前缀 |
+| `--options` | string + File + Stdin(复合 JSON) | required | 选项 JSON 数组(如 `["opt1","opt2"]`) |
+| `--colors` | string + File + Stdin(简单 JSON) | optional | 颜色数组(与 `--options` 等长) |
+| `--multiple` | bool | optional | 启用多选 |
+| `--highlight` | bool | optional | 选项配色 |
### `+dropdown-delete`
@@ -76,7 +77,7 @@ _公共:URL/token(无 sheet 定位) · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--ranges` | string + File + Stdin(简单 JSON) | 是 | 目标范围 JSON 数组(最多 100 个,每项必须带 sheet 前缀) |
+| `--ranges` | string + File + Stdin(简单 JSON) | required | 目标范围 JSON 数组(最多 100 个,每项必须带 sheet 前缀) |
## Schemas
@@ -102,16 +103,10 @@ _单元格边框配置,含 top/bottom/left/right 四个方向,每个方向
### `+dropdown-update` `--options`
-_数据验证配置_
+_列表选项(type='list' 时必填)_
-**顶层字段**:
-- `help_text` (string?) — 验证失败时显示的提示文本
-- `items` (array?) — 列表选项(type='list' 时必填)
-- `operator` (enum?) — 比较运算符(type='number'/'date'/'textLength' 时必填) [equal / notEqual / greaterThan / greaterThanOrEqual / lessThan / lessThanOrEqual / between / notBetween]
-- `range` (string?) — 源数据区域(type='listFromRange' 时必填,格式:'SheetName!A1:A10')
-- `support_multiple_values` (boolean?) — 列表验证是否支持多选(type='list'/'listFromRange' 时可选,默认 false)
-- `type` (enum) — 数据验证类型:list(下拉列表)、listFromRange(引用范围下拉列表)、number(数字)、date(日期)、textLength(文本长度)、… [list / listFromRange / number / date / textLength / checkbox]
-- `values` (array?) — 比较值(operator 为 'between'/'notBetween' 时需要两个值,其它运算符需要一个值)
+**数组项**(类型 string):
+- 标量:string
## Examples
@@ -125,10 +120,10 @@ _数据验证配置_
lark-cli sheets +batch-update --url "https://example.feishu.cn/sheets/shtXXX" --yes \
--operations @ops.json
-# ops.json (array<{tool_name, input}>):
+# ops.json (array<{tool_name, input}>,tool_name 是 CLI shortcut 名):
# [
-# {"tool_name": "modify_sheet_structure", "input": {"sheet_id":"...","operation":"insert","dimension":"row","start":10,"end":12}},
-# {"tool_name": "set_cell_range", "input": {"sheet_id":"...","range":"A11:B12","cells":[[{"value":"a"},{"value":"b"}],[{"value":"c"},{"value":"d"}]]}}
+# {"tool_name": "+dim-insert", "input": {"sheet_id":"...","dimension":"row","start":10,"end":12}},
+# {"tool_name": "+cells-set", "input": {"sheet_id":"...","range":"A11:B12","cells":[[{"value":"a"},{"value":"b"}],[{"value":"c"},{"value":"d"}]]}}
# ]
```
@@ -137,9 +132,9 @@ lark-cli sheets +batch-update --url "https://example.feishu.cn/sheets/shtXXX" --
> ```jsonc
> // 在 C 列前插入新列 → 写表头 C1 → 回填 C2:C100 共 99 行
> [
-> {"tool_name": "`+dim-{insert|delete|hide|unhide|freeze|group|ungroup}`",
-> "input": {"sheet_id": "...", "operation": "insert", "dimension": "column", "start": 3, "end": 4}},
-> {"tool_name": "`+cells-set`",
+> {"tool_name": "+dim-insert",
+> "input": {"sheet_id": "...", "dimension": "column", "start": 3, "end": 4}},
+> {"tool_name": "+cells-set",
> "input": {"sheet_id": "...", "range": "C1:C100",
> "cells": [[{"value":"score"}], [{"value":95}], [{"value":87}], /* ... 97 more rows ... */ ]}}
> ]
diff --git a/skills/lark-sheets/references/lark-sheets-chart.md b/skills/lark-sheets/references/lark-sheets-chart.md
index 3b7012a7c..4ea612bed 100644
--- a/skills/lark-sheets/references/lark-sheets-chart.md
+++ b/skills/lark-sheets/references/lark-sheets-chart.md
@@ -111,7 +111,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--chart-id` | string | 否 | 指定单个图表 reference_id 过滤 |
+| `--chart-id` | string | optional | 指定单个图表 reference_id 过滤 |
### `+chart-create`
@@ -119,7 +119,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 图表完整配置 JSON(`position` / `data` / `properties` 等);结构嵌套深,统一走 JSON 注入 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 图表完整配置 JSON(`position` / `data` / `properties` 等);结构嵌套深,统一走 JSON 注入 |
### `+chart-update`
@@ -127,8 +127,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--chart-id` | string | 是 | 目标图表 reference_id |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 完整或足够完整的图表配置 JSON(先 `+chart-list` 回读再 patch) |
+| `--chart-id` | string | required | 目标图表 reference_id |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 完整或足够完整的图表配置 JSON(先 `+chart-list` 回读再 patch) |
### `+chart-delete`
@@ -136,7 +136,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--chart-id` | string | 是 | 目标图表 reference_id |
+| `--chart-id` | string | required | 目标图表 reference_id |
## Schemas
diff --git a/skills/lark-sheets/references/lark-sheets-conditional-format.md b/skills/lark-sheets/references/lark-sheets-conditional-format.md
index d305f5564..b8c69eb1b 100644
--- a/skills/lark-sheets/references/lark-sheets-conditional-format.md
+++ b/skills/lark-sheets/references/lark-sheets-conditional-format.md
@@ -87,7 +87,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--rule-id` | string | 否 | 按规则 id 过滤 |
+| `--rule-id` | string | optional | 按规则 id 过滤 |
### `+cond-format-create`
@@ -95,9 +95,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 规则配置 JSON,含 `style`(命中样式,必填)和 `attrs?`(规则参数列表,因 `rule_type` 不同结构而异)/ `has_ref?`。`rule_type` 和 `ranges` 已拎为独立 flag |
-| `--rule-type` | string + Enum | 是 | 条件格式规则类型 enum:`cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`(共 13 项);优先级高于 `--properties` 中同名字段 |
-| `--ranges` | string + File + Stdin(简单 JSON) | 是 | 应用条件格式的 A1 范围 JSON 数组(如 `["A1:A100","C2:C50"]`);优先级高于 `--properties` 中同名字段 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 规则配置 JSON,含 `style`(命中样式,必填)和 `attrs?`(规则参数列表,因 `rule_type` 不同结构而异)/ `has_ref?`。`rule_type` 和 `ranges` 已拎为独立 flag |
+| `--rule-type` | string | required | 条件格式规则类型;优先级高于 `--properties` 中同名字段(可选值:`cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`) |
+| `--ranges` | string + File + Stdin(简单 JSON) | required | 应用条件格式的 A1 范围 JSON 数组(如 `["A1:A100","C2:C50"]`);优先级高于 `--properties` 中同名字段 |
### `+cond-format-update`
@@ -105,10 +105,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--rule-id` | string | 是 | 目标规则 id |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 规则配置 JSON,结构同 `+cond-format-create` 的 `--properties`;update 是整组覆盖式 |
-| `--rule-type` | string + Enum | 是 | 条件格式规则类型 enum:`cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`(共 13 项);优先级高于 `--properties` 中同名字段 |
-| `--ranges` | string + File + Stdin(简单 JSON) | 是 | 应用条件格式的 A1 范围 JSON 数组(如 `["A1:A100","C2:C50"]`);优先级高于 `--properties` 中同名字段 |
+| `--rule-id` | string | required | 目标规则 id |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 规则配置 JSON,结构同 `+cond-format-create` 的 `--properties`;update 是整组覆盖式 |
+| `--rule-type` | string | required | 条件格式规则类型;优先级高于 `--properties` 中同名字段(可选值:`cellValue` / `formula` / `duplicate` / `unique` / `topBottom` / `aboveBelowAverage` / `dataBar` / `colorScale` / `iconSet` / `textContains` / `dateOccurring` / `blankCell` / `errorCell`) |
+| `--ranges` | string + File + Stdin(简单 JSON) | required | 应用条件格式的 A1 范围 JSON 数组(如 `["A1:A100","C2:C50"]`);优先级高于 `--properties` 中同名字段 |
### `+cond-format-delete`
@@ -116,7 +116,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--rule-id` | string | 是 | 目标规则 id |
+| `--rule-id` | string | required | 目标规则 id |
## Schemas
@@ -147,7 +147,7 @@ _创建/更新的条件格式属性_
# 重复值高亮
lark-cli sheets +cond-format-create --url "..." --sheet-id "$SID" \
--rule-type duplicate --ranges '["A1:A100"]' \
- --properties '{"style":{"background_color":"#FFD7D7"}}'
+ --properties '{"style":{"back_color":"#FFD7D7"}}'
# 数据条
lark-cli sheets +cond-format-create --url "..." --sheet-id "$SID" \
diff --git a/skills/lark-sheets/references/lark-sheets-filter-view.md b/skills/lark-sheets/references/lark-sheets-filter-view.md
index d35ed4cee..6da48d78a 100644
--- a/skills/lark-sheets/references/lark-sheets-filter-view.md
+++ b/skills/lark-sheets/references/lark-sheets-filter-view.md
@@ -40,7 +40,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--view-id` | string | 否 | 按筛选视图 reference_id 过滤(命中即只返回单个视图) |
+| `--view-id` | string | optional | 按筛选视图 reference_id 过滤(命中即只返回单个视图) |
### `+filter-view-create`
@@ -48,9 +48,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 筛选视图规则 JSON,含 `rules?`(列级筛选规则数组)和 `filtered_columns?`。`range` 和 `view_name` 是独立 flag |
-| `--range` | string | 是 | 筛选视图作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段;create 必填,必须覆盖表头行 |
-| `--view-name` | string | 否 | 筛选视图名称;create 不传时系统自动分配,update 不传时保留原名;优先级高于 `--properties` 中同名字段 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 筛选视图规则 JSON,含 `rules?`(列级筛选规则数组)和 `filtered_columns?`。`range` 和 `view_name` 是独立 flag |
+| `--range` | string | required | 筛选视图作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段;create 必填,必须覆盖表头行 |
+| `--view-name` | string | optional | 筛选视图名称;create 不传时系统自动分配,update 不传时保留原名;优先级高于 `--properties` 中同名字段 |
### `+filter-view-update`
@@ -58,10 +58,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--view-id` | string | 是 | 目标筛选视图 reference_id |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 筛选视图规则 JSON,含 `rules?` 和 `filtered_columns?`。`range` 和 `view_name` 是独立 flag;至少传 `--properties.rules` / `--range` / `--view-name` 之一 |
-| `--range` | string | 否 | 筛选视图作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段;update 时省略表示保留当前 range |
-| `--view-name` | string | 否 | 筛选视图名称;create 不传时系统自动分配,update 不传时保留原名;优先级高于 `--properties` 中同名字段 |
+| `--view-id` | string | required | 目标筛选视图 reference_id |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 筛选视图规则 JSON,含 `rules?` 和 `filtered_columns?`。`range` 和 `view_name` 是独立 flag;至少传 `--properties.rules` / `--range` / `--view-name` 之一 |
+| `--range` | string | optional | 筛选视图作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段;update 时省略表示保留当前 range |
+| `--view-name` | string | optional | 筛选视图名称;create 不传时系统自动分配,update 不传时保留原名;优先级高于 `--properties` 中同名字段 |
### `+filter-view-delete`
@@ -69,7 +69,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--view-id` | string | 是 | 目标筛选视图 reference_id |
+| `--view-id` | string | required | 目标筛选视图 reference_id |
## Schemas
@@ -108,7 +108,7 @@ lark-cli sheets +filter-view-list --url "..." --sheet-id "$SID" --view-id vAbcde
```bash
lark-cli sheets +filter-view-create --url "..." --sheet-id "$SID" \
--view-name "活跃用户" --range "A1:F1000" \
- --properties '{"rules":[{"col":"C","filter_type":"number","compare":"greater","expected":[100]}]}'
+ --properties '{"rules":[{"column_index":"C","conditions":[{"type":"number","compare_type":"greaterThan","values":[100]}]}]}'
```
> `--range` **必须覆盖表头行**(如 `A1:F1000`),不能只包含数据行;`--view-name` 重名时服务端自动改名。
diff --git a/skills/lark-sheets/references/lark-sheets-filter.md b/skills/lark-sheets/references/lark-sheets-filter.md
index 055e42d17..04bef892e 100644
--- a/skills/lark-sheets/references/lark-sheets-filter.md
+++ b/skills/lark-sheets/references/lark-sheets-filter.md
@@ -50,8 +50,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 筛选范围(A1 表示法,含表头行,如 `A1:F1000`);不要重复写入 `--properties` 中的 range 字段 |
-| `--properties` | string + File + Stdin(复合 JSON) | 否 | 筛选规则 JSON,含 `rules`(列级筛选规则数组,必填)和 `filtered_columns?`(激活列索引提示)。`range` 是独立 flag(不要再放此 JSON 里) |
+| `--range` | string | required | 筛选范围(A1 表示法,含表头行,如 `A1:F1000`);不要重复写入 `--properties` 中的 range 字段 |
+| `--properties` | string + File + Stdin(复合 JSON) | optional | 筛选规则 JSON,含 `rules`(列级筛选规则数组,必填)和 `filtered_columns?`(激活列索引提示)。`range` 是独立 flag(不要再放此 JSON 里) |
### `+filter-update`
@@ -59,8 +59,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 筛选规则 JSON,含 `rules` 和 `filtered_columns?`;update 是整组覆盖式(传空 `rules: []` 清空)。`range` 已拎为独立 flag |
-| `--range` | string | 是 | 筛选作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 筛选规则 JSON,含 `rules` 和 `filtered_columns?`;update 是整组覆盖式(传空 `rules: []` 清空)。`range` 已拎为独立 flag |
+| `--range` | string | required | 筛选作用的单元格范围(A1 表示法,如 `A1:F1000`);优先级高于 `--properties` 中同名字段 |
### `+filter-delete`
@@ -94,7 +94,7 @@ _创建/更新的筛选器属性_
```bash
lark-cli sheets +filter-create --url "..." --sheet-id "$SID" \
--range "A1:F1000" \
- --properties '{"rules":[{"col":"B","filter_type":"multiValue","expected":["北京","上海"]}]}'
+ --properties '{"rules":[{"column_index":"B","conditions":[{"type":"multiValue","compare_type":"equal","values":["北京","上海"]}]}]}'
```
### `+filter-update`
diff --git a/skills/lark-sheets/references/lark-sheets-float-image.md b/skills/lark-sheets/references/lark-sheets-float-image.md
index 25d23b4cc..83cb373fd 100644
--- a/skills/lark-sheets/references/lark-sheets-float-image.md
+++ b/skills/lark-sheets/references/lark-sheets-float-image.md
@@ -51,7 +51,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--float-image-id` | string | 否 | 按 id 过滤;省略时列工作表全部 |
+| `--float-image-id` | string | optional | 按 id 过滤;省略时列工作表全部 |
### `+float-image-create`
@@ -59,16 +59,16 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--image-name` | string | 是 | 图片名称,含扩展名(如 `logo.png`) |
-| `--image-token` | string | XOR | 图片 file_token(与 `--image-uri` 二选一)。常见来源:`+float-image-list` 返回的 `image_token` |
-| `--image-uri` | string | XOR | 图片 reference_id(与 `--image-token` 二选一);形如 `<\|image\|>:abcdef` 这种带前缀的字符串 |
-| `--position-row` | int | 是 | 图片左上角所在行(0-based) |
-| `--position-col` | string | 是 | 图片左上角所在列(列字母,如 `A` / `B`) |
-| `--size-width` | int | 是 | 图片宽度(像素) |
-| `--size-height` | int | 是 | 图片高度(像素) |
-| `--offset-row` | int | 否 | 在 `--position-row` 基础上的行内偏移(像素) |
-| `--offset-col` | int | 否 | 在 `--position-col` 基础上的列内偏移(像素) |
-| `--z-index` | int | 否 | 图片 Z 轴层级,控制重叠顺序 |
+| `--image-name` | string | required | 图片名称,含扩展名(如 `logo.png`) |
+| `--image-token` | string | xor | 图片 file_token(与 `--image-uri` 二选一)。常见来源:`+float-image-list` 返回的 `image_token` |
+| `--image-uri` | string | xor | 图片 reference_id(与 `--image-token` 二选一);形如 `<\|image\|>:abcdef` 这种带前缀的字符串 |
+| `--position-row` | int | required | 图片左上角所在行(0-based) |
+| `--position-col` | string | required | 图片左上角所在列(列字母,如 `A` / `B`) |
+| `--size-width` | int | required | 图片宽度(像素) |
+| `--size-height` | int | required | 图片高度(像素) |
+| `--offset-row` | int | optional | 在 `--position-row` 基础上的行内偏移(像素) |
+| `--offset-col` | int | optional | 在 `--position-col` 基础上的列内偏移(像素) |
+| `--z-index` | int | optional | 图片 Z 轴层级,控制重叠顺序 |
### `+float-image-update`
@@ -76,17 +76,17 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--float-image-id` | string | 是 | 目标图片 id |
-| `--image-name` | string | 是 | 图片名称,含扩展名(如 `logo.png`) |
-| `--image-token` | string | XOR | 图片 file_token(与 `--image-uri` 二选一)。常见来源:`+float-image-list` 返回的 `image_token` |
-| `--image-uri` | string | XOR | 图片 reference_id(与 `--image-token` 二选一);形如 `<\|image\|>:abcdef` 这种带前缀的字符串 |
-| `--position-row` | int | 是 | 图片左上角所在行(0-based) |
-| `--position-col` | string | 是 | 图片左上角所在列(列字母,如 `A` / `B`) |
-| `--size-width` | int | 是 | 图片宽度(像素) |
-| `--size-height` | int | 是 | 图片高度(像素) |
-| `--offset-row` | int | 否 | 在 `--position-row` 基础上的行内偏移(像素) |
-| `--offset-col` | int | 否 | 在 `--position-col` 基础上的列内偏移(像素) |
-| `--z-index` | int | 否 | 图片 Z 轴层级,控制重叠顺序 |
+| `--float-image-id` | string | required | 目标图片 id |
+| `--image-name` | string | required | 图片名称,含扩展名(如 `logo.png`) |
+| `--image-token` | string | xor | 图片 file_token(与 `--image-uri` 二选一)。常见来源:`+float-image-list` 返回的 `image_token` |
+| `--image-uri` | string | xor | 图片 reference_id(与 `--image-token` 二选一);形如 `<\|image\|>:abcdef` 这种带前缀的字符串 |
+| `--position-row` | int | required | 图片左上角所在行(0-based) |
+| `--position-col` | string | required | 图片左上角所在列(列字母,如 `A` / `B`) |
+| `--size-width` | int | required | 图片宽度(像素) |
+| `--size-height` | int | required | 图片高度(像素) |
+| `--offset-row` | int | optional | 在 `--position-row` 基础上的行内偏移(像素) |
+| `--offset-col` | int | optional | 在 `--position-col` 基础上的列内偏移(像素) |
+| `--z-index` | int | optional | 图片 Z 轴层级,控制重叠顺序 |
### `+float-image-delete`
@@ -94,7 +94,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--float-image-id` | string | 是 | 目标图片 id |
+| `--float-image-id` | string | required | 目标图片 id |
## Examples
@@ -120,12 +120,24 @@ lark-cli sheets +float-image-create --url "..." --sheet-id "$SID" \
### `+float-image-update`
-> 必须先 `+float-image-list --float-image-id ` 回读当前完整属性,再通过 `--image-name` / `--position-*` / `--size-*` 等独立 flag 改对应字段。
+> **patch 模式**:除了 `--float-image-id`(必填,定位目标图片)外,其它字段都可选——只传你需要改的那几个,未传的字段保持原值不变。至少传一个改动字段。
+>
+> 推荐流程:先 `+float-image-list --float-image-id ` 回读当前完整属性,再针对要改的字段调一次 `+float-image-update`。
+
+```bash
+# 只改位置,保留其它属性
+lark-cli sheets +float-image-update --url "..." --sheet-id "$SID" \
+ --float-image-id "$IMG_ID" --position-row 5 --position-col C
+
+# 只换图,位置/尺寸不变
+lark-cli sheets +float-image-update --url "..." --sheet-id "$SID" \
+ --float-image-id "$IMG_ID" --image-name "new-logo.png" --image-token "$NEW_TOKEN"
+```
### `+float-image-delete`
### Validate / DryRun / Execute 约束
-- `Validate`:XOR 公共四件套;`+float-image-create` 校验 `--image-name` 非空,`--image-token` 与 `--image-uri` 互斥且至少一个非空,`--position-row/col` 与 `--size-width/height` 必填且为合法整数;`+float-image-update` 必须 `--float-image-id`;`+float-image-delete` 强制 `--yes` 或 `--dry-run`。
+- `Validate`:XOR 公共四件套;`+float-image-create` 校验 `--image-name` 非空,`--image-token` 与 `--image-uri` 互斥且至少一个非空,`--position-row/col` 与 `--size-width/height` 必填且为合法整数;`+float-image-update` 必须 `--float-image-id`,其余 `--image-name` / `--image-token` / `--image-uri` / `--position-*` / `--size-*` / `--offset-*` / `--z-index` 至少传 1 个(patch 模式:未传字段保持原值);`+float-image-delete` 强制 `--yes` 或 `--dry-run`。
- `DryRun`:写操作输出"将要 POST/PATCH/DELETE 的 float_image 请求模板"。
- `Execute`:写后调用 `+float-image-list --float-image-id ` 回读,envelope.meta.verification 给出新位置 / 尺寸对比。
diff --git a/skills/lark-sheets/references/lark-sheets-pivot-table.md b/skills/lark-sheets/references/lark-sheets-pivot-table.md
index 531a0de53..c30b3a8df 100644
--- a/skills/lark-sheets/references/lark-sheets-pivot-table.md
+++ b/skills/lark-sheets/references/lark-sheets-pivot-table.md
@@ -53,7 +53,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--pivot-table-id` | string | 否 | 按 id 过滤 |
+| `--pivot-table-id` | string | optional | 按 id 过滤 |
### `+pivot-create`
@@ -61,11 +61,11 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | JSON:`{"data_range":"Sheet1!A1:F1000","rows":[...],"columns":[...],"values":[...],"filters":[...],"show_row_grand_total":true,"show_col_grand_total":true}` |
-| `--target-sheet-id` | string | 否 | 透视表落点子表 id;省略时自动新建子表(推荐) |
-| `--target-position` | string | 否 | 落点起始 cell(A1 格式,如 `A1`),默认 `A1` |
-| `--source` | string | 是 | 透视表源数据区域(A1 表示法,格式 `SheetName!StartCell:EndCell`,如 `Sheet1!A1:D100`) |
-| `--range` | string | 否 | 透视表放置位置(左上角 A1 单值,如 `F1`);省略时放在新建子表的左上角 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | JSON:`{"data_range":"Sheet1!A1:F1000","rows":[...],"columns":[...],"values":[...],"filters":[...],"show_row_grand_total":true,"show_col_grand_total":true}` |
+| `--target-sheet-id` | string | optional | 透视表落点子表 id;省略时自动新建子表(推荐) |
+| `--target-position` | string | optional | 落点起始 cell(A1 格式,如 `A1`),默认 `A1` |
+| `--source` | string | required | 透视表源数据区域(A1 表示法,格式 `SheetName!StartCell:EndCell`,如 `Sheet1!A1:D100`) |
+| `--range` | string | optional | 透视表放置位置(左上角 A1 单值,如 `F1`);省略时放在新建子表的左上角 |
### `+pivot-update`
@@ -73,8 +73,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--pivot-table-id` | string | 是 | 目标透视表 id |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 完整或足够完整的配置(先 `+pivot-list --pivot-table-id ` 回读再 patch) |
+| `--pivot-table-id` | string | required | 目标透视表 id |
+| `--properties` | string + File + Stdin(复合 JSON) | required | 完整或足够完整的配置(先 `+pivot-list --pivot-table-id ` 回读再 patch) |
### `+pivot-delete`
@@ -82,7 +82,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--pivot-table-id` | string | 是 | 目标透视表 id |
+| `--pivot-table-id` | string | required | 目标透视表 id |
## Schemas
diff --git a/skills/lark-sheets/references/lark-sheets-range-operations.md b/skills/lark-sheets/references/lark-sheets-range-operations.md
index 0d3918c13..b6733b18d 100644
--- a/skills/lark-sheets/references/lark-sheets-range-operations.md
+++ b/skills/lark-sheets/references/lark-sheets-range-operations.md
@@ -101,8 +101,8 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 清除范围(A1 格式) |
-| `--scope` | string + Enum | 否 | 清除范围 enum:`content`(默认,仅清内容)/ `formats`(仅清格式)/ `all`(清内容 + 格式) |
+| `--range` | string | required | 清除范围(A1 格式) |
+| `--scope` | string | optional | 清除范围 enum:`content`(默认,仅清内容)/ `formats`(仅清格式)/ `all`(清内容 + 格式)(可选值:`content` / `formats` / `all`) |
### `+cells-merge`
@@ -110,8 +110,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 待合并 / 取消合并的范围(A1 格式) |
-| `--merge-type` | string + Enum | 否 | 合并方向 enum(仅 `+cells-merge`):`all` / `rows` / `columns`,默认 `all` |
+| `--range` | string | required | 待合并 / 取消合并的范围(A1 格式) |
+| `--merge-type` | string | optional | 合并方向(仅 `+cells-merge`)(可选值:`all` / `rows` / `columns`) |
### `+cells-unmerge`
@@ -119,8 +119,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 待合并 / 取消合并的范围(A1 格式) |
-| `--merge-type` | string + Enum | 否 | 合并方向 enum(仅 `+cells-merge`):`all` / `rows` / `columns`,默认 `all` |
+| `--range` | string | required | 待合并 / 取消合并的范围(A1 格式) |
### `+rows-resize`
@@ -128,10 +127,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--start` | int | 是 | 起始行(0-based, inclusive) |
-| `--end` | int | 是 | 结束行(0-based, inclusive) |
-| `--type` | string + Enum | 是 | 尺寸方式 enum:`pixel`(指定 px 像素值,需配 `--size`)/ `standard`(重置为默认标准行高)/ `auto`(自动适应内容) |
-| `--size` | int | 否 | 行高(像素,例:30 / 40 / 60);`--type pixel` 时必填,其它 type 忽略 |
+| `--start` | int | required | 起始行(0-based, inclusive) |
+| `--end` | int | required | 结束行(0-based, inclusive) |
+| `--type` | string | required | 尺寸方式 enum:`pixel`(指定 px 像素值,需配 `--size`)/ `standard`(重置为默认标准行高)/ `auto`(自动适应内容)(可选值:`pixel` / `standard` / `auto`) |
+| `--size` | int | optional | 行高(像素,例:30 / 40 / 60);`--type pixel` 时必填,其它 type 忽略 |
### `+cols-resize`
@@ -139,10 +138,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--start` | int | 是 | 起始列(0-based, inclusive) |
-| `--end` | int | 是 | 结束列(0-based, inclusive) |
-| `--type` | string + Enum | 是 | 尺寸方式 enum:`pixel`(指定 px 像素值,需配 `--size`)/ `standard`(重置为默认标准列宽) |
-| `--size` | int | 否 | 列宽(像素,例:80 / 120 / 200);`--type pixel` 时必填,其它 type 忽略 |
+| `--start` | int | required | 起始列(0-based, inclusive) |
+| `--end` | int | required | 结束列(0-based, inclusive) |
+| `--type` | string | required | 尺寸方式 enum:`pixel`(指定 px 像素值,需配 `--size`)/ `standard`(重置为默认标准列宽)(可选值:`pixel` / `standard`) |
+| `--size` | int | optional | 列宽(像素,例:80 / 120 / 200);`--type pixel` 时必填,其它 type 忽略 |
### `+range-move`
@@ -150,10 +149,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--source-range` | string | 是 | 源 A1 范围 |
-| `--target-sheet-id` | string | 否 | 目标子表 id;省略时同源 sheet |
-| `--target-range` | string | 是 | 目标 A1 范围(传起点 cell 即可,按源尺寸自动推断) |
-| `--paste-type` | string + Enum | 否 | 粘贴内容 enum(仅 `+range-copy`):`values` / `formulas` / `formats` / `all`,默认 `all` |
+| `--source-range` | string | required | 源 A1 范围 |
+| `--target-sheet-id` | string | optional | 目标子表 id;省略时同源 sheet |
+| `--target-range` | string | required | 目标 A1 范围(传起点 cell 即可,按源尺寸自动推断) |
### `+range-copy`
@@ -161,10 +159,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--source-range` | string | 是 | 源 A1 范围 |
-| `--target-sheet-id` | string | 否 | 目标子表 id;省略时同源 sheet |
-| `--target-range` | string | 是 | 目标 A1 范围(传起点 cell 即可,按源尺寸自动推断) |
-| `--paste-type` | string + Enum | 否 | 粘贴内容 enum(仅 `+range-copy`):`values` / `formulas` / `formats` / `all`,默认 `all` |
+| `--source-range` | string | required | 源 A1 范围 |
+| `--target-sheet-id` | string | optional | 目标子表 id;省略时同源 sheet |
+| `--target-range` | string | required | 目标 A1 范围(传起点 cell 即可,按源尺寸自动推断) |
+| `--paste-type` | string | optional | 粘贴内容(仅 `+range-copy`)(可选值:`values` / `formulas` / `formats` / `all`) |
### `+range-fill`
@@ -172,9 +170,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--source-range` | string | 是 | 填充模板范围(系列起始 cells) |
-| `--target-range` | string | 是 | 目标填充范围(A1 格式) |
-| `--series-type` | string + Enum | 否 | 填充序列类型 enum:`auto` / `linear` / `growth` / `date` / `copy`,默认 `auto` |
+| `--source-range` | string | required | 填充模板范围(系列起始 cells) |
+| `--target-range` | string | required | 目标填充范围(A1 格式) |
+| `--series-type` | string | optional | 填充序列类型(可选值:`auto` / `linear` / `growth` / `date` / `copy`) |
### `+range-sort`
@@ -182,9 +180,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 排序范围(A1 格式;含或不含表头由 `--has-header` 决定) |
-| `--sort-keys` | string + File + Stdin(复合 JSON) | 是 | JSON:`[{"col":"B","order":"asc"},{"col":"D","order":"desc"}]` |
-| `--has-header` | bool | 否 | 第一行是表头不参与排序,默认 false |
+| `--range` | string | required | 排序范围(A1 格式;含或不含表头由 `--has-header` 决定) |
+| `--sort-keys` | string + File + Stdin(复合 JSON) | required | JSON 数组:`[{"column":"<列字母>","ascending":}, ...]` |
+| `--has-header` | bool | optional | 第一行是表头不参与排序,默认 false |
## Schemas
diff --git a/skills/lark-sheets/references/lark-sheets-read-data.md b/skills/lark-sheets/references/lark-sheets-read-data.md
index 11315f579..4471d62c1 100644
--- a/skills/lark-sheets/references/lark-sheets-read-data.md
+++ b/skills/lark-sheets/references/lark-sheets-read-data.md
@@ -88,11 +88,11 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | A1 范围,如 `Sheet1!A1:F10` |
-| `--include` | string_slice + Enum | 否 | `value` / `formula` / `style` / `comment` / `data_validation`,逗号分隔 |
-| `--cell-limit` | int + Hidden | 否 | 防爆,默认 5000 |
-| `--max-chars` | int + Hidden | 否 | 防爆,默认 200000 |
-| `--skip-hidden` | bool | 否 | 跳过隐藏行列,默认 `false` |
+| `--range` | string_array | required | A1 范围,如 `Sheet1!A1:F10` |
+| `--include` | string_slice | optional | 要返回的信息类别,逗号分隔多个(可选值:`value` / `formula` / `style` / `comment` / `data_validation`) |
+| `--cell-limit` | int | optional | 防爆,默认 5000 |
+| `--max-chars` | int | optional | 防爆,默认 200000 |
+| `--skip-hidden` | bool | optional | 跳过隐藏行列,默认 `false` |
### `+dropdown-get`
@@ -100,7 +100,7 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 目标范围(A1 格式,必须带 sheet 前缀,如 `sheet1!A2:A100`) |
+| `--range` | string | required | 目标范围(A1 格式,必须带 sheet 前缀,如 `sheet1!A2:A100`) |
### `+csv-get`
@@ -108,12 +108,12 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 否 | A1 范围;省略时读整表的 `current_region` |
-| `--value-render-option` | string + Enum | 否 | 单元格取值模式 enum:`ToString` / `FormattedValue` / `Formula` / `UnformattedValue` |
-| `--max-rows` | int + Hidden | 否 | 防爆,默认 100000 |
-| `--max-chars` | int + Hidden | 否 | 防爆,默认 200000 |
-| `--include-row-prefix` | bool | 否 | 是否在每行前加 `[row=N]` 前缀,默认 `true` |
-| `--skip-hidden` | bool | 否 | 跳过隐藏行列,默认 `false` |
+| `--range` | string | optional | A1 范围;省略时读整表的 `current_region` |
+| `--value-render-option` | string | optional | 单元格取值模式(可选值:`formatted_value` / `raw_value` / `formula`) |
+| `--max-rows` | int | optional | 防爆,默认 100000 |
+| `--max-chars` | int | optional | 防爆,默认 200000 |
+| `--include-row-prefix` | bool | optional | 是否在每行前加 `[row=N]` 前缀,默认 `true` |
+| `--skip-hidden` | bool | optional | 跳过隐藏行列,默认 `false` |
## Examples
diff --git a/skills/lark-sheets/references/lark-sheets-search-replace.md b/skills/lark-sheets/references/lark-sheets-search-replace.md
index 7bc07bd2d..f0813bb9a 100644
--- a/skills/lark-sheets/references/lark-sheets-search-replace.md
+++ b/skills/lark-sheets/references/lark-sheets-search-replace.md
@@ -37,13 +37,14 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--find` | string | 是 | 待查找文本(与 `--regex` 配合时按正则解释) |
-| `--range` | string | 否 | 查找范围(A1 格式);省略时整表 |
-| `--match-case` | bool | 否 | 大小写敏感 |
-| `--match-entire-cell` | bool | 否 | 完全匹配整个单元格 |
-| `--regex` | bool | 否 | 把 `--find` 按正则解释 |
-| `--include-formulas` | bool | 否 | 也在公式文本中搜索 |
-| `--max-matches` | int + Hidden | 否 | 防爆,默认 5000 |
+| `--find` | string | required | 待查找文本(与 `--regex` 配合时按正则解释) |
+| `--range` | string | optional | 查找范围(A1 格式);省略时整表 |
+| `--match-case` | bool | optional | 大小写敏感 |
+| `--match-entire-cell` | bool | optional | 完全匹配整个单元格 |
+| `--regex` | bool | optional | 把 `--find` 按正则解释 |
+| `--include-formulas` | bool | optional | 也在公式文本中搜索 |
+| `--max-matches` | int | optional | 防爆,默认 5000 |
+| `--offset` | int | optional | 跳过前 N 个匹配(分页用),默认 0 |
### `+cells-replace`
@@ -51,13 +52,13 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--find` | string | 是 | 待替换文本 |
-| `--replacement` | string | 是 | 替换为;传空字符串 `""` 等价于「删除内容」 |
-| `--range` | string | 否 | 替换范围(A1 格式);省略时整表 |
-| `--match-case` | bool | 否 | 也在公式文本中替换 |
-| `--match-entire-cell` | bool | 否 | 也在公式文本中替换 |
-| `--regex` | bool | 否 | 也在公式文本中替换 |
-| `--include-formulas` | bool | 否 | 也在公式文本中替换 |
+| `--find` | string | required | 待替换文本 |
+| `--replacement` | string | required | 替换为;传空字符串 `""` 等价于「删除内容」 |
+| `--range` | string | optional | 替换范围(A1 格式);省略时整表 |
+| `--match-case` | bool | optional | 大小写敏感 |
+| `--match-entire-cell` | bool | optional | 完全匹配整个单元格 |
+| `--regex` | bool | optional | 把 `--find` 按正则解释 |
+| `--include-formulas` | bool | optional | 也在公式文本中替换 |
## Examples
diff --git a/skills/lark-sheets/references/lark-sheets-sheet-structure.md b/skills/lark-sheets/references/lark-sheets-sheet-structure.md
index b35440e46..2567e37d3 100644
--- a/skills/lark-sheets/references/lark-sheets-sheet-structure.md
+++ b/skills/lark-sheets/references/lark-sheets-sheet-structure.md
@@ -57,7 +57,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--include` | string_slice + Enum | 否 | `merges` / `row_heights` / `col_widths` / `hidden_rows` / `hidden_cols` / `groups` / `frozen`,逗号分隔 |
+| `--include` | string_slice | optional | 要返回的结构信息类别,逗号分隔多个(可选值:`merges` / `row_heights` / `col_widths` / `hidden_rows` / `hidden_cols` / `groups` / `frozen`) |
+| `--range` | string | optional | 限定只返回该 A1 范围的结构信息;省略时返回整表 |
### `+dim-insert`
@@ -65,10 +66,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 插入起始位置(0-based) |
-| `--end` | int | 是 | 插入结束位置(exclusive) |
-| `--inherit-style` | string + Enum | 否 | 新行/列样式继承策略 enum:`before`(继承前一行/列)/ `after`(继承后一行/列)/ `none`(默认) |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 插入起始位置(0-based) |
+| `--end` | int | required | 插入结束位置(exclusive) |
+| `--inherit-style` | string | optional | 新行/列样式继承策略 enum:`before`(继承前一行/列)/ `after`(继承后一行/列)/ `none`(默认)(可选值:`before` / `after` / `none`) |
### `+dim-delete`
@@ -76,9 +77,9 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 起始位置(0-based) |
-| `--end` | int | 是 | 结束位置(exclusive) |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 起始位置(0-based) |
+| `--end` | int | required | 结束位置(exclusive) |
### `+dim-hide`
@@ -86,9 +87,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 结束位置(0-based, inclusive) |
-| `--end` | int | 是 | 结束位置(0-based, inclusive) |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 起始位置(0-based, inclusive) |
+| `--end` | int | required | 结束位置(0-based, inclusive) |
### `+dim-unhide`
@@ -96,9 +97,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 结束位置(0-based, inclusive) |
-| `--end` | int | 是 | 结束位置(0-based, inclusive) |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 起始位置(0-based, inclusive) |
+| `--end` | int | required | 结束位置(0-based, inclusive) |
### `+dim-freeze`
@@ -106,8 +107,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--count` | int | 是 | 冻结前 N 行/列;传 0 解除冻结 |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--count` | int | required | 冻结前 N 行/列;传 0 解除冻结 |
### `+dim-group`
@@ -115,10 +116,11 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 结束位置(0-based, inclusive) |
-| `--end` | int | 是 | 结束位置(0-based, inclusive) |
-| `--depth` | int | 否 | 嵌套层级(`+dim-group` 用),默认 1 |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 起始位置(0-based, inclusive) |
+| `--end` | int | required | 结束位置(0-based, inclusive) |
+| `--depth` | int | optional | 嵌套层级(`+dim-group` 用),默认 1 |
+| `--group-state` | string | optional | 分组初始展开状态(可选值:`expand` / `fold`) |
### `+dim-ungroup`
@@ -126,10 +128,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 结束位置(0-based, inclusive) |
-| `--end` | int | 是 | 结束位置(0-based, inclusive) |
-| `--depth` | int | 否 | 嵌套层级(`+dim-group` 用),默认 1 |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 起始位置(0-based, inclusive) |
+| `--end` | int | required | 结束位置(0-based, inclusive) |
+| `--depth` | int | optional | 嵌套层级(`+dim-group` 用),默认 1 |
### `+dim-move`
@@ -137,10 +139,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--dimension` | string + Enum | 是 | `row` / `column` |
-| `--start` | int | 是 | 源起止区间的起始位置(0-based, inclusive) |
-| `--end` | int | 是 | 源起止区间的结束位置(0-based, inclusive) |
-| `--target` | int | 是 | 目标位置(move 到该 index 之前;0-based) |
+| `--dimension` | string | required | 维度方向(行或列)(可选值:`row` / `column`) |
+| `--start` | int | required | 源起止区间的起始位置(0-based, inclusive) |
+| `--end` | int | required | 源起止区间的结束位置(0-based, inclusive) |
+| `--target` | int | required | 目标位置(move 到该 index 之前;0-based) |
## Examples
diff --git a/skills/lark-sheets/references/lark-sheets-sparkline.md b/skills/lark-sheets/references/lark-sheets-sparkline.md
index a416715c4..0d12b0ffe 100644
--- a/skills/lark-sheets/references/lark-sheets-sparkline.md
+++ b/skills/lark-sheets/references/lark-sheets-sparkline.md
@@ -37,7 +37,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--group-id` | string | 否 | 按 group_id 过滤 |
+| `--group-id` | string | optional | 按 group_id 过滤 |
### `+sparkline-create`
@@ -45,7 +45,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | JSON:`{"type":"line\|column\|winLoss","data_range":"A2:F10","target_range":"G2:G10","style":{...},"special_points":{...}}`;type 三种 enum;data_range 与 target_range 行/列数需对齐 |
+| `--properties` | string + File + Stdin(复合 JSON) | required | JSON:`{config(共享样式配置), sparklines(迷你图数组)}`;完整字段结构跑 `--print-schema` |
### `+sparkline-update`
@@ -53,8 +53,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--group-id` | string | 是 | 目标组 id |
-| `--properties` | string + File + Stdin(复合 JSON) | 是 | 完整或足够完整的配置(先 `+sparkline-list --group-id ` 回读再 patch);可改 `type` / `data_range` / `target_range` / `style` / `special_points` 等字段 |
+| `--group-id` | string | required | 目标组 id |
+| `--properties` | string + File + Stdin(复合 JSON) | required | JSON:`{config, sparklines}`;先 `+sparkline-list --group-id ` 回读再 patch;完整字段结构跑 `--print-schema` |
### `+sparkline-delete`
@@ -62,7 +62,7 @@ _公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--group-id` | string | 是 | 目标组 id |
+| `--group-id` | string | required | 目标组 id |
## Schemas
diff --git a/skills/lark-sheets/references/lark-sheets-workbook.md b/skills/lark-sheets/references/lark-sheets-workbook.md
index 4f9f8928d..eda7e525e 100644
--- a/skills/lark-sheets/references/lark-sheets-workbook.md
+++ b/skills/lark-sheets/references/lark-sheets-workbook.md
@@ -50,9 +50,7 @@
_公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
-| Flag | Type | 必填 | 说明 |
-| --- | --- | --- | --- |
-| `--include-properties` | bool | 否 | 是否返回每个 sheet 的扩展属性(默认 true) |
+_仅含公共 / 系统 flag。_
### `+sheet-create`
@@ -60,10 +58,10 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--title` | string | 是 | 新工作表名称 |
-| `--index` | int | 否 | 插入位置;省略时附加到末尾 |
-| `--row-count` | int | 否 | 初始行数,默认 100 |
-| `--col-count` | int | 否 | 初始列数,默认 26 |
+| `--title` | string | required | 新工作表名称 |
+| `--index` | int | optional | 插入位置;省略时附加到末尾 |
+| `--row-count` | int | optional | 初始行数(默认 200,上限 50000) |
+| `--col-count` | int | optional | 初始列数(默认 20,上限 200) |
### `+sheet-delete`
@@ -77,7 +75,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--title` | string | 是 | 新名称 |
+| `--title` | string | required | 新名称 |
### `+sheet-move`
@@ -85,8 +83,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--index` | int | 是 | 目标位置(0-based) |
-| `--source-index` | int | 否 | 源位置(0-based);可选,未传时由 CLI runtime 根据 `--sheet-id` / `--sheet-name` 当前在工作簿中的 index 自动派生 |
+| `--index` | int | required | 目标位置(0-based) |
+| `--source-index` | int | optional | 源位置(0-based);可选,未传时由 CLI runtime 根据 `--sheet-id` / `--sheet-name` 当前在工作簿中的 index 自动派生 |
### `+sheet-copy`
@@ -94,8 +92,8 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--title` | string | 否 | 副本名称;省略时由服务端生成 |
-| `--index` | int | 否 | 副本插入位置(0-based);省略时附加到末尾 |
+| `--title` | string | optional | 副本名称;省略时由服务端生成 |
+| `--index` | int | optional | 副本插入位置(0-based);省略时附加到末尾 |
### `+sheet-hide`
@@ -115,7 +113,7 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--color` | string | 是 | Hex 色值如 `#FF0000`,传空 `""` 清除 |
+| `--color` | string | required | Hex 色值如 `#FF0000`,传空 `""` 清除 |
### `+workbook-create`
@@ -123,10 +121,10 @@ _系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--title` | string | 是 | 新 spreadsheet 标题 |
-| `--folder-token` | string | 否 | 目标文件夹 token;省略时放在云空间根目录 |
-| `--headers` | string + File + Stdin(简单 JSON) | 否 | 表头行 JSON 数组:`["列A","列B"]` |
-| `--values` | string + File + Stdin(简单 JSON) | 否 | 初始数据 JSON 二维数组:`[["alice",95]]` |
+| `--title` | string | required | 新 spreadsheet 标题 |
+| `--folder-token` | string | optional | 目标文件夹 token;省略时放在云空间根目录 |
+| `--headers` | string + File + Stdin(简单 JSON) | optional | 表头行 JSON 数组:`["列A","列B"]` |
+| `--values` | string + File + Stdin(简单 JSON) | optional | 初始数据 JSON 二维数组:`[["alice",95]]` |
### `+workbook-export`
@@ -134,9 +132,9 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--file-extension` | string + Enum | 否 | `xlsx` / `csv`,默认 `xlsx`;csv 模式必须配 `--sheet-id` |
-| `--sheet-id` | string | 否 | 仅 csv 模式必填:指定要导出的 sheet reference_id |
-| `--output-path` | string | 否 | 本地保存路径;省略时只触发导出不下载 |
+| `--file-extension` | string | optional | 导出文件格式;`csv` 模式必须配 `--sheet-id`(可选值:`xlsx` / `csv`) |
+| `--sheet-id` | string | optional | 仅 csv 模式必填:指定要导出的 sheet reference_id |
+| `--output-path` | string | optional | 本地保存路径;省略时只触发导出不下载 |
## Examples
diff --git a/skills/lark-sheets/references/lark-sheets-write-cells.md b/skills/lark-sheets/references/lark-sheets-write-cells.md
index 331fc4526..7b40657b8 100644
--- a/skills/lark-sheets/references/lark-sheets-write-cells.md
+++ b/skills/lark-sheets/references/lark-sheets-write-cells.md
@@ -184,10 +184,10 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 写入区域(A1 格式) |
-| `--cells` | string + File + Stdin(复合 JSON) | 是 | JSON:`{"values": [[...], ...]}`;可含 `formula` / `cell_styles` / `comments` / `embed_image` 富信息 |
-| `--allow-overwrite` | bool | 否 | 允许覆盖非空 cell;默认 false 时遇非空 cell 报错 |
-| `--max-cells` | int + Hidden | 否 | 防爆,默认 50000 |
+| `--range` | string | required | 写入区域(A1 格式) |
+| `--cells` | string + File + Stdin(复合 JSON) | required | JSON:2D 数组 `[[{cell},...],...]`,维度与 `--range` 完全一致;每个 cell 可含 `value` / `formula` / `cell_styles` / `note` / `rich_text`(含 `type="embed-image"` 单元格嵌图)等,完整字段跑 `--print-schema` |
+| `--allow-overwrite` | bool | optional | 允许覆盖非空 cell(默认 true);设为 false 时遇非空 cell 报错 |
+| `--max-cells` | int | optional | 防爆,默认 50000 |
### `+cells-set-style`
@@ -195,18 +195,18 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 目标范围(A1 格式,如 `A1:B2`) |
-| `--background-color` | string | 否 | 背景颜色(十六进制,如 `#ffffff`) |
-| `--font-color` | string | 否 | 字体颜色(十六进制,如 `#000000`) |
-| `--font-size` | number | 否 | 字体大小(px,例:10、12、14) |
-| `--font-style` | string + Enum | 否 | 字体样式 enum:`normal` / `italic` |
-| `--font-weight` | string + Enum | 否 | 字重 enum:`normal` / `bold` |
-| `--font-line` | string + Enum | 否 | 字体线条样式 enum:`none` / `underline` / `line-through` |
-| `--horizontal-alignment` | string + Enum | 否 | 水平对齐 enum:`left` / `center` / `right` |
-| `--vertical-alignment` | string + Enum | 否 | 垂直对齐 enum:`top` / `middle` / `bottom` |
-| `--word-wrap` | string + Enum | 否 | 换行策略 enum:`overflow` / `auto-wrap` / `word-clip`,默认 `overflow` |
-| `--number-format` | string | 否 | 数字格式(例:文本 `@`、数字 `0.00`、货币 `$#,##0.00`、日期 `mm/dd/yyyy`) |
-| `--border-styles` | string + File + Stdin(复合 JSON) | 否 | 边框配置 JSON:`{ top: {style,color,weight}, bottom: ..., left: ..., right: ... }`;4 方向结构相同 |
+| `--range` | string | required | 目标范围(A1 格式,如 `A1:B2`) |
+| `--background-color` | string | optional | 背景颜色(十六进制,如 `#ffffff`) |
+| `--font-color` | string | optional | 字体颜色(十六进制,如 `#000000`) |
+| `--font-size` | float64 | optional | 字体大小(px,例:10、12、14) |
+| `--font-style` | string | optional | 字体样式(可选值:`normal` / `italic`) |
+| `--font-weight` | string | optional | 字重(可选值:`normal` / `bold`) |
+| `--font-line` | string | optional | 字体线条样式(可选值:`none` / `underline` / `line-through`) |
+| `--horizontal-alignment` | string | optional | 水平对齐(可选值:`left` / `center` / `right`) |
+| `--vertical-alignment` | string | optional | 垂直对齐(可选值:`top` / `middle` / `bottom`) |
+| `--word-wrap` | string | optional | 换行策略(可选值:`overflow` / `auto-wrap` / `word-clip`) |
+| `--number-format` | string | optional | 数字格式(例:文本 `@`、数字 `0.00`、货币 `$#,##0.00`、日期 `mm/dd/yyyy`) |
+| `--border-styles` | string + File + Stdin(复合 JSON) | optional | 边框配置 JSON:`{ top: {style,color,weight}, bottom: ..., left: ..., right: ... }`;4 方向结构相同 |
### `+cells-set-image`
@@ -214,9 +214,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 目标单元格(A1 格式,必须单 cell,如 `A1`;起止 cell 须相同) |
-| `--image` | string | 是 | 本地图片路径(支持 PNG / JPEG / JPG / GIF / BMP / JFIF / EXIF / TIFF / BPG / HEIC) |
-| `--name` | string | 否 | 图片文件名(含扩展名);省略时取 `--image` 的 basename |
+| `--range` | string | required | 目标单元格(A1 格式,必须单 cell,如 `A1`;起止 cell 须相同) |
+| `--image` | string | required | 本地图片路径(支持 PNG / JPEG / JPG / GIF / BMP / JFIF / EXIF / TIFF / BPG / HEIC) |
+| `--name` | string | optional | 图片文件名(含扩展名);省略时取 `--image` 的 basename |
### `+dropdown-set`
@@ -224,11 +224,11 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 目标范围(A1 格式,如 `A2:A100`) |
-| `--options` | string + File + Stdin(复合 JSON) | 是 | 选项 JSON 数组 `["opt1","opt2"]`;最多 500 项,每项 ≤100 字符,不含逗号 |
-| `--colors` | string + File + Stdin(简单 JSON) | 否 | RGB hex 颜色数组(如 `["#1FB6C1","#F006C2"]`),长度必须与 `--options` 一致 |
-| `--multiple` | bool | 否 | 启用多选;默认 `false` |
-| `--highlight` | bool | 否 | 选项配色显示;默认 `false` |
+| `--range` | string | required | 目标范围(A1 格式,如 `A2:A100`) |
+| `--options` | string + File + Stdin(复合 JSON) | required | 选项 JSON 数组 `["opt1","opt2"]`;最多 500 项,每项 ≤100 字符,不含逗号 |
+| `--colors` | string + File + Stdin(简单 JSON) | optional | RGB hex 颜色数组(如 `["#1FB6C1","#F006C2"]`),长度必须与 `--options` 一致 |
+| `--multiple` | bool | optional | 启用多选;默认 `false` |
+| `--highlight` | bool | optional | 选项配色显示;默认 `false` |
### `+csv-put`
@@ -236,9 +236,9 @@ _公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
-| `--range` | string | 是 | 目标区域起点 A1(如 `Sheet1!A1`);终点按 CSV 实际行列数自动推断 |
-| `--csv` | string + File + Stdin(非 JSON 文本) | 是 | RFC 4180 CSV 文本;只写纯值,不带公式/样式/批注 |
-| `--allow-overwrite` | bool | 否 | 允许覆盖;默认 false 时若目标非空报错 |
+| `--start-cell` | string | required | 目标区域起点 A1(如 `Sheet1!A1`);终点按 CSV 实际行列数自动推断 |
+| `--csv` | string + File + Stdin(非 JSON 文本) | required | RFC 4180 CSV 文本;只写纯值,不带公式/样式/批注 |
+| `--allow-overwrite` | bool | optional | 允许覆盖(默认 true);设为 false 时若目标非空报错 |
## Schemas
@@ -269,16 +269,10 @@ _单元格边框配置,含 top/bottom/left/right 四个方向,每个方向
### `+dropdown-set` `--options`
-_数据验证配置_
+_列表选项(type='list' 时必填)_
-**顶层字段**:
-- `help_text` (string?) — 验证失败时显示的提示文本
-- `items` (array?) — 列表选项(type='list' 时必填)
-- `operator` (enum?) — 比较运算符(type='number'/'date'/'textLength' 时必填) [equal / notEqual / greaterThan / greaterThanOrEqual / lessThan / lessThanOrEqual / between / notBetween]
-- `range` (string?) — 源数据区域(type='listFromRange' 时必填,格式:'SheetName!A1:A10')
-- `support_multiple_values` (boolean?) — 列表验证是否支持多选(type='list'/'listFromRange' 时可选,默认 false)
-- `type` (enum) — 数据验证类型:list(下拉列表)、listFromRange(引用范围下拉列表)、number(数字)、date(日期)、textLength(文本长度)、… [list / listFromRange / number / date / textLength / checkbox]
-- `values` (array?) — 比较值(operator 为 'between'/'notBetween' 时需要两个值,其它运算符需要一个值)
+**数组项**(类型 string):
+- 标量:string
## Examples