mirror of
https://github.com/larksuite/cli.git
synced 2026-07-08 02:00:19 +08:00
f02debbfbd8b153849e286bd43f2175ba06bbaff
20 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
27a2f2758b |
fix(config): make agent-binding hints workspace-aware and surface user-identity risks (#728)
AI agents running inside OpenClaw / Hermes were routinely creating a parallel
app via `config init --new` instead of binding to the agent's existing app,
because every "not configured" hint and several deny errors hard-coded
`config init` regardless of workspace. Once bound, the same agents could
silently grant themselves user identity (impersonation) without the user
ever seeing a risk message in chat.
Changes:
- Introduce `core.NotConfiguredError` / `NoActiveProfileError` /
`reconfigureHint` helpers that branch on `CurrentWorkspace()`. In agent
workspaces they point at `lark-cli config bind --help` (a help page, not
a ready-to-run command) so AI must read the binding workflow and confirm
identity preset with the user before acting. In local terminals they
preserve the previous `config init --new` guidance.
- Migrate every `config init` hint that should be workspace-aware:
RequireConfigForProfile, default credential provider, credential provider
fallback, secret-resolve mismatch, config show, strict-mode entry-point
errors, default-as, profile use/rename/remove, auth list, doctor's
config_file check (which now also wraps the OS-level "no such file"
noise into the user-shaped "not configured" message).
- Refuse `config init` when run inside an OpenClaw / Hermes workspace by
default; add `--force-init` for the rare case the user genuinely wants
a parallel app. Without this guard, hint fixes were undone the moment
AI ignored them.
- Rewrite the strict-mode deny errors in cmd/auth/login.go, cmd/prune.go,
and internal/cmdutil/factory.go. The previous "AI agents are strictly
prohibited from modifying this setting" terminated AI reasoning while
providing no real gate. New errors point at `config strict-mode --help`
with the legitimate confirmation flow and explicitly note that switching
does NOT require re-bind. Integration test envelopes updated.
- Tighten `config bind --help` and `config strict-mode --help` to encode
the user-confirmation discipline directly: identity preset semantics
(bot-only vs user-default), "DO NOT switch without explicit user
confirmation", and a cross-reference clarifying that `config bind` is
for changing the underlying app while `config strict-mode` is the
policy-only switch (resolves an ambiguity an audit run found).
- Surface user-identity (impersonation) risk at every config write that
newly grants it, by reusing the canonical IdentityEscalationMessage
string from bind_messages.go:
- `noticeUserDefaultRisk` fires on flag-mode bind landing on
user-default, including the first-time case `warnIdentityEscalation`
misses (it requires a previous bot lock).
- `setStrictMode` warns when transitioning bot → user or bot → off
(newly permits user identity); stays quiet on narrowing changes
and on off → user (off already permitted user).
- Add tests: notconfigured_test.go (workspace branches),
init_guard_test.go (refuse + --force-init bypass), bind_warning_test.go
(user-default warning fires; bot-only does not), strict_mode_warning_test.go
(5 transitions covering both warn and no-warn paths).
Two follow-ups intentionally deferred: the keychain master-key hint at
internal/keychain/keychain.go:42 still suggests `config init` because the
keychain package can't import core (would be circular); fixing requires
either parameterizing the hint via callback or extracting workspace into
its own package. The lark-shared skill doc still tells AI to run
`config init` for first-time setup; updating the skill is in scope for
a follow-up PR.
Change-Id: I02273e044d9e061d211ceaa4f3ed5a3fb28325b3
|
||
|
|
c100ca049e |
feat(cmdutil): support @file for params and data (#724)
* feat(cmdutil): support @file for --params/--data (issue #705) Inline JSON values for --params/--data are mangled by Windows PowerShell 5's CommandLineToArgvW. Stdin (-) was the only escape hatch but supports just one flag at a time. Extend ResolveInput to accept @<path> (read JSON from a file) and @@... (escape for a literal @-prefixed value), mirroring the shortcuts framework's resolveInputFlags semantics. With this, both --params and --data can be sourced from files in the same call, sidestepping shell quoting on every platform. - internal/cmdutil/resolve.go: add @path / @@ handling, trim file content like stdin does, error on empty path or empty file - internal/cmdutil/resolve_test.go: cover file read, whitespace trim, missing file, empty path, empty content, @@ escape, plus ParseJSONMap / ParseOptionalBody integration through @file - cmd/api/api.go, cmd/service/service.go: update --params/--data help text to mention @file Change-Id: I366aa0f5783fbec6f05403f7f542505098a98c82 * refactor(cmdutil): route @file through fileio.FileIO abstraction The first cut of @file support called os.ReadFile directly inside ResolveInput, bypassing the codebase's fileio.FileIO abstraction (SafeInputPath validation, pluggable provider). That diverged from how every other file-reading path works: BuildFormdata for --file uploads and the shortcuts framework's resolveInputFlags both go through fileio.FileIO.Open with explicit fileio.ErrPathValidation handling. Re-route @file through the same path: - ResolveInput, ParseJSONMap, ParseOptionalBody now take a fileio.FileIO; @path uses fileIO.Open which goes through SafeInputPath (control-char rejection, abs-path rejection, symlink-escape check) — same security posture as --file - cmd/api and cmd/service callsites pass Factory.ResolveFileIO(ctx); the upload path now reuses the resolved fileIO instead of resolving twice - Path-validation errors surface as `--params: invalid file path "...": ...` distinct from `--params: cannot read file "...": ...` for genuine I/O errors - Nil fileIO with an @path returns a clear "file input (@path) is not available" error - Tests use localfileio.LocalFileIO with TestChdir(t, dir), matching the existing fileupload_test.go pattern; absolute-path rejection and nil-fileIO are covered This makes the feature behave identically under any FileIO provider (including server mode) instead of being silently bound to the local filesystem. Change-Id: I878c4e8fb03f43f1f19afad75ec3af9cdab7a7f9 * refactor(cmdutil): share at-file input handling Change-Id: I92a6eb6ea8fd02054bf8f4925cd81807449d5e51 |
||
|
|
9ba0d15161 |
Feat/risk tiering (#633)
* feat(risk): implement confirmation for high-risk write operations * feat(risk): streamline confirmation for high-risk write operations * feat(risk): document approval protocol for high-risk write operations * feat(risk): refine confirmation protocol for high-risk write operations * feat(risk): remove redundant variable declaration in risk test * feat(risk): add 'Yes' flag to various test cases for confirmation |
||
|
|
c09b03f854 |
fix(cmdutil): default flag completions to disabled (#688)
The previous default (atomic.Bool zero-value = enabled) meant any *cobra.Command built without first calling configureFlagCompletions leaked into cobra's package-global flagCompletionFunctions map. Bench runs (scripts/bench_build) showed hundreds of KB and thousands of objects retained per Build call. Flip the semantics so the zero-value matches the safe default: - Rename internal var to flagCompletionsEnabled (zero = disabled). - Rename public API to SetFlagCompletionsEnabled / FlagCompletionsEnabled. - Update call sites in cmd/root.go and scripts/bench_build/main.go. - Add cmd.TestBuild_DefaultNoCompletionLeak: asserts that, with no setter call at all, repeated cmd.Build invocations stay under 50 KB and 500 objects per build (observed: ~0.7 KB, 3 objs/build). This closes the gap that let the wrong default ship — every previous test explicitly Set the switch before exercising it. Change-Id: Ifefb04af5fd45eea9676a344a64ad071b6a4cd1a |
||
|
|
fe9dc4ce6a |
fix(strict-mode): reject explicit --as instead of silently overriding it (#673)
* fix(strict-mode): reject explicit --as instead of silently overriding it ResolveAs checked strict mode before the --as flag, so `--as bot` under strict=user was silently rewritten to user. Reorder so explicit --as is returned as-is and CheckStrictMode rejects the conflict (exit=2). Implicit paths (--as auto / unset) are still forced by strict mode. * fix(strict-mode): fix CI |
||
|
|
7d0ceb5d58 |
feat: block auth/config when external credential provider is active (#627)
* feat(credential): add ActiveExtensionProviderName to detect external providers Change-Id: Ie17a4b714e5eca17ae574ac188d570721790107d * feat(cmdutil): add RequireBuiltinCredentialProvider guard for external credential providers Change-Id: I8f2ea0af6fe6506b29beb69264b04c21c0f75da1 * feat(config): block all config subcommands when external credential provider is active Change-Id: If215cb8f0a53cc92d623dd3d842e4465124af2be * feat(auth): block all auth subcommands when external credential provider is active Change-Id: Ia61184fb2daeb6a7a38d122c647b7cb67eaf8b1f * fix(auth,config): silence usage in PersistentPreRunE to match root command behaviour Change-Id: I6d4b3c7d9d9c7b10fc2482fdc80252bf051771ee * test(auth,config,credential): address CodeRabbit review comments - Use cmd.Find() to assert SilenceUsage on matched subcommand (not parent) - Add TestRequireBuiltinCredentialProvider_PropagatesProviderError for error path - Add 'external' fallback sentinel in ActiveExtensionProviderName Change-Id: Iba35779ad2ed9807556264ba23db7096541e2bf3 |
||
|
|
ce80b3bc46 |
feat(config): add 'config bind' for per-Agent credential isolation (#515)
Give each AI Agent (OpenClaw, Hermes) its own lark-cli workspace so
its Feishu calls don't overwrite the developer's local config or
collide with other Agents.
lark-cli config bind [--source openclaw|hermes] [--app-id <id>]
[--identity bot-only|user-default] [--force]
Key capabilities:
- Source auto-detected from OPENCLAW_* / HERMES_* env signals; config
written to ~/.lark-cli/<agent>/, isolated per Agent.
- Two identity presets: 'bot-only' (flag-mode default) and
'user-default'. Flag mode rejects silent bot→user escalation
without --force; TUI prompts are exempt.
- Agent-friendly stdout JSON with 'identity' + 'message' for
next-step branching.
- 'config show' and 'doctor' expose the bound 'workspace'.
- OpenClaw SecretRef resolution: plain / ${VAR} / file:+JSON Pointer
/ exec:.
|
||
|
|
600fa50517 |
feat: add configurable content-safety scanning (#606)
* feat(contentsafety): add extension interface layer with Provider, Alert, and registry Change-Id: Ibeac6366c7201293057bc3b063f75ac34565bcd5 * feat(contentsafety): add normalize utility for JSON type conversion Change-Id: I7d4729a5ddcab2553abc110f8f6ecc88435ae921 * feat(contentsafety): add tree walker and regex scanner Change-Id: I215dad7cf3072711d05e45f7d384162e1f8752d4 * feat(contentsafety): add config loading with lazy creation, default rules, and allowlist matching Change-Id: I75e10df28f1f8d4f433cb2b469a0ff317af3bf70 * feat(contentsafety): add regex provider with config-driven scanning and allowlist Change-Id: I658889b3647cbbbde6881e0c5f7c13887a1eb1d4 * feat(contentsafety): add output core with mode parsing, path normalization, and scan orchestration Change-Id: I1cb9df75f1a4d176d660e2e7a9561314c3787191 * feat(contentsafety): add ScanForSafety entry point and Envelope alert field Change-Id: I5fdb311e1c8d983a35a58667970b9fd3ac729a5c * feat(contentsafety): integrate scanning into shortcut Out() and OutFormat() Change-Id: I33eef1dba14c8a9bd1998857311bdd611f33b916 * feat(contentsafety): integrate scanning into API/service output paths and register provider Change-Id: Ic3981db6c546a19eadea095d82175f92f4783bec * fix(contentsafety): emit stderr notice when lazy-creating default config Change-Id: Ia2491f7a17caceea3125ff9fb58d750dc196d7e7 * style: gofmt factory_default and exitcode Change-Id: I86c5afdfbbdb68d8137f0ca09ef3b5a1139f4b4e * fix(contentsafety): vfs for config I/O, mutex for lazy-create, sort matched rules, emit warn on --output path Change-Id: Ib4982cd54e1bfe0580a0eb03368e6ca818304e1b * fix(contentsafety): isolate scan goroutine errOut to prevent race on timeout Change-Id: Ia5a770d7387ba6d3b7fa318fc5f1384214ea10b7 * fix(contentsafety): deep-normalize typed slices so scanner can walk shortcut data Change-Id: I641e89113d1a2f2285ac6109bd3d7264f5845ea7 * fix(contentsafety): file perms 0600/0700, no result mutation, timeout test, scanTimeout comment Change-Id: Ie45a2e365ee7098e214e94f8871026cc12029d83 |
||
|
|
18e227f281 |
feat(cmdutil): add X-Cli-Build header for CLI build classification (#596)
* feat(cmdutil): add X-Cli-Build header for CLI build classification Adds X-Cli-Build (official / extended / unknown) so the gateway can distinguish official CLI from ISV-repackaged builds. * test(cmdutil): lift coverage on build-kind classification Extract classifyBuild as a pure helper so every branch (unknown / extended main-path / extended credential / extended transport / extended fileio / official) is reachable without mutating process-wide provider registries. Also cover: isBuiltinProvider non-pointer values, BuildHeaderTransport nil-Base fallback path, and fix the Name-spoof test so the test double returns a value that actually mimics an ISV provider. Coverage on PR-changed functions: - classifyBuild: 100% (new) - computeBuildKind: 61.5% -> 93.3% - BuildHeaderTransport.RoundTrip: 80% -> 100% |
||
|
|
11191df703 |
fix: skip flag-completion registration outside completion path (#598)
* fix: skip flag-completion registration outside completion path Cobra keeps completion callbacks in a package-global map keyed by *pflag.Flag with no removal path, so registrations made during Build() outlive the command itself. Route all seven call sites through cmdutil.RegisterFlagCompletion and enable registration only when the invocation actually serves a __complete request. Measured over 30 dropped Builds: ~202 KB / 2180 retained objects per Build before, ~0 after. Change-Id: I734d598a4c91a92c33b02e0f292f640cc0e224c6 |
||
|
|
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 |