docs: drop Miaoda brand word from apps command help text (#1399)

This commit is contained in:
raistlin042
2026-06-13 14:00:30 +08:00
committed by GitHub
parent e1af7e3018
commit 0fbfe68726
24 changed files with 86 additions and 86 deletions

View File

@@ -13,12 +13,12 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsAccessScopeGet reads the current access scope configuration of a Miaoda app.
// AppsAccessScopeGet reads the current access scope configuration of an app.
// 响应原样透传服务端契约(字符串 scope 枚举 All/Tenant/Range + 拆分的 users/departments/chats 数组)。
var AppsAccessScopeGet = common.Shortcut{
Service: appsService,
Command: "+access-scope-get",
Description: "Get Miaoda app access scope configuration",
Description: "Get app access scope configuration",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +access-scope-get --app-id <app_id>",
@@ -39,7 +39,7 @@ var AppsAccessScopeGet = common.Shortcut{
appID := strings.TrimSpace(rctx.Str("app-id"))
return common.NewDryRunAPI().
GET(fmt.Sprintf("%s/apps/%s/access-scope", apiBasePath, validate.EncodePathSegment(appID))).
Desc("Get Miaoda app access scope")
Desc("Get app access scope")
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {
appID := strings.TrimSpace(rctx.Str("app-id"))

View File

@@ -24,7 +24,7 @@ var allowedAccessTargetTypes = map[string]bool{
var AppsAccessScopeSet = common.Shortcut{
Service: appsService,
Command: "+access-scope-set",
Description: "Set Miaoda app access scope (specific / public / tenant)",
Description: "Set app access scope (specific / public / tenant)",
Risk: "write",
Tips: []string{
`Example: lark-cli apps +access-scope-set --app-id <app_id> --scope tenant`,
@@ -52,7 +52,7 @@ var AppsAccessScopeSet = common.Shortcut{
appID := strings.TrimSpace(rctx.Str("app-id"))
dry := common.NewDryRunAPI().
PUT(fmt.Sprintf("%s/apps/%s/access-scope", apiBasePath, validate.EncodePathSegment(appID))).
Desc("Set Miaoda app access scope")
Desc("Set app access scope")
body, bodyErr := buildAccessScopeBody(rctx)
if bodyErr != nil {
dry.Set("body_error", bodyErr.Error())

View File

@@ -12,13 +12,13 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
const createHint = "verify --app-type is html or full_stack and --name is non-empty; if this is a permission error, confirm your account can create Miaoda apps"
const createHint = "verify --app-type is html or full_stack and --name is non-empty; if this is a permission error, confirm your account can create apps"
// AppsCreate creates a new Miaoda app.
// AppsCreate creates a new app.
var AppsCreate = common.Shortcut{
Service: appsService,
Command: "+create",
Description: "Create a new Miaoda app",
Description: "Create a new app",
Risk: "write",
Tips: []string{
`Example: lark-cli apps +create --name "审批系统" --app-type full_stack`,
@@ -42,7 +42,7 @@ var AppsCreate = common.Shortcut{
DryRun: func(ctx context.Context, rctx *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
POST(apiBasePath + "/apps").
Desc("Create a Miaoda app").
Desc("Create an app").
Body(buildAppsCreateBody(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -14,7 +14,7 @@ import (
const dbEnvCreateHint = "verify --app-id is correct; if the app is already multi-env this is a conflict — inspect current tables with `lark-cli apps +db-table-list --app-id <app_id> --env dev`"
// AppsDBEnvCreate creates a DB environment for a Miaoda app拆分单库为 dev/online 多环境)。
// AppsDBEnvCreate creates a DB environment for an app拆分单库为 dev/online 多环境)。
//
// 调 POST /apps/{app_id}/db_dev_init。--env 指定要创建的环境,由调用方传入,目前只支持 dev。
// 不可逆:单库一旦拆成 dev/online 双库无法回退。Risk: high-risk-write 触发框架自动注入 --yes 确认关卡。
@@ -30,7 +30,7 @@ var AppsDBEnvCreate = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app id", Required: true},
{Name: "app-id", Desc: "app id", Required: true},
{Name: "env", Default: "dev", Enum: []string{"dev"}, Desc: "environment to create (only dev supported for now)"},
{Name: "sync-data", Type: "bool", Desc: "copy existing online data into the new environment (default off)"},
},
@@ -42,7 +42,7 @@ var AppsDBEnvCreate = common.Shortcut{
appID, _ := requireAppID(rctx.Str("app-id"))
return common.NewDryRunAPI().
POST(appDbEnvCreatePath(appID)).
Desc("Create Miaoda app DB environment").
Desc("Create app DB environment").
Body(buildDBEnvCreateBody(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -17,7 +17,7 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsDBExecute executes SQL against a Miaoda app database.
// AppsDBExecute executes SQL against an app database.
//
// POST /apps/{app_id}/sql_commandsCLI 永远带 ?transactional=false 进入 DBA 模式
// (不默认包事务、支持 DDL、result 字符串内嵌结构化 JSON
@@ -45,7 +45,7 @@ import (
var AppsDBExecute = common.Shortcut{
Service: appsService,
Command: "+db-execute",
Description: "Execute SQL (SELECT / DML / DDL) against a Miaoda app database",
Description: "Execute SQL (SELECT / DML / DDL) against an app database",
Risk: "high-risk-write",
Tips: []string{
`Example: lark-cli apps +db-execute --app-id <app_id> --sql "SELECT * FROM orders LIMIT 10" --yes`,
@@ -56,7 +56,7 @@ var AppsDBExecute = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app id", Required: true},
{Name: "app-id", Desc: "app id", Required: true},
{Name: "sql", Desc: "SQL text; use - to read stdin. Mutually exclusive with --file",
Input: []string{common.Stdin}},
{Name: "file", Desc: "path to a .sql file (relative to cwd). Mutually exclusive with --sql"},
@@ -97,7 +97,7 @@ var AppsDBExecute = common.Shortcut{
appID, _ := requireAppID(rctx.Str("app-id"))
return common.NewDryRunAPI().
POST(appSQLPath(appID)).
Desc("Execute SQL on Miaoda app database").
Desc("Execute SQL on app database").
Params(buildDBSQLParams(rctx)).
Body(buildDBSQLBody(rctx))
},

View File

@@ -35,7 +35,7 @@ var AppsDBTableGet = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app id", Required: true},
{Name: "app-id", Desc: "app id", Required: true},
{Name: "table", Desc: "table name", Required: true},
{Name: "env", Default: "online", Enum: []string{"dev", "online"}, Desc: "target db environment"},
},
@@ -52,7 +52,7 @@ var AppsDBTableGet = common.Shortcut{
appID, _ := requireAppID(rctx.Str("app-id"))
return common.NewDryRunAPI().
GET(appTablePath(appID, strings.TrimSpace(rctx.Str("table")))).
Desc("Get Miaoda app db table schema").
Desc("Get app db table schema").
Params(buildDBTableGetParams(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -15,7 +15,7 @@ import (
const dbTableListHint = "verify --app-id is correct; if targeting --env dev, create it first with `lark-cli apps +db-env-create --app-id <app_id> --env dev`"
// AppsDBTableList lists tables in a Miaoda app's database.
// AppsDBTableList lists tables in an app's database.
//
// GET /apps/{app_id}/tablescursor 分页response items[] 含 estimated_row_count /
// size_bytes optional 字段,默认返回,不必额外传 query。
@@ -29,7 +29,7 @@ const dbTableListHint = "verify --app-id is correct; if targeting --env dev, cre
var AppsDBTableList = common.Shortcut{
Service: appsService,
Command: "+db-table-list",
Description: "List tables in a Miaoda app database (cursor pagination)",
Description: "List tables in an app database (cursor pagination)",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +db-table-list --app-id <app_id>",
@@ -39,7 +39,7 @@ var AppsDBTableList = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app id", Required: true},
{Name: "app-id", Desc: "app id", Required: true},
{Name: "env", Default: "online", Enum: []string{"dev", "online"}, Desc: "target db environment"},
{Name: "page-size", Type: "int", Default: "20", Desc: "page size"},
{Name: "page-token", Desc: "pagination cursor from previous response"},
@@ -52,7 +52,7 @@ var AppsDBTableList = common.Shortcut{
appID, _ := requireAppID(rctx.Str("app-id"))
return common.NewDryRunAPI().
GET(appTablesPath(appID)).
Desc("List Miaoda app db tables").
Desc("List app db tables").
Params(buildDBTableListParams(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -19,7 +19,7 @@ import (
var AppsHTMLPublish = common.Shortcut{
Service: appsService,
Command: "+html-publish",
Description: "Publish HTML to a Miaoda app (single multipart POST returns the access URL)",
Description: "Publish HTML to an app (single multipart POST returns the access URL)",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +html-publish --app-id <app_id> --path ./dist",
@@ -29,7 +29,7 @@ var AppsHTMLPublish = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
{Name: "path", Desc: "path to HTML file or directory", Required: true},
{Name: "allow-sensitive", Type: "bool", Desc: "skip the credential-file scan (allow .env / .npmrc / .aws/credentials / etc. in the publish payload)"},
},
@@ -179,7 +179,7 @@ func ensureIndexHTML(candidates []htmlPublishCandidate) error {
}
}
return appsFailedPreconditionParamError("--path", "--path is missing index.html").
WithHint("Miaoda uses index.html as the app entrypoint; for a directory put index.html at the root, or pass a single file named index.html")
WithHint("index.html is the app entrypoint; for a directory put index.html at the root, or pass a single file named index.html")
}
func runHTMLPublish(ctx context.Context, fio fileio.FileIO, publisher appsHTMLPublishClient, spec appsHTMLPublishSpec) (map[string]interface{}, error) {

View File

@@ -27,8 +27,8 @@ const defaultInitBranch = "sprint/default"
// the non-empty (`app sync`) path stays a single commit.
const (
commitMsgAppCode = "chore: initialize app project code"
commitMsgAppConfig = "chore: initialize miaoda app config"
commitMsgUpgrade = "chore: initialize miaoda app repository"
commitMsgAppConfig = "chore: initialize app config"
commitMsgUpgrade = "chore: initialize app repository"
)
// scaffold kinds returned by runScaffold and consumed by commitAndPushIfDirty.
@@ -49,11 +49,11 @@ const (
// can swap in a fakeCommandRunner. Production uses execCommandRunner.
var initRunner commandRunner = execCommandRunner{}
// AppsInit initializes a Miaoda app's code and local development environment.
// AppsInit initializes an app's code and local development environment.
var AppsInit = common.Shortcut{
Service: appsService,
Command: "+init",
Description: "Initialize a Miaoda app's code and local development environment",
Description: "Initialize an app's code and local development environment",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +init --app-id <app_id> --dir <dir>",
@@ -73,7 +73,7 @@ var AppsInit = common.Shortcut{
// envelope. The spec and the E2E assert exit-2 + a structured
// {"ok":false,"error":{...}} envelope for missing --app-id, so the empty
// check lives in Validate (typed validation error -> exit 2).
{Name: "app-id", Desc: "Miaoda app ID"},
{Name: "app-id", Desc: "app ID"},
{Name: "dir", Desc: "clone target directory; absolute or relative path (default ./<app-id>)"},
{Name: "template", Desc: "code-init template for an empty repo; optional — if omitted, derived from the app's tech stack"},
},
@@ -87,7 +87,7 @@ var AppsInit = common.Shortcut{
appID := strings.TrimSpace(rctx.Str("app-id"))
template := resolveTemplate(rctx, appID)
dry := common.NewDryRunAPI().
Desc("Initialize Miaoda app code (credential-init, clone, checkout, npx code-init, optional commit/push)").
Desc("Initialize app code (credential-init, clone, checkout, npx code-init, optional commit/push)").
Set("credential_init", fmt.Sprintf("apps +git-credential-init --app-id %s --format json", appID)).
Set("checkout", "git checkout "+defaultInitBranch).
Set("scaffold", fmt.Sprintf("empty repo: npx -y --prefer-online %s app init --template %s --app-id %s; non-empty: npx -y --prefer-online %s app sync + .spark/meta.json app_id patch + conditional skills sync --local", miaodaCLIPkg, template, appID, miaodaCLIPkg)).
@@ -191,7 +191,7 @@ func ensureEmptyDir(dir string) error {
return nil
}
// isAlreadyInitialized reports whether dir is an already-initialized Miaoda app
// isAlreadyInitialized reports whether dir is an already-initialized app
// repo, detected by the presence of <dir>/.spark/meta.json (regardless of its
// app_id value). Used to short-circuit +init into a friendly no-op.
func isAlreadyInitialized(dir string) bool {
@@ -379,7 +379,7 @@ func appsInitExecute(ctx context.Context, rctx *common.RuntimeContext) error {
}
// Already-initialized short-circuit: a dir containing .spark/meta.json is an
// initialized Miaoda app repo -> skip clone/scaffold/commit, but still refresh
// initialized app repo -> skip clone/scaffold/commit, but still refresh
// the local env so a re-run picks up the latest startup env vars.
if isAlreadyInitialized(dir) {
initLogf(rctx, "Already initialized at %s — refreshing local environment", dir)
@@ -556,7 +556,7 @@ func issueCredentials(ctx context.Context, rctx *common.RuntimeContext, appID st
// commitAndPushIfDirty commits and pushes only when the working tree has
// changes; a clean tree is a no-op (returns false,false). For the empty-repo
// init path (scaffoldKind == "init") it splits the scaffolded tree into two
// commits — app project code, then Miaoda config (.spark/.agent) — skipping
// commits — app project code, then app config (.spark/.agent) — skipping
// either commit when that group has no changes (no empty commits). Other paths
// commit once. Push is a single `git push origin <branch>` for all commits.
func commitAndPushIfDirty(ctx context.Context, dir, scaffoldKind string) (committed, pushed bool, err error) {
@@ -621,7 +621,7 @@ func stageAndCommit(ctx context.Context, dir, message string, pathspecs ...strin
// classifyPorcelain parses `git status --porcelain` output and partitions the
// changed paths into the "app code" group (anything outside .spark/ and .agent/)
// and the "Miaoda config" group (.spark/ and .agent/). It returns the exact
// and the "app config" group (.spark/ and .agent/). It returns the exact
// porcelain paths so callers can stage them verbatim: porcelain never lists
// gitignored files, so `git add -- <these paths>` never trips git's ignored-path
// error. (Naming an ignored dir explicitly — or combining a "." pathspec with
@@ -658,7 +658,7 @@ func porcelainPath(line string) string {
return p
}
// isConfigPath reports whether p is the Miaoda app-config group: the .spark or
// isConfigPath reports whether p is the app-config group: the .spark or
// .agent directory itself, or anything under them. ".sparkrc" is NOT config.
func isConfigPath(p string) bool {
return p == ".spark" || p == ".agent" ||

View File

@@ -835,7 +835,7 @@ func TestAppsInit_EmptyRepo_TwoCommits(t *testing.T) {
t.Fatalf("unexpected: %v", err)
}
msgs := commitMessages(f.calls)
want := []string{"chore: initialize app project code", "chore: initialize miaoda app config"}
want := []string{"chore: initialize app project code", "chore: initialize app config"}
if len(msgs) != 2 || msgs[0] != want[0] || msgs[1] != want[1] {
t.Fatalf("commit messages = %v, want %v", msgs, want)
}
@@ -896,7 +896,7 @@ func TestAppsInit_EmptyRepo_ConfigOnly_SingleCommit(t *testing.T) {
t.Fatalf("unexpected: %v", err)
}
msgs := commitMessages(f.calls)
if len(msgs) != 1 || msgs[0] != "chore: initialize miaoda app config" {
if len(msgs) != 1 || msgs[0] != "chore: initialize app config" {
t.Fatalf("commit messages = %v, want one config commit", msgs)
}
}
@@ -916,7 +916,7 @@ func TestAppsInit_NonEmpty_SingleInitCommit(t *testing.T) {
t.Fatalf("unexpected: %v", err)
}
msgs := commitMessages(f.calls)
if len(msgs) != 1 || msgs[0] != "chore: initialize miaoda app repository" {
if len(msgs) != 1 || msgs[0] != "chore: initialize app repository" {
t.Fatalf("commit messages = %v, want one upgrade commit", msgs)
}
for _, c := range f.calls {

View File

@@ -12,7 +12,7 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsList lists Miaoda apps visible to the calling user (cursor pagination).
// AppsList lists apps visible to the calling user (cursor pagination).
//
// Supports name fuzzy match (--keyword), ownership-dimension filter
// (--ownership: all / mine / shared), and app-type filter (--app-type). See
@@ -22,7 +22,7 @@ import (
var AppsList = common.Shortcut{
Service: appsService,
Command: "+list",
Description: "List Miaoda apps visible to the calling user (cursor pagination)",
Description: "List apps visible to the calling user (cursor pagination)",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +list",
@@ -42,7 +42,7 @@ var AppsList = common.Shortcut{
DryRun: func(ctx context.Context, rctx *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
GET(apiBasePath + "/apps").
Desc("List Miaoda apps").
Desc("List apps").
Params(buildAppsListParams(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -13,11 +13,11 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsReleaseCreate creates a release for a Miaoda app.
// AppsReleaseCreate creates a release for an app.
var AppsReleaseCreate = common.Shortcut{
Service: appsService,
Command: "+release-create",
Description: "Create a release for a Miaoda app (returns release_id for status polling)",
Description: "Create a release for an app (returns release_id for status polling)",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +release-create --app-id <app_id>",
@@ -27,7 +27,7 @@ var AppsReleaseCreate = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
{Name: "branch", Desc: "release branch (server uses default if omitted)"},
},
Validate: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -26,7 +26,7 @@ var AppsReleaseGet = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
{Name: "release-id", Desc: "release ID (the release_id returned by +release-create)", Required: true},
},
Validate: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -14,11 +14,11 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsReleaseList lists a Miaoda app's release history (most recent first).
// AppsReleaseList lists an app's release history (most recent first).
var AppsReleaseList = common.Shortcut{
Service: appsService,
Command: "+release-list",
Description: "List a Miaoda app's release history (most recent first)",
Description: "List an app's release history (most recent first)",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +release-list --app-id <app_id>",
@@ -28,7 +28,7 @@ var AppsReleaseList = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
{Name: "status", Enum: []string{"publishing", "finished", "failed"}, Desc: "filter by release status: publishing | finished | failed"},
{Name: "page-size", Type: "int", Default: "20", Desc: "page size (max 500)"},
{Name: "page-token", Desc: "pagination cursor from a previous response"},

View File

@@ -13,11 +13,11 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsSessionCreate creates a new session under an existing Miaoda app.
// AppsSessionCreate creates a new session under an existing app.
var AppsSessionCreate = common.Shortcut{
Service: appsService,
Command: "+session-create",
Description: "Create a session under a Miaoda app",
Description: "Create a session under an app",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +session-create --app-id <app_id>",
@@ -37,7 +37,7 @@ var AppsSessionCreate = common.Shortcut{
DryRun: func(ctx context.Context, rctx *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
POST(sessionsPath(rctx.Str("app-id"))).
Desc("Create a session under a Miaoda app")
Desc("Create a session under an app")
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {
data, err := rctx.CallAPITyped("POST", sessionsPath(rctx.Str("app-id")), nil, nil)

View File

@@ -12,11 +12,11 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsSessionList lists sessions under a Miaoda app (cursor pagination, single page).
// AppsSessionList lists sessions under an app (cursor pagination, single page).
var AppsSessionList = common.Shortcut{
Service: appsService,
Command: "+session-list",
Description: "List sessions under a Miaoda app (cursor pagination)",
Description: "List sessions under an app (cursor pagination)",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +session-list --app-id <app_id>",
@@ -39,7 +39,7 @@ var AppsSessionList = common.Shortcut{
DryRun: func(ctx context.Context, rctx *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
GET(sessionsPath(rctx.Str("app-id"))).
Desc("List sessions under a Miaoda app").
Desc("List sessions under an app").
Params(buildSessionListParams(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -13,11 +13,11 @@ import (
"github.com/larksuite/cli/shortcuts/common"
)
// AppsUpdate partially updates a Miaoda app's name / description.
// AppsUpdate partially updates an app's name / description.
var AppsUpdate = common.Shortcut{
Service: appsService,
Command: "+update",
Description: "Partially update a Miaoda app (only provided fields are sent)",
Description: "Partially update an app (only provided fields are sent)",
Risk: "write",
Tips: []string{
`Example: lark-cli apps +update --app-id <app_id> --name "新名称"`,
@@ -49,7 +49,7 @@ var AppsUpdate = common.Shortcut{
appID := strings.TrimSpace(rctx.Str("app-id"))
return common.NewDryRunAPI().
PATCH(fmt.Sprintf("%s/apps/%s", apiBasePath, validate.EncodePathSegment(appID))).
Desc("Update a Miaoda app").
Desc("Update an app").
Body(buildAppsUpdateBody(rctx))
},
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {

View File

@@ -12,12 +12,12 @@ import (
// appsService 是 CLI 命令的 service 前缀lark-cli apps ...)。
const appsService = "apps"
// apiBasePath is the registered OAPI prefix for the Miaoda apps domain.
// apiBasePath is the registered OAPI prefix for the apps domain.
const apiBasePath = "/open-apis/spark/v1"
// appIDListHint is the shared recovery hint for commands whose most likely
// failure cause is a wrong/inaccessible --app-id. It points at +list to find
// the correct Miaoda app id. The app_/cli_ format rule is taught in
// the correct app id. The app_/cli_ format rule is taught in
// lark-apps SKILL.md ("app_id 获取"); the hint stays lean and does not repeat it.
const appIDListHint = "verify --app-id is correct and you have access to the app; list your apps with `lark-cli apps +list`"

View File

@@ -35,12 +35,12 @@ const gitCredentialIssuePath = apiBasePath + "/apps/:app_id/git_info"
// gitCredentialIssueHint is the actionable next-step attached to a failed
// Git-credential issuance. A 5xx is flagged retryable separately at the call site.
const gitCredentialIssueHint = "failed to issue the Git credential: verify --app-id is correct and you have developer access to this Miaoda app; a 5xx is a transient server error and is safe to retry"
const gitCredentialIssueHint = "failed to issue the Git credential: verify --app-id is correct and you have developer access to this app; a 5xx is a transient server error and is safe to retry"
var AppsGitCredentialInit = common.Shortcut{
Service: appsService,
Command: "+git-credential-init",
Description: "Initialize Git credentials and a URL-scoped Git helper for a Miaoda app repository",
Description: "Initialize Git credentials and a URL-scoped Git helper for an app repository",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +git-credential-init --app-id <app_id>",
@@ -49,7 +49,7 @@ var AppsGitCredentialInit = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
},
Validate: func(ctx context.Context, rctx *common.RuntimeContext) error {
if strings.TrimSpace(rctx.Str("app-id")) == "" {
@@ -64,7 +64,7 @@ var AppsGitCredentialInit = common.Shortcut{
appID := strings.TrimSpace(rctx.Str("app-id"))
return common.NewDryRunAPI().
GET(gitCredentialIssuePath).
Desc("Issue a Miaoda Git repository PAT").
Desc("Issue an app Git repository PAT").
Set("mode", "api-plus-local-setup").
Set("action", "initialize_local_git_credential").
Set("app_id", appID).
@@ -81,7 +81,7 @@ var AppsGitCredentialInit = common.Shortcut{
manager := newGitCredentialManager(appID, rctx.Factory.Keychain, runtimeIssuer{rctx: rctx})
result, err := manager.Init(ctx, profileFromConfig(rctx.Config), appID)
if err != nil {
return gitCredentialLocalError("Initialize local Miaoda Git credential", err)
return gitCredentialLocalError("Initialize local app Git credential", err)
}
payload := map[string]interface{}{
"app_id": result.AppID,
@@ -119,7 +119,7 @@ var AppsGitCredentialInit = common.Shortcut{
var AppsGitCredentialRemove = common.Shortcut{
Service: appsService,
Command: "+git-credential-remove",
Description: "Remove local Git credentials and the URL-scoped Git helper for a Miaoda app repository",
Description: "Remove local Git credentials and the URL-scoped Git helper for an app repository",
Risk: "write",
Tips: []string{
"Example: lark-cli apps +git-credential-remove --app-id <app_id>",
@@ -128,7 +128,7 @@ var AppsGitCredentialRemove = common.Shortcut{
AuthTypes: []string{"user"},
HasFormat: true,
Flags: []common.Flag{
{Name: "app-id", Desc: "Miaoda app ID", Required: true},
{Name: "app-id", Desc: "app ID", Required: true},
},
Validate: func(ctx context.Context, rctx *common.RuntimeContext) error {
if strings.TrimSpace(rctx.Str("app-id")) == "" {
@@ -159,7 +159,7 @@ var AppsGitCredentialRemove = common.Shortcut{
manager := newGitCredentialManager(appID, rctx.Factory.Keychain, nil)
result, err := manager.Remove(ctx, profileFromConfig(rctx.Config), appID)
if err != nil {
return gitCredentialLocalError("Remove local Miaoda Git credential", err)
return gitCredentialLocalError("Remove local app Git credential", err)
}
payload := map[string]interface{}{
"app_id": result.AppID,
@@ -193,7 +193,7 @@ var AppsGitCredentialRemove = common.Shortcut{
var AppsGitCredentialList = common.Shortcut{
Service: appsService,
Command: "+git-credential-list",
Description: "List local Git credentials for Miaoda app repositories",
Description: "List local Git credentials for app repositories",
Risk: "read",
Tips: []string{
"Example: lark-cli apps +git-credential-list",
@@ -215,7 +215,7 @@ var AppsGitCredentialList = common.Shortcut{
Execute: func(ctx context.Context, rctx *common.RuntimeContext) error {
records, err := listGitCredentialRecords(rctx.Factory.Keychain, time.Now)
if err != nil {
return gitCredentialLocalError("List local Miaoda Git credentials", err)
return gitCredentialLocalError("List local app Git credentials", err)
}
payload := map[string]interface{}{
"count": len(records),
@@ -252,7 +252,7 @@ func InstallOnApps(parent *cobra.Command, f *cmdutil.Factory) {
func newGitCredentialHelperCommand(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "git-credential-helper get|store|erase",
Short: "Git credential helper for Miaoda app repositories",
Short: "Git credential helper for app repositories",
Hidden: true,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@@ -260,7 +260,7 @@ func newGitCredentialHelperCommand(f *cmdutil.Factory) *cobra.Command {
return runGitCredentialHelper(cmd.Context(), f, strings.TrimSpace(appID), args[0])
},
}
cmd.Flags().String("app-id", "", "Miaoda app ID")
cmd.Flags().String("app-id", "", "app ID")
_ = cmd.Flags().MarkHidden("app-id")
return cmd
}
@@ -457,10 +457,10 @@ func issuedFromData(appID string, data map[string]interface{}) (*gitcred.IssuedC
issued.AppID = appID
}
if issued.GitHTTPURL == "" {
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response missing gitURL")
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response missing gitURL")
}
if issued.PAT == "" {
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response missing token")
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response missing token")
}
return issued, nil
}
@@ -479,7 +479,7 @@ func parseIssueCredentialData(resp *larkcore.ApiResp, err error, cc errclass.Cla
detail := logIDDetail(resp)
if resp == nil || len(resp.RawBody) == 0 {
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse,
"Issue Miaoda Git credential: empty response body")
"Issue app Git credential: empty response body")
}
var result map[string]any
jsonErr := json.Unmarshal(resp.RawBody, &result)
@@ -522,7 +522,7 @@ func checkGitInfoBaseResp(result map[string]any, logID string) error {
if message == "" {
message = "Git credential API returned non-zero BaseResp status"
}
baseErr := errs.NewAPIError(errs.SubtypeUnknown, "Issue Miaoda Git credential: %s", message).WithCode(int(code))
baseErr := errs.NewAPIError(errs.SubtypeUnknown, "Issue app Git credential: %s", message).WithCode(int(code))
if logID != "" {
baseErr = baseErr.WithLogID(logID)
}

View File

@@ -699,7 +699,7 @@ func assertStringSliceEqual(t *testing.T, got, want []string) {
func TestGitCredentialLocalErrorWrapsOnlyPlainErrors(t *testing.T) {
plain := errors.New("git config failed")
wrapped := gitCredentialLocalError("List local Miaoda Git credentials", plain)
wrapped := gitCredentialLocalError("List local app Git credentials", plain)
var configErr *errs.ConfigError
if !errors.As(wrapped, &configErr) {
t.Fatalf("plain local error wrapped as %T, want *errs.ConfigError", wrapped)

View File

@@ -458,19 +458,19 @@ func defaultUsername(username string) string {
func validateIssuedCredential(appID, normalizedURL string, issued *IssuedCredential, now int64) error {
if issued == nil {
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: empty credential")
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: empty credential")
}
if issued.AppID != "" && issued.AppID != appID {
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response app_id %q does not match requested app_id %q", issued.AppID, appID)
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response app_id %q does not match requested app_id %q", issued.AppID, appID)
}
if normalizedURL == "" {
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response missing gitURL")
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response missing gitURL")
}
if strings.TrimSpace(issued.PAT) == "" {
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response missing token")
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response missing token")
}
if issued.ExpiresAt <= now {
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue Miaoda Git credential: response expiredTime must be in the future")
return errs.NewInternalError(errs.SubtypeInvalidResponse, "Issue app Git credential: response expiredTime must be in the future")
}
return nil
}

View File

@@ -27,7 +27,7 @@ const (
)
// CredentialFile is the app-scoped non-secret metadata persisted under the
// Miaoda app storage directory.
// app storage directory.
type CredentialFile struct {
Version int `json:"version"`
CredentialRecord

View File

@@ -53,7 +53,7 @@ func (api appsHTMLPublishAPI) HTMLPublish(ctx context.Context, appID string, tar
return &htmlPublishResponse{URL: url}, nil
}
// OAPI business error codes returned by the Miaoda
// OAPI business error codes returned by the
// /apps/{id}/upload_and_release_html_code endpoint. Owned by the backend
// service; update when new codes are documented in the OAPI spec.
const (
@@ -66,7 +66,7 @@ func buildHTMLPublishFailureHint(code int) string {
case errCodeBuildFailed:
return "server-side build failed: run `lark-cli apps +html-publish --app-id <your-app-id> --path <path> --dry-run` to inspect the packaged file list"
case errCodeAppNotFound:
return "the app does not exist or the caller has no access; ask the user to confirm the app_id (extract it from the Miaoda app URL https://miaoda.feishu.cn/app/app_xxx after /app/, or take the app_xxx string directly)"
return "the app does not exist or the caller has no access; ask the user to confirm the app_id (extract it from the app URL https://miaoda.feishu.cn/app/app_xxx after /app/, or take the app_xxx string directly)"
default:
return ""
}

View File

@@ -14,7 +14,7 @@
- `TestAppsAccessScopeSetDryRun`: CLI input `specific`/`public`/`tenant` -> server enum `Range`/`All`/`Tenant`; `apply_config.approvers` shape; four mutex rejection paths.
- `TestAppsAccessScopeGetDryRun`: URL shape; no body/params on GET; `--app-id` required.
- `TestAppsHTMLPublishDryRun`: walker manifest for directory + single file; hidden files intentionally included (design decision); empty dir / missing `index.html` produce envelope `validation_error` field (dry-run exits 0 advisory, not blocking); both required-flag rejections.
- `TestAppsGitCredentialInitDryRun`: URL shape for issuing a Miaoda Git PAT; no body; `app_id` query metadata included.
- `TestAppsGitCredentialInitDryRun`: URL shape for issuing an app Git PAT; no body; `app_id` query metadata included.
- `TestAppsGitCredentialListLocalE2E`: local-only command scans every app storage directory and reports repository URL and status without exposing PAT or expiry details.
- `TestAppsGitCredentialRemoveLocalE2E`: local cleanup command removes app-scoped metadata under an isolated config dir.