Skip to content

test - #1620

Closed
maojinze7-prog wants to merge 0 commit into
mainfrom
feat/whoami-command
Closed

test#1620
maojinze7-prog wants to merge 0 commit into
mainfrom
feat/whoami-command

Conversation

@maojinze7-prog

@maojinze7-prog maojinze7-prog commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add a top-level lark-cli whoami command that shows the currently effective identity at a glance: the active profile, app, the effective identity (bot/user), and token status.

The underlying identity data already existed via internal/identitydiag, but it was only reachable through auth status — JSON-only, without the active profile, and not discoverable under a whoami name. This command aggregates profile + app + effective identity + token status into a single, human-readable view (with --json for structured output and --verify for an optional online check), following the near-universal whoami CLI convention (gh, aws sts, gcloud, kubectl).

Changes

  • Add top-level whoami command (cmd/whoami/):
    • Default human-readable one-screen summary; --json for structured output (mirrors the auth status payload plus a new profile field); --verify for optional online token verification.
    • Read-only, runs even when not logged in (reports identity: none); exits 0 whenever it successfully renders state (including none / not-configured), mirroring the whoami convention.
    • Never prints secrets — only appId, openId, userName, scope, expiry, and token status enums (the same field set as auth status).
  • Extract the effective-identity resolution into a shared identitydiag.EffectiveIdentity helper so whoami and auth status agree on which identity is in effect (no behavior change to auth status; existing regression tests cover it).
  • Register the command in the root command tree and add a one-line discoverability note to the lark-shared skill doc.

Test Plan

  • Unit tests (cmd/whoami, internal/identitydiag): JSON output, human-readable output, none and not-configured handling, --verify, no-secret-leakage, and profile-line rendering; plus an auth status backward-compatibility regression for the shared-helper extraction.
  • go build ./..., go vet, and gofmt all clean.
  • Manual:
    lark-cli whoami
    lark-cli whoami --json
    lark-cli whoami --verify
    lark-cli whoami --help
    

Related Issues

N/A

Summary by CodeRabbit

  • New Features
    • Added a new whoami command to display the current effective identity and related token/verification status.
    • Support --json for structured output and --verify to perform联网校验.
    • Included whoami in the root command set so it’s available from the main CLI.
    • Updated identity help guidance to quickly confirm the active profile/app and token state.
  • Bug Fixes
    • Improved effective identity selection to consistently prefer user when available, otherwise bot, otherwise none.
  • Tests
    • Added coverage for JSON/human output, unconfigured identity behavior, and verification reporting.

@coderabbitai

coderabbitai Bot commented Jun 26, 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

Run ID: a2fd0509-a262-4d2e-8b2a-4a1331cca3a7

📥 Commits

Reviewing files that changed from the base of the PR and between 516c6cb and bb6fdc8.

📒 Files selected for processing (2)
  • cmd/whoami/whoami.go
  • cmd/whoami/whoami_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/whoami/whoami.go
  • cmd/whoami/whoami_test.go

📝 Walkthrough

Walkthrough

Identity selection is centralized in internal/identitydiag, auth status now consumes it, and the CLI gains a new whoami command with JSON and human output modes, verification support, tests, and a skill doc entry.

Changes

Identity selection and whoami command

Layer / File(s) Summary
Shared identity helper
internal/identitydiag/diagnostics.go, internal/identitydiag/diagnostics_test.go, cmd/auth/status.go
identitydiag exports shared identity constants and EffectiveIdentity, tests that selection logic, and auth status uses the shared helper and constants.
whoami JSON and verification
cmd/build.go, cmd/whoami/whoami.go, cmd/whoami/whoami_test.go
The root command registers whoami, and the command loads diagnostics, computes verification fields, and emits JSON or not-configured output with tests for those paths.
whoami human output
cmd/whoami/whoami.go, cmd/whoami/whoami_test.go, skills/lark-shared/SKILL.md
Human output renders profile, identity, token, and hint lines, with tests for formatting, redaction, and bot output without verification; the skill doc adds a command tip.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

  • larksuite/cli#957: Shares the same identity-diagnostics area that auth status now uses through identitydiag.
  • larksuite/cli#961: Also updates internal/identitydiag and cmd/auth/status.go around shared identity/status helpers.

Suggested labels

domain/ccm

Suggested reviewers

  • MaxHuang22

Poem

A bunny typed whoami with a hop,
And saw user, bot, and none pop up.
With --json bright and --verify true,
My whiskers twitched at the identity view.
Hop hop — the CLI knows who I am too. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.00% 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 clearly matches the main change: adding a new top-level whoami command that shows the current identity.
Description check ✅ Passed The description includes the required Summary, Changes, Test Plan, and Related Issues sections with enough detail for this PR.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/whoami-command

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.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jun 26, 2026
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.33333% with 60 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.62%. Comparing base (39d60cb) to head (bb6fdc8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/whoami/whoami.go 55.22% 57 Missing and 3 partials ⚠️

❌ Your patch status has failed because the patch coverage (58.33%) is below the target coverage (60.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1620      +/-   ##
==========================================
- Coverage   74.64%   74.62%   -0.03%     
==========================================
  Files         806      807       +1     
  Lines       81386    81521     +135     
==========================================
+ Hits        60752    60831      +79     
- Misses      16101    16154      +53     
- Partials     4533     4536       +3     

☔ 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.

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/whoami-command -y -g

@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: 1

🧹 Nitpick comments (1)
cmd/whoami/whoami.go (1)

36-41: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Thread the command context instead of context.Background().

With --verify, whoamiRun calls identitydiag.Diagnose which performs network I/O. Using context.Background() means the root command's context (and therefore Ctrl+C/parent cancellation) never reaches the verification HTTP call. The RunE closure has access to cmd.Context(); consider passing it through to whoamiRun.

♻️ Proposed change
-		RunE: func(cmd *cobra.Command, args []string) error {
-			if runF != nil {
-				return runF(opts)
-			}
-			return whoamiRun(opts)
-		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if runF != nil {
+				return runF(opts)
+			}
+			return whoamiRun(cmd.Context(), opts)
+		},
-func whoamiRun(opts *WhoamiOptions) error {
+func whoamiRun(ctx context.Context, opts *WhoamiOptions) error {
 	f := opts.Factory
 	...
-	diagnostics := identitydiag.Diagnose(context.Background(), f, cfg, opts.Verify)
+	diagnostics := identitydiag.Diagnose(ctx, f, cfg, opts.Verify)

Also applies to: 69-69

🤖 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/whoami/whoami.go` around lines 36 - 41, The whoami command is dropping
the Cobra command context, so cancellation from Ctrl+C/parent commands does not
reach the verification network call. Update the RunE closure on the whoami
command to pass cmd.Context() through to whoamiRun, and adjust whoamiRun (and
any related helpers it calls, such as the verify/identitydiag.Diagnose path) to
accept and use that context instead of context.Background().
🤖 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/whoami/whoami.go`:
- Around line 55-62: The error handling in whoami’s config load path only
special-cases errs.ConfigError and returns all other f.Config() failures
directly, which breaks the typed-error contract. In whoami.go, update the cfg,
err := f.Config() branch to wrap any unclassified error with
errs.NewInternalError(errs.SubtypeUnknown, ...) and attach the original error
via WithCause(err), while keeping the existing errors.As(err, &cfgErr) path for
renderNotConfigured.

---

Nitpick comments:
In `@cmd/whoami/whoami.go`:
- Around line 36-41: The whoami command is dropping the Cobra command context,
so cancellation from Ctrl+C/parent commands does not reach the verification
network call. Update the RunE closure on the whoami command to pass
cmd.Context() through to whoamiRun, and adjust whoamiRun (and any related
helpers it calls, such as the verify/identitydiag.Diagnose path) to accept and
use that context instead of context.Background().
🪄 Autofix (Beta)

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

Run ID: e7fb53b1-a5e9-4694-80fe-a7be74975473

📥 Commits

Reviewing files that changed from the base of the PR and between 8a268aa and 516c6cb.

📒 Files selected for processing (7)
  • cmd/auth/status.go
  • cmd/build.go
  • cmd/whoami/whoami.go
  • cmd/whoami/whoami_test.go
  • internal/identitydiag/diagnostics.go
  • internal/identitydiag/diagnostics_test.go
  • skills/lark-shared/SKILL.md

Comment thread cmd/whoami/whoami.go Outdated
Comment on lines +55 to +62
cfg, err := f.Config()
if err != nil {
var cfgErr *errs.ConfigError
if errors.As(err, &cfgErr) {
return renderNotConfigured(opts, cfgErr)
}
return err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect what error types f.Config() can return.
ast-grep run --pattern 'func ($_ $_) Config() (*core.CliConfig, error) { $$$ }' --lang go internal/cmdutil 2>/dev/null
rg -nP 'Config\s+func\(\)\s*\(\*core\.CliConfig,\s*error\)' --type=go internal/cmdutil -C3

Repository: larksuite/cli

Length of output: 757


🏁 Script executed:

#!/bin/bash
# Find where Factory struct is instantiated and Config field is assigned
rg -n 'Factory{.*Config' --type=go -A5 --include='*.go'
# Also search for .Config = assignment patterns
rg -n '\.Config\s*=\s*func' --type=go -B2 -A10
# Search for implementations of config loading functions
ast-grep run --pattern 'func $_() (*core.CliConfig, error) { $$$ }' --lang go . --limit 10

Repository: larksuite/cli

Length of output: 593


🏁 Script executed:

#!/bin/bash
# Find where Factory struct is instantiated and Config field is assigned
rg -n 'Factory{.*Config' --type=go -A5
# Also search for .Config = assignment patterns
rg -n '\.Config\s*=\s*func' --type=go -B2 -A10
# Search for implementations of config loading functions
ast-grep run --pattern 'func $_() (*core.CliConfig, error) { $$$ }' --lang go . --limit 10

Repository: larksuite/cli

Length of output: 258


🏁 Script executed:

#!/bin/bash
# Fix regex syntax and search for Factory struct initialization
rg -n 'Factory{' --type=go -A10 | head -100
# Search for Config field assignment with lambda
rg -n 'Config:' --type=go -B2 -A10
# Find all functions returning (*core.CliConfig, error)
ast-grep run --pattern 'func $NAME() (*core.CliConfig, error) { $$$ }' --lang go .

Repository: larksuite/cli

Length of output: 231


🏁 Script executed:

#!/bin/bash
# Search for Factory struct initialization (escape braces)
rg -n 'Factory\{' --type=go -A15 | head -150
# Search for Config field assignment
rg -n 'Config:' --type=go -B2 -A15 | head -150
# Find all functions returning (*core.CliConfig, error)
ast-grep run --pattern 'func $NAME() (*core.CliConfig, error) { $$$ }' --lang go .

Repository: larksuite/cli

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Search for Factory struct initialization more broadly
rg -n 'Factory' --type=go | grep -E '(=|return|&)' | head -50
# Look at the factory.go file to see how Config is typically set
cat -n internal/cmdutil/factory.go | head -80
# Search for any function that loads config
rg -n 'LoadConfig|loadConfig|readConfig' --type=go -i | head -30

Repository: larksuite/cli

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Read the factory.go file to see the Factory struct and see if there are NewFactory or similar functions
cat -n internal/cmdutil/factory.go
# Search for file names containing "factory" to find related files
fd -t f --extension go -g '*factory*'
# Look for any place where Factory is used or created
rg -n 'NewFactory|NewCmdFactory|MakeFactory' --type=go

Repository: larksuite/cli

Length of output: 10173


🏁 Script executed:

#!/bin/bash
# Search for usages of Factory struct initialization to find where Config is assigned
rg -n 'Factory{' --type=go -A20
# Search for patterns like ".Config = " or ".Config:"
rg -n '\.Config\s*[:=]' --type=go -B2 -A5 | head -100
# Look for the main entry point to see how Factory is created
rg -n 'func main|NewInvocationContext|NewFactory' --type=go | head -30
# Find cmd/root.go or similar initialization files
fd -t f -g '*root*' --extension go cmd

Repository: larksuite/cli

Length of output: 231


🏁 Script executed:

#!/bin/bash
# Escape braces properly for rg
rg -n 'Factory\{' --type=go -A20
# Search for patterns like ".Config =" or ".Config:"
rg -n '\.Config\s*[:=]' --type=go -B2 -A5 | head -100
# Look for the main entry point to see how Factory is created
rg -n 'func main|NewInvocationContext|NewFactory' --type=go | head -30
# Find cmd/root.go or similar initialization files
fd -t f -g '*root*' --extension go cmd

Repository: larksuite/cli

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Search for where Factory is initialized (look for struct literals)
rg -n 'func.*Config.*func' --type=go -B2 -A10 | head -100
# Find main.go or root command files
fd -t f 'main.go' cmd
fd -t f 'root.go' cmd
# Read the cmd/root.go or main file to see Factory initialization
cat -n cmd/main.go 2>/dev/null || cat -n cmd/root.go 2>/dev/null || find cmd -name '*.go' -exec sh -c 'echo "=== {} ===" && head -80 {}' \; | head -200

Repository: larksuite/cli

Length of output: 151


🏁 Script executed:

#!/bin/bash
# List all Go files in cmd directory to find initialization code
find cmd -name '*.go' -type f
# Search for NewInvocationContext or where Factory fields are set
rg -n 'InvocationContext' --type=go | head -30
# Look for any file that constructs Factory struct
rg -n 'Config.*:.*func' --type=go -B2 -A10 | head -100

Repository: larksuite/cli

Length of output: 3741


🏁 Script executed:

#!/bin/bash
# Read cmd/root.go to see how Factory is initialized
cat -n cmd/root.go | head -150
# Search for where the Config func is assigned in Factory
rg -n 'Config:' --type=go -B2 -A15 | head -200
# Look for factory initialization patterns without braces in pattern
rg -n 'func \(\w+ \*Factory\) Config' --type=go -A30

Repository: larksuite/cli

Length of output: 5887


🏁 Script executed:

#!/bin/bash
# Continue reading cmd/root.go to find buildInternal function which likely creates Factory
cat -n cmd/root.go | sed -n '150,250p'
# Search for buildInternal function definition
rg -n 'func buildInternal' --type=go -A50 | head -80
# Search for where Config is assigned in Factory struct literal
rg -n 'Config:' --type=go -B5 -A20 | head -150

Repository: larksuite/cli

Length of output: 4932


🏁 Script executed:

#!/bin/bash
# Search for buildInternal function which creates the Factory
rg -n 'func buildInternal' --type=go -A80 | head -120
# Also search for where the Config function is actually assigned/defined
rg -n '\.Config\s*=\s*func' --type=go -B5 -A15
# Look for factory_test.go or other files that might show how Config is set
cat -n internal/cmdutil/factory_test.go | head -100

Repository: larksuite/cli

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Search for buildInternal definition more broadly
ast-grep run --pattern 'func $FUNC($CONTEXT, $INV) $TYP { $$$ }' --lang go . | head -20
# Look for the file containing buildInternal
rg -l 'buildInternal' --type=go
# Search for any pattern that assigns Config to a function
rg -n 'Config.*func\(\)' --type=go -B2 -A3 | head -80

Repository: larksuite/cli

Length of output: 1480


🏁 Script executed:

#!/bin/bash
# Find the file containing buildInternal
rg -l 'buildInternal' --type=go
# Read cmd/build.go which likely contains buildInternal
cat -n cmd/build.go | head -150

Repository: larksuite/cli

Length of output: 159


🏁 Script executed:

#!/bin/bash
# Read cmd/build.go which likely contains buildInternal
cat -n cmd/build.go | head -200
# Search for where Config field is assigned
rg -n 'factory.Config' --type=go -B5 -A5
# Look for factory assignment patterns
rg -n 'f.Config' --type=go -B5 -A5 | head -100

Repository: larksuite/cli

Length of output: 9093


Wrap unclassified errors from f.Config() to satisfy the typed-error contract.

Per the coding guidelines for cmd/**/*.go, unclassified lower-layer errors used as final output must be wrapped with errs.NewInternalError(errs.SubtypeUnknown, ...).WithCause(err). The current code only handles *errs.ConfigError explicitly; any other error returned from f.Config() is passed bare, violating the contract.

if err != nil {
    var cfgErr *errs.ConfigError
    if errors.As(err, &cfgErr) {
        return renderNotConfigured(opts, cfgErr)
    }
-   return err
+   return errs.NewInternalError(errs.SubtypeUnknown, "failed to load configuration").WithCause(err)
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cfg, err := f.Config()
if err != nil {
var cfgErr *errs.ConfigError
if errors.As(err, &cfgErr) {
return renderNotConfigured(opts, cfgErr)
}
return err
}
cfg, err := f.Config()
if err != nil {
var cfgErr *errs.ConfigError
if errors.As(err, &cfgErr) {
return renderNotConfigured(opts, cfgErr)
}
return errs.NewInternalError(errs.SubtypeUnknown, "failed to load configuration").WithCause(err)
}
🤖 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/whoami/whoami.go` around lines 55 - 62, The error handling in whoami’s
config load path only special-cases errs.ConfigError and returns all other
f.Config() failures directly, which breaks the typed-error contract. In
whoami.go, update the cfg, err := f.Config() branch to wrap any unclassified
error with errs.NewInternalError(errs.SubtypeUnknown, ...) and attach the
original error via WithCause(err), while keeping the existing errors.As(err,
&cfgErr) path for renderNotConfigured.

Source: Coding guidelines

@CLAassistant

CLAassistant commented Jun 26, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@maojinze7-prog
maojinze7-prog deleted the feat/whoami-command branch June 26, 2026 16:04
@maojinze7-prog
maojinze7-prog restored the feat/whoami-command branch June 27, 2026 09:57
@github-actions github-actions Bot added size/M Single-domain feat or fix with limited business impact and removed size/L Large or sensitive change across domains or core paths labels Jun 27, 2026
@maojinze7-prog maojinze7-prog changed the title feat: add whoami command to show current identity test Jun 27, 2026
@maojinze7-prog
maojinze7-prog deleted the feat/whoami-command branch June 27, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants