Skip to content

feat: apps support multi dev modes#1175

Merged
raistlin042 merged 80 commits into
larksuite:mainfrom
raistlin042:feat/lark-apps-dev
Jun 10, 2026
Merged

feat: apps support multi dev modes#1175
raistlin042 merged 80 commits into
larksuite:mainfrom
raistlin042:feat/lark-apps-dev

Conversation

@raistlin042

@raistlin042 raistlin042 commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Build out the apps domain into a full Miaoda development toolchain covering both local fullstack development and cloud-generation workflows (the "multi dev modes"). Beyond the existing HTML create flow, this adds app scaffolding with git-credential provisioning, local env/database debugging, the publish lifecycle, and cloud-generation session management, all exposed as apps + shortcuts.

Changes

Create & discover

  • apps +create: add fullstack app-type (with required --message) alongside HTML; add +list and +chat.

Init & git credentials (apps +init, shortcuts/apps/gitcred/, storage.go)

  • +init clones the app repo, scaffolds via miaoda-cli, and issues repo credentials.
  • Keychain-backed per-app credential/metadata storage with atomic writes and safe-path handling; a hidden git-credential helper plus gitconfig integration for transparent git auth.

Local dev environment (apps +env-pull)

  • Pull app env vars into .env.local, with development-database detection and env-key validation.

App database debugging (apps +db-*)

  • +db-sql (run SQL), +db-table-list, +db-table-schema, +db-dev-init.

Publishing (apps +publish*)

  • +publish, plus +publish-history, +publish-status, +publish-error-log.

Cloud-generation sessions (apps +session-*)

  • +session-create, +session-list, +session-read, +session-stop.

Skill & tests

  • skills/lark-apps/ SKILL.md and per-command references document the full command surface and HTML-vs-fullstack intent routing.
  • Unit + E2E coverage across the new commands; shortcuts/apps package at ~88% statement coverage.

Test Plan

  • make unit-test passed (./shortcuts/apps/... green; package coverage ~88%)
  • validate passed (build / vet / unit / integration)
  • local-eval passed (E2E + skillave across apps commands)
  • acceptance-reviewer passed
  • deferred: real backend round-trip for fullstack create -- server-side interface not yet deployed

Related Issues

N/A

Summary by CodeRabbit

  • New Features

    • App creation now supports case-sensitive types: HTML and fullstack.
    • Added Git credential workflow: init/list/remove commands and a hidden git-credential helper for Git integration.
    • Added local per-app secure storage for credentials and metadata with safe path handling and atomic writes.
  • Tests

    • Extensive unit and end-to-end tests covering fullstack create flows, storage, git-credential lifecycle, helper, and gitconfig behaviors.
  • Documentation

    • Updated fullstack creation guidance and added a Git credential reference and usage guide.

* feat: accept fullstack app-type and require --message for it

* feat: inject message into fullstack create request body

* refactor: align fullstack message injection with existing body-build style

* docs: document fullstack app-type and --message for apps +create

* docs: keep scene numbering consistent in lark-apps-create reference

* docs: add HTML/fullstack intent routing to lark-apps SKILL.md

* docs: cover fullstack in lark-apps skill description and clarify HTML flow step

* test: assert fullstack in allow-list error and reject wrong-cased fullstack
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds case-sensitive support for --app-type fullstack (flag text, validation, and request payload), a filesystem-backed per-app key/value storage API with tests, a comprehensive git-credential manager and helper (CLI shortcuts, hidden git helper, storage adapter, gitconfig integration, secret store, locking, store/types/url normalization), many unit and E2E tests, and documentation updates.

Changes

Apps: fullstack, storage, and git-credential

Layer / File(s) Summary
CLI flag text and payload
shortcuts/apps/apps_create.go
--app-type help updated to “HTML or fullstack”; validation updated to allow fullstack; validAppTypes expanded and app_type set from trimmed input.
Apps create tests
shortcuts/apps/apps_create_test.go
Updated tests to expect fullstack in validation messages; added tests for case-sensitivity, successful fullstack create request body, and dry-run output.
Skill & reference docs
skills/lark-apps/*, skills/lark-apps/references/*
Updated SKILL guidance, examples, and references to document fullstack behavior, intent mapping, and fullstack creation scenarios; added git-credential reference doc.
Local per-app storage implementation
shortcuts/apps/storage.go
New filesystem-backed per-app key/value store with segment validation, encoded segment paths, and exported Read, Write, Delete, List.
Storage tests and env setup
shortcuts/apps/storage_test.go
Comprehensive tests: temp-config helper, round-trip read/write, missing-key semantics, validation, overwrite/delete idempotence, listing, subdir skipping, path-escaping, traversal rejection, and perms.
Git credential shortcuts & helper wiring
shortcuts/apps/git_credential.go, shortcuts/apps/git_credential_storage.go
Adds `+git-credential-init
Git credential shortcut tests
shortcuts/apps/git_credential_test.go
Extensive unit tests covering dry-run shapes, validation, parsing backend shapes, init/remove/list flows, pretty/JSON outputs, error paths, helper dispatcher, and many helper utilities.
gitcred package: manager, store, types, url, keychain, lock, gitconfig
shortcuts/apps/gitcred/*
New gitcred package: types and timing constants, Store (load/save/upsert/find/delete), SecretStore keychain wrapper, URL normalization and PAT ref builder, Manager with Init/Get/Remove/List/Erase, locking and global git config helpers, and helpers for writing git-credential output.
gitcred tests
shortcuts/apps/gitcred/gitcred_test.go
Comprehensive integration/unit tests for manager lifecycle, store semantics, secret store branches, git config set/unset/rollback, normalization, parse errors, and many failure branches with fakes.
Shortcuts/register wiring and tests
shortcuts/apps/shortcuts.go, shortcuts/register.go, tests
Registers new shortcuts, ensures hidden git helper command installed via InstallOnApps, updates Shortcuts() and tests to expect new entries and hidden helper.
CLI E2E tests and coverage doc updates
tests/cli_e2e/apps/*, tests/cli_e2e/apps/coverage.md
Added dry-run E2E for init and local E2E tests for list/remove; updated coverage metrics and docs rows.

Sequence Diagram(s)

(no sequence diagrams generated)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • larksuite/cli#1002: Modifies AppsCreate --app-type handling and related tests (similar app_type changes).
  • larksuite/cli#236: Adds CLI E2E harness utilities used by new E2E tests.
  • larksuite/cli#1025: Related apps shortcuts/register wiring and brand gating changes.

Suggested labels

domain/ccm

Suggested reviewers

  • liangshuo-1

"A rabbit hops on keys at night, 🐇
Fullstack flags now gleam in light,
Small files kept in tidy stores,
Credentials guarded behind closed doors,
Tests sing green — the patch takes flight."

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and overly broad—'multi dev modes' does not clearly convey the main change, which is adding fullstack app support with a message flag. Consider a more specific title like 'feat: add fullstack app type support with message flag to apps +create' to better describe the primary changes.
✅ Passed checks (3 passed)
Check name Status Explanation
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.
Description check ✅ Passed The pull request provides a comprehensive summary with detailed lists of changes, test plan checkboxes, and related issues section.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions github-actions Bot added the size/M Single-domain feat or fix with limited business impact label May 29, 2026

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

🧹 Nitpick comments (1)
shortcuts/apps/apps_create.go (1)

41-41: 💤 Low value

Allowed-values list is duplicated across three sites and can drift.

The supported types now appear in the flag help text (Line 27: "HTML or fullstack"), the validation error (Line 41: "allowed: HTML, fullstack"), and the validAppTypes map (Lines 67-70). Adding a future type means editing all three, and a missed edit produces a misleading user-facing error. Consider deriving the allowed-values string from the map (sorted for deterministic output).

♻️ Example: derive the list from validAppTypes
func allowedAppTypes() string {
	keys := make([]string, 0, len(validAppTypes))
	for k := range validAppTypes {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return strings.Join(keys, ", ")
}
-			return output.ErrValidation(fmt.Sprintf("--app-type %q is not supported (allowed: HTML, fullstack)", appType))
+			return output.ErrValidation(fmt.Sprintf("--app-type %q is not supported (allowed: %s)", appType, allowedAppTypes()))
🤖 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 `@shortcuts/apps/apps_create.go` at line 41, The error message and flag help
duplicate the allowed app types; derive the user-facing list from the canonical
validAppTypes map instead of hardcoding: add a helper (e.g., allowedAppTypes())
that collects keys from validAppTypes, sorts them deterministically, and returns
a comma-separated string, then use that helper in the flag help text and in the
validation error inside the code that returns
output.ErrValidation(fmt.Sprintf("--app-type %q is not supported (allowed: %s)",
appType, allowedAppTypes())). Ensure you reference validAppTypes when building
the list so future type additions only require updating that map.
🤖 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.

Nitpick comments:
In `@shortcuts/apps/apps_create.go`:
- Line 41: The error message and flag help duplicate the allowed app types;
derive the user-facing list from the canonical validAppTypes map instead of
hardcoding: add a helper (e.g., allowedAppTypes()) that collects keys from
validAppTypes, sorts them deterministically, and returns a comma-separated
string, then use that helper in the flag help text and in the validation error
inside the code that returns output.ErrValidation(fmt.Sprintf("--app-type %q is
not supported (allowed: %s)", appType, allowedAppTypes())). Ensure you reference
validAppTypes when building the list so future type additions only require
updating that map.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 392d9f38-c111-4570-b3f0-3cd6e06760f6

📥 Commits

Reviewing files that changed from the base of the PR and between 1ba107d and 06a77dc.

📒 Files selected for processing (4)
  • shortcuts/apps/apps_create.go
  • shortcuts/apps/apps_create_test.go
  • skills/lark-apps/SKILL.md
  • skills/lark-apps/references/lark-apps-create.md

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.26337% with 244 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.69%. Comparing base (077b5e7) to head (d970017).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/apps/apps_init.go 78.73% 45 Missing and 29 partials ⚠️
shortcuts/apps/apps_env_pull.go 87.55% 16 Missing and 13 partials ⚠️
shortcuts/apps/apps_release_list.go 44.68% 24 Missing and 2 partials ⚠️
shortcuts/apps/apps_db_table_list.go 87.05% 17 Missing and 5 partials ⚠️
shortcuts/apps/apps_release_create.go 43.75% 16 Missing and 2 partials ⚠️
shortcuts/apps/apps_db_execute.go 93.75% 11 Missing and 6 partials ⚠️
shortcuts/apps/apps_release_get.go 56.75% 15 Missing and 1 partial ⚠️
shortcuts/apps/apps_session_list.go 62.85% 12 Missing and 1 partial ⚠️
shortcuts/apps/apps_db_table_get.go 80.00% 3 Missing and 3 partials ⚠️
shortcuts/apps/apps_chat.go 85.18% 2 Missing and 2 partials ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1175      +/-   ##
==========================================
+ Coverage   71.95%   72.69%   +0.74%     
==========================================
  Files         699      727      +28     
  Lines       66285    68780    +2495     
==========================================
+ Hits        47695    50001    +2306     
- Misses      14883    15015     +132     
- Partials     3707     3764      +57     

☔ 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 May 29, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add raistlin042/cli#feat/lark-apps-dev -y -g

* feat: drop --message from apps +create

* docs: drop --message and document agent-generated name/description for apps +create

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

🤖 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 `@shortcuts/apps/storage.go`:
- Line 15: The storage.go file under shortcuts should not import internal/vfs;
remove the "github.com/larksuite/cli/internal/vfs" import and replace direct vfs
calls in the storage implementation with the runtime file-IO abstraction: call
runtime.FileIO() for filesystem operations and runtime.ValidatePath() for path
checks (or move this storage package out of shortcuts if you intend to keep
direct internal/vfs usage). Update any functions/methods in storage.go that
reference vfs (e.g., any Read/Write/Delete helpers) to use the runtime FileIO
interface methods instead so the shortcuts/ → runtime boundary is preserved.
- Around line 122-126: List currently appends decoded filenames from
url.PathUnescape without validating them, allowing values like "." or ".." (or
other segments Write would reject) to surface; update the List implementation to
call checkSeg on the decoded key (the result of url.PathUnescape) and skip
(continue) any keys that fail checkSeg, ensuring List only returns keys that
Write would accept.
🪄 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: 870a5ea9-d583-463b-8b56-192368060f55

📥 Commits

Reviewing files that changed from the base of the PR and between 88797de and cccd909.

📒 Files selected for processing (2)
  • shortcuts/apps/storage.go
  • shortcuts/apps/storage_test.go

Comment thread shortcuts/apps/storage.go Outdated
Comment thread shortcuts/apps/storage.go
@CLAassistant

CLAassistant commented Jun 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added size/XL Architecture-level or global-impact change and removed size/M Single-domain feat or fix with limited business impact labels Jun 2, 2026

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/lark-apps/SKILL.md (1)

15-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update the fullstack docs to use --message, not --description.

The new fullstack flow is documented here with --description, but the PR contract says --message is the required flag for --app-type fullstack. As written, the example and routing rules will teach the skill to emit a command that fails validation or drops the generation prompt.

Proposed fix
-lark-cli apps +create           --name "团队任务看板" --app-type fullstack --description "带登录和数据库的任务看板"
+lark-cli apps +create           --name "团队任务看板" --app-type fullstack --message "带登录和数据库的任务看板"
-- 用户要**带后端能力的全栈应用**(数据库 / 登录鉴权 / API / 表单提交存储 / 用户系统 / 增删改查 / 持久化 / 服务端逻辑 / "全栈" / "带后台" / "后台管理")→ `--app-type fullstack`(从用户描述生成 `--name` 和 `--description`),到 `+create` 为止(fullstack 后续本地开发链路待 `+git-credential-init` 就绪后补充)
+- 用户要**带后端能力的全栈应用**(数据库 / 登录鉴权 / API / 表单提交存储 / 用户系统 / 增删改查 / 持久化 / 服务端逻辑 / "全栈" / "带后台" / "后台管理")→ `--app-type fullstack`(从用户描述生成 `--name`,并把原始需求作为 `--message` 传给 `+create`),到 `+create` 为止
-| [`+create`](references/lark-apps-create.md) | 创建妙搭应用(HTML / fullstack;从用户输入生成 name/description) |
+| [`+create`](references/lark-apps-create.md) | 创建妙搭应用(HTML / fullstack;fullstack 需传 `--message`,并从用户输入生成 name/message) |

Also applies to: 87-88, 112-112

🤖 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 `@skills/lark-apps/SKILL.md` at line 15, The example and related examples in
SKILL.md use the wrong flag (--description) for the fullstack flow; update the
"lark-cli apps +create" examples and any routing rules or examples that
reference the fullstack app-type to use --message instead of --description so
the generated commands validate against the PR contract (e.g., replace
--description "..." with --message "...").
🤖 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 `@shortcuts/apps/git_credential.go`:
- Around line 433-450: The APIError struct literal incorrectly uses a
non-existent Detail field; remove the Detail: detail entry from the
errs.APIError literals in the error return sites (the two places constructing
&errs.APIError{Problem: errs.Problem{...}, Detail: detail}) and instead route
the extra context through the supported API by either populating a Detail (or
similar) field on errs.Problem (e.g., set errs.Problem.Detail = detail if that
field exists) or by appending/injecting the detail into the Problem.Message
(e.g., combine firstString(...)/msg with detail) or by calling the package's
provided constructor/wrapper (e.g., any errs.NewAPIError/Wrap helper) that
accepts detail; update the same change for both occurrences referencing
errs.APIError, errs.Problem, firstInt64, firstString and logIDString so the code
compiles and preserves the extra context.

In `@shortcuts/apps/gitcred/gitconfig.go`:
- Around line 24-31: SetHelper (and the corresponding UnsetHelper) must
canonicalize gitHTTPURL before building git-config keys so equivalent URLs map
to the same credential.<url>.* entries; create or call a small canonicalize
function (e.g., normalizeGitHTTPURL) and run gitHTTPURL =
normalizeGitHTTPURL(gitHTTPURL) at the top of SetHelper and UnsetHelper before
calling gitCredentialKey/helperCommand; ensure it trims whitespace, lowercases
scheme/host, removes default ports (80/443) and any trailing slash so
helperCommand, gitCredentialKey and helperKey/useHttpPathKey are derived from
the normalized URL.

In `@shortcuts/apps/gitcred/helper.go`:
- Around line 72-79: The code currently uses m.Store.Current() to find a prior
credential, which can pick the wrong record across apps; instead perform an
app-scoped lookup for the record matching the given appID and URL by iterating
the store's records (e.g. via m.Store.List()/Records()) and selecting the entry
whose AppID and URL match the incoming appID/URL, then use that matched record
as the "previous" record and call m.Secrets.Get(previous.PATRef) only for that
record; update the same pattern in the other block that currently uses
m.Store.Current() (the cleanup logic that updates Refreshed, removes PATs or
unsets git helper) so those changes are applied only to the matched app-specific
record rather than whatever Current() returns.
- Around line 236-245: The fallback after reading a confirmed record currently
only checks found and may write back an expired or PAT-less credential; change
the gate to verify usability by calling m.usable(latest, latestPAT) instead of
relying on found alone so that only usable (non-expired, PAT-present) records
are passed to writeGitCredential(out, latest.Username, latestPAT); adjust the
branch that handles readConfirmed(url, current) to check m.usable(...) and
handle the non-usable case by returning nil (or the existing error flow) rather
than writing an invalid credential.

In `@shortcuts/apps/gitcred/keychain.go`:
- Around line 48-58: SecretStore.Remove currently returns nil when the keychain
backend is unavailable or when s==nil/ref=="" which signals success; change it
to return the same config-style error used by SecretStore.Set() so callers
(e.g., Manager.Remove) do not proceed to delete metadata when the secret still
exists. Update SecretStore.Remove to mirror Set()’s error-handling: when s is
nil, when ref=="" and especially when s.kc==nil (keychain backend unavailable)
return the identical error value/type and message shape that Set() returns, and
adjust/cover behavior in any tests that expect the previous nil return.

In `@shortcuts/apps/gitcred/store.go`:
- Around line 63-65: In Load (shortcuts/apps/gitcred/store.go) the
json.Unmarshal error currently returns output.Errorf(output.ExitAPI, "config",
...), causing corrupted git.json to be treated as an API failure; change the
returned error to a config/local-state typed error (e.g., use output.ExitConfig
or the project's local-state exit constant) while keeping the same message and
MetadataFilename reference so callers like gitCredentialLocalError will
reclassify it as a local/config issue instead of an API error.

In `@shortcuts/apps/gitcred/url.go`:
- Around line 66-71: In normalizeHost(), when net.SplitHostPort succeeds and you
decide to drop the default port (inside the branch checking scheme=="https" &&
port=="443" or scheme=="http" && port=="80"), ensure IPv6 literals are
re-wrapped with brackets before returning: detect if the raw host name contains
':' (indicating an IPv6 literal returned without brackets by net.SplitHostPort)
and return "[" + strings.ToLower(name) + "]"; otherwise return
strings.ToLower(name); this prevents normalizeParsedURL from constructing a URL
authority with a missing required IPv6 bracket. Reference normalizeHost,
normalizeParsedURL and net.SplitHostPort in your change.

In `@tests/cli_e2e/apps/apps_git_credential_local_test.go`:
- Around line 37-41: The assertions assume a stable order of entries in the JSON
(using gjson.Get(result.Stdout, "data.credentials.0...") and index 1), which
makes the test flaky; update the test to treat data.credentials as an unordered
set: parse the credentials array from result.Stdout (using gjson.Get(...,
"data.credentials").Array() or equivalent), then either sort the slice by app_id
or locate items by app_id and assert each item's repository_url and status
(e.g., find the object with app_id "app_a" and assert its repository_url and
status, and likewise for "app_b") instead of asserting fixed indices.

---

Outside diff comments:
In `@skills/lark-apps/SKILL.md`:
- Line 15: The example and related examples in SKILL.md use the wrong flag
(--description) for the fullstack flow; update the "lark-cli apps +create"
examples and any routing rules or examples that reference the fullstack app-type
to use --message instead of --description so the generated commands validate
against the PR contract (e.g., replace --description "..." with --message
"...").
🪄 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: 6107afc1-ea0b-433d-b6f1-821901e4876d

📥 Commits

Reviewing files that changed from the base of the PR and between cccd909 and cbb02b8.

📒 Files selected for processing (22)
  • shortcuts/apps/apps_create_test.go
  • shortcuts/apps/git_credential.go
  • shortcuts/apps/git_credential_storage.go
  • shortcuts/apps/git_credential_test.go
  • shortcuts/apps/gitcred/gitconfig.go
  • shortcuts/apps/gitcred/gitcred_test.go
  • shortcuts/apps/gitcred/helper.go
  • shortcuts/apps/gitcred/keychain.go
  • shortcuts/apps/gitcred/lock.go
  • shortcuts/apps/gitcred/store.go
  • shortcuts/apps/gitcred/types.go
  • shortcuts/apps/gitcred/url.go
  • shortcuts/apps/shortcuts.go
  • shortcuts/apps/shortcuts_test.go
  • shortcuts/apps/storage.go
  • shortcuts/register.go
  • shortcuts/register_test.go
  • skills/lark-apps/SKILL.md
  • skills/lark-apps/references/lark-apps-git-credential.md
  • tests/cli_e2e/apps/apps_git_credential_dryrun_test.go
  • tests/cli_e2e/apps/apps_git_credential_local_test.go
  • tests/cli_e2e/apps/coverage.md
✅ Files skipped from review due to trivial changes (2)
  • skills/lark-apps/references/lark-apps-git-credential.md
  • tests/cli_e2e/apps/coverage.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • shortcuts/apps/apps_create_test.go
  • shortcuts/apps/storage.go

Comment thread shortcuts/apps/git_credential.go Outdated
Comment thread shortcuts/apps/gitcred/gitconfig.go Outdated
Comment thread shortcuts/apps/gitcred/helper.go Outdated
Comment thread shortcuts/apps/gitcred/helper.go
Comment thread shortcuts/apps/gitcred/keychain.go Outdated
Comment thread shortcuts/apps/gitcred/store.go
Comment thread shortcuts/apps/gitcred/url.go Outdated
Comment thread tests/cli_e2e/apps/apps_git_credential_local_test.go Outdated
wangjiangwen-gif and others added 14 commits June 2, 2026 19:57
…ws (#3)

Reframe lark-apps from an HTML-publish skill into a full Miaoda app dev
tool covering three paths: local fullstack dev, HTML hosting, and cloud
session dev. Builds on the fullstack create change already on this branch.

- SKILL.md: 3-path routing table; mental models (code via native git,
  develop/main branch model, DB via +db-* through Miaoda, env auto-pulled
  by `npm dev run`, auto-managed credentials); command index for the new
  verbs; ambiguous-input fallback (infer app type from need, ask local vs
  cloud instead of assuming; default HTML when no signal)
- add local-dev and cloud-dev playbooks
- create: keep HTML/fullstack + required --message; add local/cloud scene
  routing and --enable-multi-env-db
- list: usable by agents with --filter; app_id resolution order
  (user-provided / .spark/meta.json / +list --filter)

Co-authored-by: wangjiangwen-gif <286006750+wangjiangwen-gif@users.noreply.github.com>
Co-authored-by: raistlin042 <lvxinsheng@bytedance.com>
…dev-init)

妙搭 data CLI 4 条命令,复用存量 OpenAPI URL + 1 个新增 dev-init:
- +db-table-list  → GET /apps/{id}/tables(游标分页,AppTable 含预估行数/占用空间)
- +db-table-schema → GET /apps/{id}/tables/{name}(默认结构化 schema;--format pretty 出建表 DDL)
- +db-sql         → POST /apps/{id}/sql_commands(?transactional=false DBA 模式)
- +db-dev-init    → POST /apps/{id}/db_dev_init(单库→online/dev,不可逆,high-risk-write)

要点:
- sql result 兼容两种 wire 形态(结构化 [{sql_type,data,record_count}] 与 legacy ["rows-json"])
- 多语句失败:server 返 code:0 + ERROR 哨兵,CLI 升级成 typed api_error(exit 非 0),
  detail 带 statement_index/completed/rolled_back,防止 agent 误判 ok:true 假成功
- pretty 渲染对齐 miaoda:列间两空格、CJK 双宽、size 友好格式(KB/MB/GB)
- 单测 + e2e dry-run 全覆盖;BOE 真机 e2e 验证通过(25 PASS)
- SKILL.md 注册 4 条命令 + 4 篇 reference

注:内含的 BOE 联调专用 env 覆盖(LARK_CLI_OPEN_API_BASE / LARK_CLI_X_TT_ENV,
internal/cmdutil + internal/envvars)未包含在本次提交,仅本地联调用。

Change-Id: I0fe4458086708a93941e2dee852fa6a10b53bd4a
…aoda-db-cli

Change-Id: Ib6c3eebd13070ed3050e130af6f3e0ed986d2f57
按 skill 质量规范(description 三段式 WHAT+WHEN+NOT,加载前唯一可见信息),
原 WHEN 仅"连数据库调试"含糊覆盖 db。补成「查看或操作应用数据库(看表结构 /
跑 SQL / 初始化 dev 环境)」,让 +db-table-schema / +db-sql / +db-dev-init
类查询能精确触发,净增 ~12 字无膨胀。

Change-Id: Id52819fa7d6b8ed0c1f174bf5946d55da7b893d7
feat(apps): 妙搭 data CLI 4 条 db 命令
* feat: add apps env-pull shortcut

* fix: support array env_vars response in apps env-pull

* fix(apps): improve env-pull merge and expiry output
* feat: switch apps +create --app-type enum to lowercase html/full_stack

* feat: add keyword/scope/app-type query to apps +list and unhide it

* docs: document apps +list query params and lowercase app_type enum

* test: update apps cli_e2e dry-run tests for lowercase app_type and +list filters

* docs: trim redundant app_type case-sensitivity note in create skill

* docs: single-source apps +list usage contract to SKILL.md
)

* feat: add apps publish shared guard and NodeStatus mapping

* test: cover json.Number path in injectStatusName

* feat: add apps +publish shortcut

Implements the `apps +publish` command with dry-run preview (upstream
PSM path shown) and an Execute gated by ensurePublishWired() per the
not-yet-deployed OpenAPI gateway constraint (publishAPIWired=false).

* refactor: make apps publish path placeholders var to satisfy go vet

Declare the four publishXxxPath constants as var instead of const so
go vet's printf analyzer skips them while they are empty placeholders.
Revert the Execute path-build in apps_publish.go from strings.Replace
back to fmt.Sprintf (now safe because the format string is a var).

* feat: add apps +publish-history shortcut

* feat: add apps +publish-status shortcut

* feat: add apps +publish-error-log shortcut

* feat: register apps publish shortcuts

Add AppsPublish, AppsPublishHistory, AppsPublishStatus, AppsPublishErrorLog
to Shortcuts() and update count test from 6 → 10.

* docs: add skill references for apps publish shortcuts

* docs: surface apps publish shortcuts in lark-apps SKILL.md

* docs: clarify publish instance id is not an approval instance

* docs: nudge agent to run apps +publish --dry-run for release requests

* feat: update apps publish shortcuts to v1.0.381 release protocol

Rename concept instance→release across all 4 publish shortcuts and their
tests: NodeStatus→ReleaseStatus enum, --instance-id→--release-id flag,
pipelineTaskID→releaseID response field, errorJobs→errorLogs, and
upstream HTTP path consts→RPC method name consts (PSM lark.apaas.devops
v1.0.381). Dry-run now shows psm+rpc_method instead of an HTTP path.

* docs: update apps publish skill docs to v1.0.381 release protocol

* fix: soften apps publish unavailable hint to user-facing language

* feat: update apps publish to v1.0.385 string status + --status filter

- Remove obsolete int-enum machinery (releaseStatusName/toInt/injectStatusName)
  and their encoding/json + fmt imports from apps_publish_common.go
- +publish Execute now returns status string alongside release_id
- +publish-history gains --status Enum flag (publishing/finished/failed);
  buildHistoryBody gains status param, table column status_name→status
- +publish-status Execute drops injectStatusName, pretty prints out["status"]
- +publish-error-log shapeErrorLog is string passthrough (no status_name)
- Unit tests updated: delete 3 obsolete common tests, update history/error-log

* docs: update apps publish docs to v1.0.385 string status + --status filter

* feat: wire apps publish shortcuts to final gateway paths (guard stays until deploy)

Replace RPC-name placeholders with real OpenAPI paths (publishCreate/Get/ErrorLog/ListPath consts). Switch DryRun to idiomatic HTTP form (POST/GET + real URL + body/params). Fix body/query placement: publish body has no app_id (path-only); history switches from POST body to GET query with snake page_token. Fix Execute response reads to snake_case fields (release_id, created_at, updated_at, error_logs). publishAPIWired stays false; 1-line flip activates live calls.

* docs: update apps publish docs to final gateway paths

Replace RPC/PSM dry-run example with real HTTP form (POST/GET /open-apis/spark/v1/apps/:app_id/releases[/:release_id[/error_logs]]).
Fix all response field names to snake_case (release_id, created_at, updated_at, error_log).
Note --status/--limit/--page-token as HTTP query params in publish-history.

* feat: enable apps publish gateway calls (remove not-deployed guard)

* docs: remove not-deployed transition notes from apps publish docs

* feat: use spark:app:publish scope for apps +publish
* feat(apps): add command runner and credential redaction for +init

* fix(apps): make credential redaction scheme matching case-insensitive

* feat(apps): add +init shortcut declaration, validation, and dry-run

* feat(apps): implement +init orchestration (credential-init, clone, checkout, conditional push)

* fix(apps): redact full userinfo when repo URL contains literal @

* docs(apps): add +init skill reference

* fix(apps): declare explicit empty Scopes on +init shortcut

* fix(apps): consume repository_url from +git-credential-init in +init

* feat(apps): add +init template flag and absolute-path dir resolution

* refactor(apps): use shared charcheck for +init --dir validation

* feat(apps): add meta.json, steering, and empty-repo helpers for +init

* feat(apps): add +init npx scaffold orchestration (init/upgrade branches)

* feat(apps): wire +init scaffold, already-initialized short-circuit, npx dep check

* docs(apps): document +init npx scaffold, --template, --dir, already-initialized

* docs(apps): correct stale +git-credential-init unreleased note in +init ref

* fix(apps): reject all control chars in +init --dir

* feat(apps): add +init progress logging and optional --template resolver

* refactor(apps): inline constant in +init scaffold progress log

* docs(apps): document +init optional --template and stderr progress contract

* feat(apps): treat README-only repo as empty and commit with --no-verify in +init

* docs(apps): explain README-seed match and --no-verify rationale in +init

* docs(apps): document README-seed empty detection and commit --no-verify
* feat(apps): add +session-create shortcut

* fix(apps): remove unused sessionPath helper, assert empty +session-create body

* feat(apps): add +session-list shortcut

* feat(apps): add +session-read shortcut

* feat(apps): add +session-stop shortcut

* feat(apps): add +chat shortcut

* feat(apps): register session lifecycle shortcuts

* docs(apps): add session conversation skill reference

* docs(apps): clarify fullstack session_id source and fallback

* style(apps): gofmt apps_session_create.go

* docs(apps): add conversation/session triggers to skill routing description

* docs(apps): add conversation flow guidance (when to reuse vs new session, per-step user prompts)

* docs(apps): slim session reference per skill quality standard (4047->1726 tok)

* docs(apps): tighten session additions in SKILL.md (4394->4145 tok)

* fix(apps): align +chat with v7.8 contract (async, no turn_id in response)

* fix(apps): update +chat path to .../sessions/{id}/chat (backend endpoint change)

* docs(apps): align SKILL.md session command shape with v7.8 contract
Go 1.19+ gofmt 文档注释列表缩进新规则(普通缩进 → tab 对齐),
修复 fast-gate CI 的 gofmt 卡点。

Change-Id: Ic246a659e016d9d6216182199ef300ae6f00ef9d
…#14)

* refactor(apps): plainer +init progress/help wording, keep scaffold key

* refactor(apps): add porcelain change classifier for +init commit split

* feat(apps): split +init empty-repo commit into code + config, reword subjects

* refactor(apps): scaffold-kind constants and pathspec assertions for +init split

* docs(apps): use +init in Path A; align app-repo branch to sprint/default

* docs(apps): align local-dev playbook to sprint/default + origin remote

* docs(apps): document +init two-commit split and plainer init wording

* docs(apps): require asking clone dir before +init, no assumed path

* fix(apps): stage +init commits by exact paths to avoid gitignore error

* refactor(apps): lowercase miaoda in +init commit subjects

* test(apps): cover +init upgrade path with real git
chenxingyang1019 and others added 26 commits June 9, 2026 20:24
+db-sql 可含 DML/DDL,统一升级为 high-risk-write:框架对所有执行强制 --yes 确认关卡
(--dry-run 预览豁免),无 --yes 返 confirmation_required / exit 10。
- Risk: write → high-risk-write(去掉自定义门禁,直接用框架机制)
- skill 文档:命令骨架标注 --yes 要求;Agent 规则改为「执行需 --yes,只读可直接带、
  破坏性先 dry-run 确认再带」
- 单测所有执行调用补 --yes

Change-Id: I57e78832b35fa170a485774e6fb7289109d678c3
refactor(apps): rename +db-dev-init→+db-env-create, trim db-table-list columns
Co-authored-by: fushengdong.1 <fushengdong.1@bytedance.com>
* refactor(apps): drop +publish-error-log, rename release path constants

* refactor(apps): rename +publish to +release-create

* refactor(apps): rename +publish-history to +release-list, unify pagination to --page-size

* refactor(apps): rename +publish-status to +release-get

Renames apps +publish-status → +release-get (AppsPublishStatus → AppsReleaseGet),
updates --release-id desc to reference +release-create, and fixes the Execute
error hint to point at +release-list instead of +publish-history.

* refactor(apps): rename +session-read to +session-get

* docs(apps): rename publish references to release, +session-read to +session-get

* refactor(apps): clean up residual publish/session-read references

Fix six leftover references missed in Tasks 1-6: +publish-history in
jq-tip test wantCmds map and common_test hint fixture (×3), +session-read
in apps_chat.go comment+output string (×2), apps_session_stop.go flag
desc (×1), apps_chat_test.go comment (×1), and +publish-status in
lark-apps-list.md agent rule prose (×1).

* docs(apps): clarify release-get link contract and session-get vs session-list

* docs(apps): generalize release-list page-size rule to N records
* feat(apps): rename +list --scope flag to --ownership

* test(apps): update +list cli_e2e dry-run for --ownership rename

* docs(apps): document +list --ownership flag
* feat(apps): align +release-create scope to spark:app:write

* feat(apps): raise +release-list --page-size documented max to 500

* feat(apps): show commit_id in +release-get pretty output

* docs(apps): update release reference docs for page-size 500 and commit_id

* test(apps): cover empty commit_id in +release-get pretty output
docs: align lark apps cloud dev release flow
… dev)

按 db 子域命令最终设计重做执行入口:
- 命令 +db-sql → +db-execute(动词收尾,对齐 +db-table-list/-get)
- --query 拆为 --sql(内联/stdin)与 --file(.sql 文件路径),二选一互斥;
  --file 在 Validate 阶段读出归一化到 --sql
- 默认 --env online → dev(打生产库需显式 --env online)
- 文件/标识符/注册/测试/cli_e2e/skill 文档全部对齐重命名
- 新增测试:--sql/--file 互斥、--file 读取、默认 env=dev

不在本次范围:--transaction/--no-transaction(服务端 transactional 实为路径切换、
非真事务,需 dataloom 侧先支持真事务开关)、--max-rows/--timeout 等后续项。

Change-Id: I50c06faf83527471446e2a6651ccb51f6eedd6ff
把口语化的「打生产库需显式」改为「需要操作线上环境数据库时,显式指定 --env online」;
flag desc 同步去掉 hit production 措辞。

Change-Id: Iee82fccf17e08bddb4b760c3970a416746b10c4c
中文文档/英文 description 去掉术语 ad-hoc;SELECT/DML/DDL 已表意,含义不丢。

Change-Id: Ie2cccc5fc3491fe5f57190a87b93ecd70405b156
- 何时用去掉「(查询 / 临时数据修复 / 应急 DDL)」枚举
- --file 路径说明去掉 .. /符号链接/统一约束 的技术化描述,改为「相对路径,
  否则用 --sql - < 文件路径」的产品化口吻

Change-Id: Ie70e57895c78650230b6942b03d90a2d95c937f2
简短补回 --file 的路径约束(绝对路径 / 经 ..、符号链接越界会被拒),去掉冗余评注。

Change-Id: I549893c82cafbe97529e08dcbc3ee5496927da18
feat(apps): redesign +db-sql → +db-execute (--sql/--file, default env dev)
…compat)

t.Chdir 是 Go 1.24 API,但 go.mod 为 go 1.23.0,CI(Go 1.23)报
"t.Chdir undefined"。改用 os.Chdir + t.Cleanup 还原,1.23 兼容。

Change-Id: I550611773e5088275be1c4344d4f8269610ce74a
fix(apps): db-execute test t.Chdir → os.Chdir (Go 1.23 CI fix)
原实现用 string + Enum["true","false"] + == "true" 模拟 bool,啰嗦且非惯用。
改为 Type:bool(rctx.Bool):传 --sync-data 即开启、省略为 false。
同步更新测试、cli_e2e dry-run、skill 文档。

Change-Id: I3068e0577fa20a7cbaf414ca9af3d197f6ae8049
refactor(apps): +db-env-create --sync-data → Type:bool
* docs(apps): front-load intent-routing table and dedupe skill body

* docs(apps): dedupe publish guardrail and polling rules in cloud-dev

* docs(apps): trim env-pull implementation detail to behavior contract

* docs(apps): add +env-pull routing entry in SKILL.md

* docs(apps): fix create.md cross-ref to actual SKILL.md section name
…#57)

* feat(apps): add appIDListHint const and wrap 4 pure app-id command failure paths

Adds shared `appIDListHint` recovery hint to common.go and wraps the
CallAPITyped failure branch of session-create, session-list, update, and
release-list to surface an actionable next-step hint on 4xx errors.
Includes httpmock unit tests in apps_hints_more_test.go (TDD: red→green).

* feat(apps): add sessionStopHint and createHint for session-stop and create commands

Adds per-command recovery hints with specific guidance: sessionStopHint
points at +session-list and +session-get; createHint explains valid
--app-type values and permission failure. Wraps the CallAPITyped failure
branch in both commands.

* feat(apps): add recovery hints for db-env-create, db-table-get, db-table-list

Adds dbEnvCreateHint, dbTableGetHint, and dbTableListHint with actionable
cross-command guidance (e.g. pointing at +db-table-list for env conflicts,
+db-env-create for missing dev env). Wraps only the CallAPITyped failure
branch; requireAppID validation errors are left untouched.

* refactor(apps): make session-stop hint runnable and align hint test names

* test(apps): guard withAppsHint upstream-wins contract and new hint leak safety

* test(apps): add help-skill command consistency gate
@raistlin042 raistlin042 merged commit 2c703f2 into larksuite:main Jun 10, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants