Skip to content

feat: profile selection from environment with source-aware errors - #2198

Merged
liangshuo-1 merged 5 commits into
mainfrom
feat/profile-provenance
Aug 5, 2026
Merged

feat: profile selection from environment with source-aware errors#2198
liangshuo-1 merged 5 commits into
mainfrom
feat/profile-provenance

Conversation

@liangshuo-1

@liangshuo-1 liangshuo-1 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

What

Profile selection can now come from the environment (LARKSUITE_CLI_PROFILE), and every place that resolves a profile now knows which channel selected it — flag, environment, or the persisted default — so failures name the actual selector instead of guessing.

Four commits, one functional unit:

  1. feat: support profile selection from environment — resolve the env var at the process boundary (single os.Getenv consumption point in bootstrap), with precedence --profile flag > non-empty env > persisted currentApp. Restricted builds reject an environment-origin profile through the same distribution gate that already rejects the flag, before hooks or lifecycle events can observe the invocation.
  2. refactor: carry profile selection source in the invocation contextInvocationContext carries ProfileSource alongside Profile; no behavior change on its own.
  3. fix: name the profile selector in resolution failures — when the selected profile doesn't resolve, errors state which selector chose it and list the available profiles, instead of the previous generic (and sometimes misleading) messages.
  4. feat: surface the effective profile beside the persisted default — status output distinguishes "what is persisted" from "what is in effect for this invocation".

Contract changes (intentional, reviewer-relevant)

  • auth list / auth logout with a dangling persisted selector (currentApp pointing at a profile that no longer exists): previously returned success-shaped output ("ok": true, empty users) at exit 0; now fail with a named config error at exit 3. The old behavior actively masked a broken default.
  • config show adds a profileSource field; profile list adds effective / effectiveSource fields. Purely additive — with no env var and no flag, config show output differs from main by exactly the one added field, and auth list / doctor are byte-identical.
  • Profile-resolution errors may carry a field key naming the selector (existing envelope key, newly populated here).
  • Errors and hints now name the real selector value (fixes cases on main where the broken value was shown as an empty string, or where the hint suggested config init --new while valid profiles existed).

Verification

  • Full test suite, go vet, and -race -count=1 across cmd/internal/shortcuts/extension green; golangci-lint run --new-from-rev=origin/main clean.
  • Dry-run e2e suites pass against a binary built from this branch.
  • A/B against a baseline main binary: 824 help paths, full schema output (42k lines), and shell completions byte-identical; 62 populated-config scenarios across config/profile/auth/doctor/whoami and 36 error paths audited — every difference traces to the contract changes listed above, none outside them.
  • Environment variable is intentionally undocumented in user-facing help; verified it leaks into no help/schema/completion text.

Summary by CodeRabbit

  • New Features
    • Profile selection now follows clear precedence: command-line flag, environment variable, then saved configuration.
    • Profile listings identify the effective profile and its selection source.
    • Added warnings when environment-selected profiles override saved or requested profiles.
  • Bug Fixes
    • Invalid or missing profiles now produce specific errors and recovery guidance instead of misleading unauthenticated or unconfigured messages.
    • Commands requiring profiles now stop safely when profile selection is unsupported or unavailable.
    • Diagnostic checks warn when external providers ignore profile selectors.

A profile selector that matches no configured entry was answered by the
generic "no active profile" — and config default-as / strict-mode
steered agents toward `config init --new`, a destructive OAuth setup
flow, while intact profiles sat in config.json. The environment variable
form is the worst case: nothing in what the user just typed points at
LARKSUITE_CLI_PROFILE.

MultiAppConfig.RequireAppConfig now folds lookup + typed error into one
seam. The error names the requested profile, carries the selector as the
envelope field (--profile / LARKSUITE_CLI_PROFILE / currentApp), and
scopes the hint to the actual fix; config init remains only for a
genuinely empty config. auth list / auth logout stop disguising the
input error as not_logged_in (exit 0 -> exit 3), the credential chain
threads the selector source through ResolveConfigFromMulti, and doctor
warns when an external credential provider silently ignores the
selector.
profile list marked only the persisted default as active, profile use
compared only persisted state, and config show reported only the
resolved name — with a session-level LARKSUITE_CLI_PROFILE in play the
three commands gave contradictory answers to "which profile am I on",
and a successful profile use looked like it took effect while the
environment kept overriding every subsequent command.

Both dimensions are now visible wherever they can disagree, computed by
one definition (MultiAppConfig.EffectiveProfile): profile list adds
effective/effectiveSource beside the unchanged active field and warns on
a dangling selector instead of silently marking nothing, profile use
discloses on both its branches when the environment shadows the switch,
and config show adds profileSource (config | flag | environment).
@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 92e032ee-524e-4939-be6b-6a36e96fe5e6

📥 Commits

Reviewing files that changed from the base of the PR and between 42ea265 and 22c4e51.

📒 Files selected for processing (5)
  • cmd/doctor/doctor_test.go
  • cmd/presentation_test.go
  • cmd/profile/profile_test.go
  • cmd/profile_env_integration_test.go
  • internal/core/notconfigured_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • cmd/presentation_test.go
  • internal/core/notconfigured_test.go
  • cmd/profile_env_integration_test.go

📝 Walkthrough

Walkthrough

Profile selection now follows flag, environment, and configuration precedence. The selected source flows through invocation, configuration, credentials, and commands. Missing profiles return typed errors. Profile and doctor commands report environment overrides and ignored selectors.

Changes

Profile source resolution

Layer / File(s) Summary
Selection contracts and resolution
cmd/bootstrap.go, internal/core/types.go, internal/core/config.go, internal/core/notconfigured.go, internal/cmdutil/factory.go, internal/envvars/envvars.go, cmd/bootstrap_test.go, internal/core/*_test.go
Profile resolution records whether selection came from configuration, a flag, or LARKSUITE_CLI_PROFILE. RequireAppConfig returns source-specific typed errors for missing or dangling profiles.
Credential propagation and command enforcement
internal/cmdutil/factory_default.go, internal/credential/default_provider.go, cmd/auth/*.go, cmd/config/*.go, cmd/build.go, cmd/flag_gate.go, cmd/presentation_test.go, cmd/config/config_test.go, internal/credential/integration_test.go
Profile source metadata reaches credential resolution. Profile-dependent commands use RequireAppConfig. Unsupported environment profile selection is rejected before lifecycle hooks and command execution.
Profile command reporting
cmd/profile/list.go, cmd/profile/use.go, cmd/profile/profile_test.go, cmd/profile_env_integration_test.go
Profile listing reports effective selection and source. Profile listing and switching warn about unmatched or shadowed environment selectors while preserving persisted selections.
Doctor selector diagnostics
cmd/doctor/doctor.go, cmd/doctor/doctor_test.go
Doctor reports when external credentials ignore an explicit profile selector and identifies the selector source.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BootstrapInvocationContext
  participant Build
  participant MultiAppConfig
  participant DefaultAccountProvider
  BootstrapInvocationContext->>BootstrapInvocationContext: Apply flag, environment, or config precedence
  BootstrapInvocationContext->>Build: Pass InvocationContext with ProfileSource
  Build->>MultiAppConfig: RequireAppConfig(profile, ProfileSource)
  MultiAppConfig-->>DefaultAccountProvider: Resolve selected AppConfig
  DefaultAccountProvider-->>Build: Return account provider
  Build-->>BootstrapInvocationContext: Continue or return typed validation error
Loading

Possibly related PRs

  • larksuite/cli#1837: Both changes modify build-time gating and guard ordering in cmd/build.go and cmd/flag_gate.go.

Suggested reviewers: evandance

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: profile selection from environment with source-aware errors, matching the substantial refactoring across profile resolution, invocation context, and error reporting.
Description check ✅ Passed The PR description provides detailed summary, changes, test plan, and verification. However, the structured template sections (Summary/Changes/Test Plan/Related Issues) are not followed; content is organized as free-form narrative.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/profile-provenance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/doctor/doctor_test.go`:
- Around line 275-280: Update cmd/doctor/doctor_test.go at lines 275-280 and
316-321 to initialize both test factories with cmdutil.TestFactory(t, config)
instead of direct cmdutil.Factory literals. Override only the dependencies
needed for each credential-provider scenario, and preserve isolation of
LARKSUITE_CLI_CONFIG_DIR.

In `@cmd/doctor/doctor.go`:
- Around line 138-145: The profile-selector warning in cmd/doctor/doctor.go must
only run when Invocation.ProfileSource is ProfileFromFlag or
ProfileFromEnvironment; update the condition around the profile_selector check
while preserving the existing selector-specific messaging. In
cmd/doctor/doctor_test.go, add a regression case for a persisted
currentApp/profile source with external credentials and assert that no
profile_selector check is produced.

In `@cmd/presentation_test.go`:
- Around line 673-681: Replace string-only stderr checks in
cmd/presentation_test.go lines 673-681 by decoding the JSON error envelope and
asserting its category, subtype, and parameter fields directly. In
cmd/config/config_test.go lines 135-148, use errs.ProblemOf to verify the
expected category and subtype while preserving the existing ConfigError.Field
assertion for currentApp.

In `@cmd/profile_env_integration_test.go`:
- Around line 119-135: Strengthen the profile-resolution error test around the
error-producing resolver by decoding the returned error envelope and asserting
errs.CategoryValidation and errs.SubtypeInvalidArgument via errs.ProblemOf, then
use errors.As to verify the *errs.ValidationError Param value and preserve any
wrapped lower-layer cause. Keep the existing integration assertions for rendered
guidance, but rely on typed error assertions rather than serialized substrings
for the contract.

In `@cmd/profile/profile_test.go`:
- Around line 687-722: Add a new `profileListRun` coverage case alongside
`TestProfileListRun_MarksEffectiveOverride` that exercises
`cmdutil.InvocationContext.ProfileSource` set to `core.ProfileFromFlag` with the
target profile selected by flag. Assert the same persisted/default vs override
split as the environment case: the default entry remains `Active` but not
`Effective`, the target entry is `Effective`, and `EffectiveSource` is "flag".
Reuse the existing `setupProfileConfigDir`, `core.SaveMultiAppConfig`, and
`profileListRun` flow so the test directly covers the `ProfileFromFlag` mapping.

In `@internal/core/notconfigured_test.go`:
- Around line 249-272: Update the error assertions in the RequireAppConfig test
cases around the existing errors.As checks to call errs.ProblemOf(err) and
verify the expected category and SubtypeNotConfigured subtype, while also
asserting the expected param where applicable. Preserve the existing
*errs.ConfigError checks for Field, message, and recovery-hint behavior,
including the prohibition on suggesting config init.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7ff720a2-e570-4132-a73d-c91c68e36a2a

📥 Commits

Reviewing files that changed from the base of the PR and between 875d20a and 42ea265.

📒 Files selected for processing (27)
  • cmd/auth/list.go
  • cmd/auth/logout.go
  • cmd/bootstrap.go
  • cmd/bootstrap_test.go
  • cmd/build.go
  • cmd/config/config_test.go
  • cmd/config/default_as.go
  • cmd/config/show.go
  • cmd/config/strict_mode.go
  • cmd/doctor/doctor.go
  • cmd/doctor/doctor_test.go
  • cmd/flag_gate.go
  • cmd/presentation_test.go
  • cmd/profile/list.go
  • cmd/profile/profile_test.go
  • cmd/profile/use.go
  • cmd/profile_env_integration_test.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/core/config.go
  • internal/core/config_test.go
  • internal/core/notconfigured.go
  • internal/core/notconfigured_test.go
  • internal/core/types.go
  • internal/credential/default_provider.go
  • internal/credential/integration_test.go
  • internal/envvars/envvars.go

Comment thread cmd/doctor/doctor_test.go Outdated
Comment thread cmd/doctor/doctor.go
Comment on lines +138 to +145
if f.Invocation.Profile != "" && cfg.ProfileName == "" {
selector := "--profile"
if f.Invocation.ProfileSource == core.ProfileFromEnvironment {
selector = envvars.CliProfile
}
checks = append(checks, warn("profile_selector",
fmt.Sprintf("%s=%q is ignored: credentials are provided externally", selector, f.Invocation.Profile),
fmt.Sprintf("unset %s, or remove the external credential variables to select accounts by profile", selector)))

@coderabbitai coderabbitai Bot Aug 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Only warn for explicit selector sources.

Invocation.Profile also contains the persisted currentApp. With an external provider, this condition emits profile_selector and says --profile was ignored even when the user supplied no flag or environment selector.

Require ProfileFromFlag or ProfileFromEnvironment before adding this warning. Add a persisted-default regression case that asserts no profile_selector check.

  • cmd/doctor/doctor.go#L138-L145: gate the warning on ProfileFromFlag or ProfileFromEnvironment.
  • cmd/doctor/doctor_test.go#L257-L302: add coverage for a persisted profile source with external credentials.
📍 Affects 2 files
  • cmd/doctor/doctor.go#L138-L145 (this comment)
  • cmd/doctor/doctor_test.go#L257-L302
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/doctor/doctor.go` around lines 138 - 145, The profile-selector warning in
cmd/doctor/doctor.go must only run when Invocation.ProfileSource is
ProfileFromFlag or ProfileFromEnvironment; update the condition around the
profile_selector check while preserving the existing selector-specific
messaging. In cmd/doctor/doctor_test.go, add a regression case for a persisted
currentApp/profile source with external credentials and assert that no
profile_selector check is produced.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The premise doesn't hold: BootstrapInvocationContext only populates Invocation.Profile for an explicit selector — the persisted-default path returns Profile == "" with ProfileFromConfig (cmd/bootstrap.go), so this warning cannot fire without a flag or environment selector. Added TestDoctorRun_NoSelectorWarningForPersistedDefault in 22c4e51 to pin that contract against future bootstrap changes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline cmd/bootstrap.go --items all --type function --match 'BootstrapInvocationContext'
ast-grep outline cmd/doctor/doctor_test.go --items all --type function --match 'TestDoctorRun_NoSelectorWarningForPersistedDefault|TestDoctorRun_WarnsWhenExternalProviderIgnoresProfileSelector'

printf '\n--- Bootstrap implementation ---\n'
rg -n -A90 -B8 'func BootstrapInvocationContext\s*\(' cmd/bootstrap.go

printf '\n--- Persisted-default doctor regression test ---\n'
rg -n -A100 -B8 'func TestDoctorRun_NoSelectorWarningForPersistedDefault\s*\(' cmd/doctor/doctor_test.go

printf '\n--- Doctor warning condition ---\n'
rg -n -A22 -B7 'profile_selector' cmd/doctor/doctor.go

Length of output: 6247


@liangshuo-1, verification confirms your explanation.

BootstrapInvocationContext returns an empty Profile with ProfileFromConfig. The warning requires a non-empty Profile. Therefore, a persisted default cannot produce profile_selector.

TestDoctorRun_NoSelectorWarningForPersistedDefault correctly protects this contract.


🧠 Learnings used
Learnt from: JayYoung2021
Repo: larksuite/cli PR: 410
File: cmd/auth/login_scope_cache.go:47-54
Timestamp: 2026-04-11T23:06:23.250Z
Learning: In larksuite/cli Go code, use `validate.SafeInputPath` only for user-supplied file path inputs (e.g., `--file` flags). Do NOT require `validate.SafeInputPath` for internally constructed, application-managed filesystem paths when: (1) their root directory is already validated via `validate.SafeEnvDirPath()` inside helpers like `appdir.CacheDir()`, `appdir.StateDir()`, or `appdir.LogDir()`, and (2) the filename/path components are sanitized by helpers such as `sanitizeLoginScopeCacheKey()`. In code reviews, missing `SafeInputPath` calls should not be flagged for these app-managed paths if the above safeguards are already in place.

Learnt from: JayYoung2021
Repo: larksuite/cli PR: 410
File: internal/update/update.go:147-147
Timestamp: 2026-04-11T23:06:28.717Z
Learning: In this repo’s Go code (larksuite/cli), treat `validate.SafeInputPath` as a guard for **user-supplied local file paths only**. When you build a path by joining a previously validated base directory (e.g., from `appdir.StateDir()`, `appdir.CacheDir()`, `appdir.ConfigDir()` which already validate env overrides via `validate.SafeEnvDirPath()`) with a compile-time constant filename (e.g., `"update-state.json"`, `"config.json"`), do **not** require an additional `validate.SafeInputPath` call before using `vfs.*` or `validate.AtomicWrite`. Reviewers should avoid flagging/adding redundant `validate.SafeInputPath` in these computed-path cases; only require it when the path ultimately comes from user input.

Learnt from: ViperCai
Repo: larksuite/cli PR: 450
File: shortcuts/slides/slides_create.go:50-60
Timestamp: 2026-04-14T03:13:09.459Z
Learning: When reviewing this Go codebase, do not require explicit `validate.SafeInputPath` / `validate.SafeOutputPath` calls for user-supplied paths if the code uses the `runtime.FileIO()` abstraction methods (`Stat`, `Open`, `Save`, `ResolvePath`). `runtime.FileIO()` is backed by `LocalFileIO` (in `localfileio.go`), which enforces `SafeInputPath`/`SafeOutputPath` before any filesystem access and reports violations as `fileio.PathValidationError`. Only require explicit `validate.SafeInputPath` when bypassing `runtime.FileIO()` and calling `vfs.*` or `os.*` directly with user-influenced paths.

Learnt from: evandance
Repo: larksuite/cli PR: 984
File: internal/lintcheck/scan_test.go:0-0
Timestamp: 2026-05-20T08:44:00.596Z
Learning: In Go, the "declared and not used" compiler error is triggered only for variables that are never referenced after declaration. A statement like `x++` counts as a use, so a variable that is only incremented (e.g., `rejectCount++`) will still compile even if it is never read. When reviewing Go code, don’t assume `x++`-only variables would fail to compile—treat them as potentially semantically dead code instead (remove/avoid unless it’s required for later reads, logging, metrics, or other side effects).

Learnt from: evandance
Repo: larksuite/cli PR: 1135
File: cmd/config/default_as.go:44-50
Timestamp: 2026-05-27T11:31:47.366Z
Learning: In migrated command files (the ones covered by the `errs-typed-only` forbidigo rule in `.golangci.yml`) where `RunE` is expected to use typed errors, `RunE` must return typed `errs.NewXxxError(...)` values directly (return the error value), and must not use `output.Errorf(...)` or `output.ErrWithHint(...)`. The root dispatcher (`cmd/root.go` → `handleRootError`) will route `errs.*` typed errors through `output.WriteTypedErrorEnvelope` and `output.ExitCodeOf`, so direct `errs.*` returns are the correct post-migration stderr JSON contract shape. Only non-migrated/legacy paths should continue to use `output.Errorf` / `output.ErrWithHint`. In migrated command files, do not flag direct `errs.*` returns from `RunE` as stderr JSON contract violations.

Learnt from: evandance
Repo: larksuite/cli PR: 1135
File: cmd/config/keychain_downgrade_other.go:23-25
Timestamp: 2026-05-27T11:31:49.884Z
Learning: For larksuite/cli command files under cmd/**/*.go (starting with migrated commands / PR `#1135` onward), ensure `RunE` returns typed errors directly: return values created by `errs.NewXxxError(...)` (e.g., `errs.NewValidationError`, `errs.NewInternalError`, `errs.NewConfigError`, etc.). Do not return `output.ErrXxx` or `output.ErrWithHint` from `RunE`. The command-layer error dispatcher (`cmd/root.go`’s `handleRootError`) should route `errs.TypedError` / `errs.ProblemOf` through `output.WriteTypedErrorEnvelope` and `output.ExitCodeOf` to produce the typed stderr JSON envelope. Treat direct `errs.NewXxxError` returns in `RunE` as compliant with the new stderr contract (do not flag them); the older pre-migration rule requiring `output.Errorf` / `output.ErrWithHint` no longer applies. This is enforced by the `.golangci.yml` `errs-typed-only` forbidigo rule for migrated paths.

Learnt from: evandance
Repo: larksuite/cli PR: 1135
File: cmd/config/keychain_downgrade.go:57-60
Timestamp: 2026-05-27T11:31:54.717Z
Learning: In larksuite/cli, for migrated code paths, RunE handlers should return typed errors directly (e.g., errs.NewInternalError / errs.NewValidationError / errs.NewAuthenticationError) rather than using the old output.Errorf / output.ErrWithHint pattern. This is the intended post-migration behavior introduced in PR `#1135` (typed envelope contract for auth-domain errors): cmd/root.go’s handleRootError detects errs.* typed errors and dispatches them through output.WriteTypedErrorEnvelope to produce the canonical stderr JSON envelope. Do not flag typed errs.* returns as violations of the old guideline; that old output.Errorf/ErrWithHint guideline applies only to un-migrated paths. The .golangci.yml forbidigo rule errs-typed-only defines which paths are migrated and must use typed errors exclusively—follow that rule when reviewing RunE handlers.

Learnt from: evandance
Repo: larksuite/cli PR: 1449
File: cmd/profile/rename.go:70-71
Timestamp: 2026-06-13T11:20:19.566Z
Learning: In larksuite/cli Go code, when wrapping errors returned by `core.SaveMultiAppConfig` and other local config persistence/save operations, use `errs.NewInternalError(errs.SubtypeStorage, ...)` instead of `errs.SubtypeFileIO`. In this codebase, `errs.SubtypeStorage` is the canonical subtype for “config file save”/local persistence failures, while `errs.SubtypeFileIO` is reserved for general file I/O operations. Do not treat `errs.SubtypeStorage` as an incorrect subtype for config-save paths during code review.

Learnt from: evandance
Repo: larksuite/cli PR: 1449
File: cmd/profile/list.go:49-49
Timestamp: 2026-06-13T11:20:17.330Z
Learning: In the larksuite/cli codebase, when migrating error handling for calls to `core.LoadMultiAppConfig`, don’t add typed passthrough guards like `errs.ProblemOf` / `errs.IsTyped` just to preserve/forward typed errors—`core.LoadMultiAppConfig` only returns raw (untyped) errors, and there’s no typed `errs.*` error to pass through. Also, if the failure-path subtype classification (e.g., `SubtypeFailedPrecondition` vs `SubtypeFileIO`) is already inconsistent as a pre-existing issue elsewhere, don’t block a migration-only PR on that mismatch; keep the PR focused on the migration.

Learnt from: evandance
Repo: larksuite/cli PR: 1449
File: cmd/profile/use.go:70-71
Timestamp: 2026-06-13T11:20:25.527Z
Learning: In larksuite/cli, when an error subtype represents internal persistence of configuration/state (e.g., saving multi-app config via core.SaveMultiAppConfig or similar “config file save” operations), use errs.SubtypeStorage rather than errs.SubtypeFileIO. errs.SubtypeStorage is intended for local persistence failures (config file save is the canonical case). Reserve errs.SubtypeFileIO for user-facing file read/write operations (e.g., reading a user-supplied --file path). Therefore, do not flag errs.SubtypeStorage usage when it occurs on config/state save paths—this is intentional and correct.

Learnt from: wanghm25
Repo: larksuite/cli PR: 2122
File: skills/lark-base/references/lark-base-dashboard-block-get-data.md:66-66
Timestamp: 2026-07-30T13:20:18.339Z
Learning: When reviewing Go code related to lark “base shortcuts” dashboard URL resolution and the `+dashboard-block-get-data` command, do not infer/require a `dsh*` prefix for dashboard IDs from mocked test fixtures. A dashboard should be treated as a top-level `Base` block: `shortcuts/base/base_resolve.go` assigns the selected block ID directly to `dashboard_id` for dashboard URLs. Also ensure `+dashboard-block-get-data` accepts `--dashboard-id` only as a compatibility argument (not as the source of truth for fetching chart data), and that chart data is read using `base_token + block_id`. Documentation/examples should use `blk_xxx` placeholders for `--dashboard-id`.

You are interacting with an AI system.

Comment thread cmd/presentation_test.go Outdated
Comment thread cmd/profile_env_integration_test.go Outdated
Comment thread cmd/profile/profile_test.go
Comment thread internal/core/notconfigured_test.go
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@22c4e5170c916bc287f2e1285ce700ffa6a10cca

🧩 Skill update

npx skills add larksuite/cli#feat/profile-provenance -y -g

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.14570% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.02%. Comparing base (875d20a) to head (22c4e51).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/core/types.go 37.50% 10 Missing ⚠️
internal/core/config.go 20.00% 7 Missing and 1 partial ⚠️
cmd/config/strict_mode.go 25.00% 4 Missing and 2 partials ⚠️
cmd/config/default_as.go 0.00% 3 Missing ⚠️
cmd/auth/list.go 50.00% 1 Missing and 1 partial ⚠️
cmd/auth/logout.go 50.00% 1 Missing and 1 partial ⚠️
internal/core/notconfigured.go 94.28% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2198      +/-   ##
==========================================
+ Coverage   76.00%   76.02%   +0.02%     
==========================================
  Files         966      966              
  Lines      102541   102644     +103     
==========================================
+ Hits        77933    78036     +103     
+ Misses      18704    18702       -2     
- Partials     5904     5906       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Review follow-ups: build doctor test factories with cmdutil.TestFactory;
decode stderr envelopes and assert category/subtype/param instead of
matching serialized substrings; assert ProblemOf metadata at the profile
resolver; cover the flag-selected effective profile in profile list; pin
that a persisted default never triggers the external-provider selector
warning.
@liangshuo-1
liangshuo-1 merged commit 47c9741 into main Aug 5, 2026
64 of 76 checks passed
@liangshuo-1
liangshuo-1 deleted the feat/profile-provenance branch August 5, 2026 15:09
@liangshuo-1 liangshuo-1 mentioned this pull request Aug 5, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant