mirror of
https://github.com/larksuite/cli.git
synced 2026-08-03 08:32:46 +08:00
v1.0.16
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fbed6beac3 |
refactor: split Execute into Build + Execute with explicit IO and keychain injection (#371)
* refactor(cmd): split Execute into Build with IO/Keychain injection
Introduce a public cmd.Build entry point so external consumers (cli-server,
MCP server, other embedders) can assemble the full CLI command tree without
going through os.Args or the platform keychain. Build takes an
InvocationContext plus functional BuildOptions:
* WithIO(in, out, errOut) — inject custom streams; terminal detection
is derived from the input's underlying *os.File when present.
* WithKeychain(kc) — swap the credential store.
* HideProfile(bool) — registered later in cmd.HideProfile.
The existing Execute() keeps using the internal buildInternal (which
still returns the Factory so error handling can attribute exit codes),
and SetDefaultFS replaces the global VFS implementation at startup.
Hardening applied up front:
* cmdutil.NewIOStreams(in, out, errOut) centralizes terminal detection
so SystemIO() and WithIO share one path.
* cmdutil.NewDefault normalizes partial IOStreams — callers may pass
&IOStreams{Out: buf} without tripping nil-writer panics in the
RoundTripper warnings, Cobra, or the credential provider.
* Build guards against nil functional options.
* An API contract test (cmd/build_api_test.go) exercises Build +
WithIO + WithKeychain + HideProfile + SetDefaultFS so the public
surface is reachable by deadcode analysis.
Change-Id: I7c895e6019817401accbde2db3ef800da40ad319
* feat(schema): filter methods by strict mode in schema output
When strict mode is active, schema output now excludes methods that
are incompatible with the forced identity. This applies to both
pretty and JSON output formats at the resource and method levels.
Change-Id: I39647d5578466c3e23dc545bfb917ae075203ad7
* refactor: centralize strict-mode as flag registration
Change-Id: Iec11151c5002c2f58a8aa067d08747db2e4d2d8c
* fix(cmd): align strict-mode completion and build context; drop dead register shims
Thread a context.Context through RegisterShortcuts, RegisterServiceCommands,
and service.registerService/Resource/Method by introducing explicit
*WithContext variants. Pass that context into NewCmdServiceMethodWithContext
so shortcut and service command construction can honor cancellation and
strict-mode pruning consistently.
Also drop the context-less registerMethod and registerResource shims —
they became unreachable once the WithContext variants took over, and
were the source of new deadcode warnings. registerService is retained
because service_test.go still calls it directly.
Change-Id: I3fe5673aed663c7383bbbc5b0ae94d1f3491f22d
* refactor(cmd): hide --profile in single-app mode via build option
- GlobalOptions gains HideProfile; RegisterGlobalFlags stays pure and reads
the policy off the struct. No boolean-trap parameter, one call per site.
- buildConfig holds GlobalOptions inline so HideProfile(bool) BuildOption
mutates it directly. buildInternal stays a pure assembly function and
requires callers to supply WithIO — no implicit os.Std* fallback.
- Add WithIO BuildOption (wrapping raw io.Reader/Writer with automatic
*os.File TTY detection); Execute injects streams explicitly and decides
profile visibility via HideProfile(isSingleAppMode()).
- installTipsHelpFunc force-shows hidden root flags while rendering the
root command's own help, so single-app users still discover --profile
via lark-cli --help without it polluting subcommand helps.
Change-Id: I7755387e993992ca969e0a4a6f54441cc1993eef
* feat(transport): extension abort hook and shared base transport
Two transport-layer changes bundled because both reshape the base
round-tripper contract used by the HTTP client, the Lark SDK client,
and the in-process updater.
1. Extension abort hook (PreRoundTripE).
Extensions implementing exttransport.AbortableInterceptor can now
return an error from PreRoundTripE to skip the built-in chain. The
post hook still fires with (nil, reason) so extensions can unwind
resources. extensionMiddleware captures the provider name so the
returned *AbortError carries attribution.
2. Shared base transport to stop RPC leak.
util.NewBaseTransport cloned http.DefaultTransport on every call, so
each cmdutil.Factory produced a fresh *http.Transport whose
persistConn readLoop/writeLoop goroutines lingered until
IdleConnTimeout (~90s). Invisible in a single-process CLI, but the
fork is consumed by cli-server where each RPC request constructs a
new Factory, causing linear memory + goroutine growth under load.
Replace NewBaseTransport with SharedTransport — returns
http.DefaultTransport (the stdlib-wide singleton) by default, and
a cached proxy-disabled clone only when LARK_CLI_NO_PROXY is set.
Return type is http.RoundTripper to discourage in-place mutation of
the shared instance. FallbackTransport is kept as a thin
*http.Transport wrapper so existing callers in internal/auth and
internal/cmdutil transport decorators (which were already on the
singleton path) do not have to migrate.
Leak-site migrations: factory_default.go (HTTP + SDK base) and
update.go now call SharedTransport directly.
Change-Id: Ia82462134c5c5ee838be878b887860f41446a235
* fix: unblock Build() zero-opts path and sidecar demo build
Two regressions surfaced on refactor/build-execute-split:
1. cmd.Build(ctx, inv) without WithIO panicked at rootCmd.SetIn/Out/Err
because cfg.streams stayed nil — NewDefault normalized internally
but cmd/build.go never saw the normalized value. Default cfg.streams
to cmdutil.SystemIO() before the root command wires them, and add a
TestBuild_NoOptions regression guard.
2. sidecar/server-demo/main.go still called cmdutil.NewDefault(inv),
so `go build -tags authsidecar_demo ./sidecar/server-demo` failed
with "not enough arguments". Pass nil for the new streams parameter
to preserve the prior behavior (NewDefault substitutes SystemIO).
Change-Id: I20227b2355cde7d19e22eba3eb841c6d8611e8a7
|
||
|
|
abb02cd46c |
feat(sheets): add float image shortcuts (#494)
Implement +create-float-image, +update-float-image, +get-float-image, +list-float-images, and +delete-float-image shortcuts wrapping the v3 spreadsheet float_image API. The create reference doc includes the prerequisite media upload step with the correct parent_type (sheet_image) to avoid common token mismatch errors. |
||
|
|
344ff88701 |
feat: add --file flag for multipart/form-data file uploads (#395)
* feat(cmdutil): add shared file upload helpers Add ParseFileFlag, ValidateFileFlag, and BuildFormdata to support multipart file upload via --file flag across raw API and meta API commands. Change-Id: Ib724cf8b055b0b314af11d8d830f38559dac60eb * feat(api): add --file flag for multipart/form-data file uploads Add --file flag to `lark-cli api` command enabling file upload via multipart/form-data. The flag accepts [field=]path format and supports stdin (-). Includes mutual exclusion validation with --output, --page-all, and GET method. Dry-run mode shows file metadata instead of building actual formdata. Change-Id: Icf34aba5da3a558219a97a583e8f6aa951ded199 * feat(service): add --file flag with auto-detection from metadata Add file upload support to meta API service method commands. The --file flag is conditionally registered only for methods whose metadata declares file-type fields (POST/PUT/PATCH/DELETE). The default field name is auto-detected from metadata when exactly one file field exists. Change-Id: Ibbf04eb42341ba11bb1fd9750e63bc1d0eacd08d * feat(schema): show file upload indicators in method detail display Add hasFileFields helper to detect file-type fields in requestBody metadata. Modify printMethodDetail to display [file upload] tag on --data line, --file flag description with default field name, and --file <path> in CLI example for methods that accept file uploads. Change-Id: Iae3bc14fe07e16a8b5f6a50a2b3592d6d8490ed9 * fix: address code review findings for file upload feature - ParseFileFlag: change idx >= 0 to idx > 0 to prevent empty field name when input like "=photo.jpg" is passed - BuildFormdata: read file into bytes.Reader with defer Close to prevent file handle leak on later errors - BuildFormdata: remove unused ctx parameter from signature and callers - Eliminate duplicated dry-run logic by having buildAPIRequest and buildServiceRequest return FileUploadMeta when in dry-run mode, removing ~60 lines of copy-pasted URL building and validation code Change-Id: I27b9534fd0eaefce40390f6e723dd0c04a2cdf80 * fix: address PR review findings - Remove opts.File=="" guard on dual-stdin check so --file photo.jpg --params - --data - correctly reports an error instead of silently dropping --data content (P1 bug in both api.go and service.go) - Extract shared DetectFileFields into cmdutil, deduplicate detectFileFields (service.go) and hasFileFields (schema.go) - Show "<stdin>" instead of empty path in dry-run output for --file - Change-Id: Iccc5d879165ea6a3d04f0425ec6a5018a10e72e1 * fix: reject non-object --data with --file and improve multi-file schema - --data with --file now requires a JSON object; arrays/strings/numbers are rejected with a clear error instead of being silently dropped - Schema display for multi-file methods shows explicit field=path syntax and lists valid field names instead of advertising a false default Change-Id: I0facdb3ad86f68cb125c7ea109a33714fd91dba0 |
||
|
|
619ec8c2cb |
fix(api): support stdin and quoted JSON inputs on Windows (#367)
* fix(api): add stdin and single-quote support for --params/--data on Windows (#64) Windows PowerShell 5.x mangles JSON double-quotes when passing arguments to native executables, causing --params and --data to fail with "invalid JSON format". This commit adds two mitigations at the framework level: - stdin piping: `echo '{"k":"v"}' | lark-cli --params -` bypasses shell argument parsing entirely and works on all platforms/shells. - single-quote stripping: cmd.exe passes literal single quotes which are now transparently removed before JSON parsing. Implementation: - New `cmdutil.ResolveInput(raw, stdin)` handles `-` (stdin), strip surrounding `'...'`, and plain passthrough. - `ParseJSONMap` and `ParseOptionalBody` now accept an `io.Reader` and delegate to `ResolveInput` before JSON unmarshalling. - `cmd/api` and `cmd/service` pass `IOStreams.In` and guard against simultaneous stdin usage by --params and --data. - Empty stdin is rejected with a clear error message. Closes #64 Change-Id: If21e735d0aed5c6a2d6674c1e6c898186fca3aba * test: add stdin e2e regression coverage Change-Id: I4e00bf1c6b6f3259f503e3414cae10fa4b34ba75 |
||
|
|
f5a8fbf8f1 |
refactor: migrate common/client/im to FileIO and add localfileio tests (#322)
* refactor: migrate common/client/im to FileIO and add localfileio tests - runner resolveInputFlags: replace validate.SafeInputPath + vfs.ReadFile with FileIO.Open + io.ReadAll - SaveResponse: delegate to FileIO.Save + ResolvePath - cmd/api, cmd/service: pass FileIO to ResponseOptions - im: replace validate.SafeLocalFlagPath with RuntimeContext.ValidatePath, migrate download/upload to FileIO.Save/Open/Stat - Add path_test.go and atomicwrite_test.go for localfileio - Add validate_media_test.go for im media flag validation - Adapt test mocks to fileio.FileInfo interface |
||
|
|
900c12ce8d |
feat: add FileIO extension for file transfer abstraction (#314)
* feat: add FileIO extension for file transfer abstraction Introduce extension/fileio package with Provider/FileIO/File interfaces and a global registry, following the same pattern as extension/credential. - Add LocalFileIO default implementation with path validation and atomic writes - Wire FileIOProvider into Factory and resolve at runtime via RuntimeContext.FileIO() - Factory holds Provider (not resolved instance), deferring resolution to execution time |
||
|
|
bb38ecd41a |
feat: add transport extension with interceptor pre/post hooks (#292)
* feat: add transport extension with interceptor pre/post hooks Add extension/transport package following the same Provider pattern as credential and fileio extensions. The Interceptor interface uses a PreRoundTrip/post-closure design that guarantees built-in transport decorators (SecurityHeader, SecurityPolicy, Retry) cannot be skipped, overridden, or tampered with by extensions. The original request context is restored after PreRoundTrip to prevent context tampering. Change-Id: I2e51ff67a0e2d8d32944a0565c2a6781110f281f Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
8db4528269 |
feat: add strict mode identity filter, profile management and credential extension (#252)
* feat: add strict mode identity filter, profile management and credential extension Port changes from feat/strict-mode-identity-filter_3 branch: - Add strict mode for identity filtering and configuration - Add profile management commands (add/list/remove/rename/use) - Add credential extension framework (registry, env provider) - Add VFS abstraction layer - Refactor factory default and client options - Update shortcuts to use new credential and validation patterns Change-Id: I8c104c6b147e1901d94aefcefe35a174932c742b Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: go mod tidy Change-Id: I0f610ccea6bc874248e84c24770944a3071dcc57 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: fix test failures from credential provider migration - Remove unused TAT stub registrations in api and service tests (CredentialProvider manages tokens, SDK no longer calls TAT endpoint) - Update strict mode integration test: +chat-create now supports user identity, so it should succeed under strict mode user Change-Id: Iab51c2e12a97995e0b95dcd71df212d2d1f76570 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: migrate remaining os calls to internal/vfs Replace direct os.Stat/Open/MkdirAll/OpenFile/Remove/ReadDir/UserHomeDir with vfs equivalents in shortcuts/minutes, shortcuts/drive, and internal/keychain. Add ReadDir to the vfs interface and OsFs implementation. Change-Id: I8f97e5fb3e1731b4684d276644fcb10fae823067 * fix: resolve gofmt and goimports formatting issues Change-Id: If61578631f5698f7ca2d9a946ca59753651463fb * feat: add Flag.Input support for @file and stdin input sources Add framework-level support for reading flag values from files (@path) or stdin (-), solving the fundamental problem of passing complex text (markdown, multi-line content) via CLI arguments where shell escaping breaks content. Closes #239, fixes #163. - Add File/Stdin constants and Input field to Flag struct - Add resolveInputFlags() in runner pipeline (pre-Validate) - Support @@ escape for literal @ prefix - Guard against multiple stdin consumers - Auto-append "(supports @file, - for stdin)" to help text - Apply to: docs +create/+update --markdown, im +messages-send/+reply --text/--markdown/--content, task +comment --content, drive +add-comment --content Change-Id: I305a326d972417542aeadd70f37b74ea456461ef Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: fix pre-existing test failures in task, minutes, and registry - task/minutes: remove unused tenant_access_token httpmock stubs (TestFactory's testDefaultToken provides tokens directly, so the HTTP stub was never consumed and failed verification) - registry: fix hasEmbeddedData() to check for actual services instead of just byte length (meta_data_default.json has empty services array) Change-Id: Ic7b5fc7f9de09137a7254fe1ddf47d24ade40587 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: suppress nilerr lint for intentional nil returns Both cases intentionally return nil on error for graceful degradation: - profile list: show friendly message when config is not initialized - service: skip scope check when token resolution fails Change-Id: I7285c37277c9b0361a421ab00359244c2cd150b3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address CodeRabbit review feedback - runner.go: fail fast when Input is used on non-string flags - remote_test.go: rename hasEmbeddedData → hasEmbeddedServices - profile/list.go: add omitempty to optional JSON fields - service.go: surface context cancellation errors in scope check Change-Id: I7072d41f8c711b4b37c542e32dfd8150f42b13c0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: tighten credential resolution and profile flows Change-Id: I83f6d424540eab9b1708944b9b6e26e8477cc60d * refactor: centralize identity hint resolution Change-Id: I38d5f98160b92adb62dc929ae73697ae5b3d64f8 * fix: surface unverified extension identities Change-Id: Ia86d9bd19add9010176339ec4cc89deb033f5b4f * fix: honor runtime credential sources in config views Change-Id: I40b2ffedc5c1db5e08e86b9472ea2b84fa02bb29 * fix: prefer runtime values in config show commands Change-Id: I5663a53e147577f0f1f533f67d12bea504e6b839 * Revert "fix: prefer runtime values in config show commands" This reverts commit |
||
|
|
77460abc49 |
fix(security): replace http.DefaultTransport with proxy-aware base transport to mitigate MITM risk (#247)
All HTTP clients previously used http.DefaultTransport which silently respects HTTP_PROXY/HTTPS_PROXY env vars, allowing credentials to transit through untrusted proxies. This adds a proxy detection warning and an opt-out switch (LARK_CLI_NO_PROXY=1) so security-sensitive users can disable proxy entirely. - Redact proxy credentials in warning output (handles both scheme-prefixed and bare URL formats) - Suppress warning when LARK_CLI_NO_PROXY is already set - Use FallbackTransport singleton for nil-Base fallback paths to preserve connection pooling - Emit proxy warning on both HTTP client and Lark SDK client paths Change-Id: Ibed7d0470409c73fbd42bccac6673f9fc5e87a83 |
||
|
|
83dfb068ad |
feat: open-source lark-cli — the official CLI for Lark/Feishu
Change-Id: I113d9cdb5403cec347efe4595415e34a18b7decf |