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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions internal/cmdutil/secheader.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
if v := AgentTraceValue(); v != "" {
h.Set(HeaderAgentTrace, v)
}
// PPE 路由 header(开发自测):仅当对应 env var 非空时注入,避免污染生产构建。
// 二者独立——通常配对使用:LARKSUITE_CLI_TT_ENV=<ppe-env> + LARKSUITE_CLI_USE_PPE=1。
if v := strings.TrimSpace(os.Getenv(envvars.CliTtEnv)); v != "" {
h.Set("x-tt-env", v)

Check warning on line 84 in internal/cmdutil/secheader.go

View check run for this annotation

Codecov / codecov/patch

internal/cmdutil/secheader.go#L84

Added line #L84 was not covered by tests
}
if v := strings.TrimSpace(os.Getenv(envvars.CliUsePpe)); v != "" {
h.Set("x-use-ppe", v)

Check warning on line 87 in internal/cmdutil/secheader.go

View check run for this annotation

Codecov / codecov/patch

internal/cmdutil/secheader.go#L87

Added line #L87 was not covered by tests
}
return h
}

Expand Down
6 changes: 6 additions & 0 deletions internal/envvars/envvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ const (

CliAgentTrace = "LARKSUITE_CLI_AGENT_TRACE"

// PPE / 灰度环境路由(开发自测用):若设置,会注入对应 HTTP header 把请求
// 稳定地打到指定 PPE/灰度集群。生产构建禁止设置;通过 env 而非硬编码,
// 是为了让 sync-global.sh 在打包前 export 一次就能稳定生效,commit 不污染线上。
CliTtEnv = "LARKSUITE_CLI_TT_ENV" // → x-tt-env header value
CliUsePpe = "LARKSUITE_CLI_USE_PPE" // → x-use-ppe header value (typically "1")

CliProxyEnable = "LARKSUITE_CLI_PROXY_ENABLE"
CliProxyAddress = "LARKSUITE_CLI_PROXY_ADDRESS"
CliCAPath = "LARKSUITE_CLI_CA_PATH"
Expand Down
128 changes: 123 additions & 5 deletions shortcuts/sheets/data/flag-defs.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,67 @@
{
"+formula-verify": {
"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_slice",
"required": "optional",
"desc": "Sheet reference_id(s); repeat or comma-separate to scan multiple sheets. Omit to scan all visible sheets."
},
{
"name": "sheet-name",
"kind": "public",
"type": "string_slice",
"required": "optional",
"desc": "Sheet name(s); repeat or comma-separate to scan multiple sheets. Omit to scan all visible sheets."
},
{
"name": "range",
"kind": "own",
"type": "string_slice",
"required": "optional",
"desc": "Optional A1 ranges (e.g. `A1:Z200`); repeat or comma-separate for multiple ranges. Omit to scan each sheet's current_region."
},
{
"name": "max-locations",
"kind": "own",
"type": "int",
"required": "optional",
"desc": "Max locations / samples per error type; default 20.",
"default": "20"
},
{
"name": "cell-limit",
"kind": "own",
"type": "int",
"required": "optional",
"desc": "Total cell scan cap (default 50000). When exceeded, `has_more=true` and caller should narrow `--range` to continue.",
"default": "50000"
},
{
"name": "exit-on-error",
"kind": "own",
"type": "bool",
"required": "optional",
"desc": "When status=errors_found, exit non-zero. Useful for CI / xlsx-style write-then-verify pipelines."
}
]
},
"+workbook-info": {
"risk": "read",
"flags": [
Expand Down Expand Up @@ -526,7 +589,7 @@
"kind": "own",
"type": "string",
"required": "optional",
"desc": "Typed table payload as JSON (same shape as `+table-put`): top-level `{\"sheets\":[...]}`, with each array item a sub-sheet `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[\"colA\",\"colB\",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}` — `name` and the outer `sheets` envelope are both required. Agents typically use `df_to_sheet(df, name)` from `scripts/sheets_df.py` to pack each DataFrame into one item, then wrap the list in `{\"sheets\":[...]}`. Mutually exclusive with --values. Creates the workbook, then writes typed type-faithful data (dates land as real dates, numbers keep precision).",
"desc": "Typed table payload as JSON (same shape as `+table-put`): a top-level `sheets` array, each item `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[\"colA\",\"colB\",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}`. Agents typically build it from a DataFrame via `{**json.loads(df.to_json(orient=\"split\")), \"dtypes\": df.dtypes.astype(str).to_dict()}`. Mutually exclusive with --values and --dataframe. Creates the workbook, then writes typed type-faithful data (dates land as real dates, numbers keep precision).",
"input": [
"file",
"stdin"
Expand All @@ -543,6 +606,13 @@
"stdin"
]
},
{
"name": "dataframe",
"kind": "own",
"type": "string",
"required": "optional",
"desc": "Single-sheet typed table from one Arrow IPC file (Feather v2 — what `pandas.DataFrame.to_feather()` writes), mutually exclusive with --values and --sheets. Pass `@<path>` for a file or `-` for binary stdin (same convention as other input flags). Arrow bytes are read raw — no TrimSpace / BOM strip — so the IPC magic survives intact (unlike text input flags). Column types come from the Arrow schema; per-column `number_format` may be set via Arrow field metadata. Creates the workbook and fills its default sheet (`Sheet1` — adopted in place, no empty Sheet1 left behind). For multi-sheet or non-default placement, use `--sheets` instead."
},
{
"name": "dry-run",
"kind": "system",
Expand Down Expand Up @@ -593,7 +663,7 @@
"kind": "own",
"type": "string",
"required": "optional",
"desc": "Local save path. When omitted, **only the export task is triggered + polled, the file is NOT downloaded** (returns file_token / status so a later step can resume the download). Pass a concrete path (e.g. `./out.xlsx`) or a directory (`.` keeps the server-provided filename) to download. Note: the equivalent `lark-cli drive +export --doc-type sheet` uses three separate flags (`--output-dir` / `--file-name` / `--overwrite`) and defaults to downloading into the current directory; this wrapper collapses them into a single `--output-path` for ergonomics but defaults to no-download — fall back to `drive +export` if the split flag set fits better."
"desc": "Local save path; export is triggered but not downloaded when omitted"
},
{
"name": "dry-run",
Expand Down Expand Up @@ -1380,6 +1450,13 @@
"required": "optional",
"desc": "Treat the first row as data instead of a header (columns get positional names col1, col2, ...)"
},
{
"name": "dataframe-out",
"kind": "own",
"type": "string",
"required": "optional",
"desc": "Write the typed table as one Arrow IPC file (Feather v2) instead of the default JSON. Pass `@<path>` for a file or `-` for binary stdout (same convention as other binary I/O flags). Mirror of the input-side `--dataframe` on `+table-put` / `+workbook-create` — pandas users round-trip via `df = pd.read_feather(\"x.arrow\")` or `pd.read_feather(io.BytesIO(stdout))`. Single-sheet only: requires `--sheet-id` or `--sheet-name`; whole-workbook reads keep the default JSON path. Column types come from the typed read-back (string/number/date/bool); per-column `number_format` is preserved as Arrow field metadata so the Arrow file can round-trip straight back through `+table-put --dataframe`."
},
{
"name": "dry-run",
"kind": "system",
Expand Down Expand Up @@ -2062,19 +2139,26 @@
"name": "sheets",
"kind": "own",
"type": "string",
"required": "required",
"desc": "Typed table payload (pandas-DataFrame-shaped) as JSON: top-level `{\"sheets\":[...]}`, with each array item a sub-sheet `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[\"colA\",\"colB\",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}` — `name` and the outer `sheets` envelope are both required. Agents typically use `df_to_sheet(df, name)` from `scripts/sheets_df.py` to pack each DataFrame into one item, then wrap the list in `{\"sheets\":[...]}`. `dtypes` values are pandas dtype strings (`int64`, `float64`, `Int64`, `bool`, `boolean`, `datetime64[ns]`, `object`, ...); the writer maps them to internal string/number/date/bool — omit `dtypes` and a column writes as text (good for raw CSV-shaped data). `formats[col]` is an Excel number_format string (e.g. `#,##0.00`, `0.0%`, `yyyy-mm`); when absent, date columns default to `yyyy-mm-dd` and string columns to text format (`@`).",
"required": "xor",
"desc": "Typed table payload (pandas-DataFrame-shaped) as JSON, XOR with `--dataframe`: a top-level `sheets` array, each item `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[\"colA\",\"colB\",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}`. Agents typically build it with `{**json.loads(df.to_json(orient=\"split\")), \"dtypes\": df.dtypes.astype(str).to_dict()}`. `dtypes` values are pandas dtype strings (`int64`, `float64`, `Int64`, `bool`, `boolean`, `datetime64[ns]`, `object`, ...); the writer maps them to internal string/number/date/bool — omit `dtypes` and a column writes as text (good for raw CSV-shaped data). `formats[col]` is an Excel number_format string (e.g. `#,##0.00`, `0.0%`, `yyyy-mm`); when absent, date columns default to `yyyy-mm-dd` and string columns to text format (`@`).",
"input": [
"file",
"stdin"
]
},
{
"name": "dataframe",
"kind": "own",
"type": "string",
"required": "xor",
"desc": "Single-sheet typed table from one Arrow IPC file (a.k.a. Feather v2 — what `pandas.DataFrame.to_feather()` writes), XOR with `--sheets`. Pass `@<path>` for a file or `-` for binary stdin (same convention as other input flags). Arrow bytes are read raw — no TrimSpace / BOM strip — so the IPC magic survives intact (unlike text input flags). Column types come from the Arrow schema (int*/uint*/float* → number, date32/date64/timestamp → date, utf8/large_utf8 → string, bool → bool); per-column `number_format` may be set via Arrow field metadata (`pa.field(\"price\", pa.float64(), metadata={b\"number_format\": b\"$#,##0.00\"})`). Writes the sheet at default placement: name `Sheet1` (created when absent), overwrite from A1 with header. For a different sheet name, anchor, mode, or to write multiple sheets, use `--sheets` instead."
},
{
"name": "styles",
"kind": "own",
"type": "string",
"required": "optional",
"desc": "Visual operations applied after the typed write, as JSON: top-level `{styles:[...]}`. Each item corresponds to one written sheet and must include `name`, plus at least one of `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges`. `cell_styles` entries use +cells-set-style fields with a cell range; row/col sizes use dimension ranges plus type/size; merges use cell ranges plus optional merge_type. The styles array length/order/name must match the written sheets in --sheets.sheets. Run `+table-put --print-schema --flag-name styles` for the full cell_styles field schema.",
"desc": "Visual operations applied after the typed write, as JSON: top-level `{styles:[...]}`. Each item corresponds to one written sheet and must include `name`, plus at least one of `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges`. `cell_styles` entries use +cells-set-style fields with a cell range; row/col sizes use dimension ranges plus type/size; merges use cell ranges plus optional merge_type. The styles array length/order/name must match the written sheets: with --sheets, match --sheets.sheets; with --dataframe (single sheet named Sheet1), pass exactly one styles item with name `Sheet1`. Run `+table-put --print-schema --flag-name styles` for the full cell_styles field schema.",
"input": [
"file",
"stdin"
Expand Down Expand Up @@ -4747,5 +4831,39 @@
"desc": ""
}
]
},
"+changeset-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": "start-revision",
"kind": "own",
"type": "int",
"required": "required",
"desc": "Start version (CS revision); the before baseline for review (must be >= 1)"
},
{
"name": "end-revision",
"kind": "own",
"type": "int",
"required": "optional",
"desc": "End version (CS revision); defaults to the latest revision. Gap (end-start+1) must be <= 20",
"default": "-1"
}
]
}
}
Loading
Loading