Skip to content

feat(apps): support modern_html app type with TOS publish path and app type querying - #1762

Merged
anngo-nk merged 48 commits into
mainfrom
feat/doubao-miaoda-integration
Jul 13, 2026
Merged

feat(apps): support modern_html app type with TOS publish path and app type querying#1762
anngo-nk merged 48 commits into
mainfrom
feat/doubao-miaoda-integration

Conversation

@anngo-nk

@anngo-nk anngo-nk commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Support modern_html app type for the doubao agent HTML publish workflow. Adds app type querying, conditional init behavior, and a TOS-based publish path alongside the existing multipart flow.

Changes

New commands

  • +get: Fetch single app detail by app_id (app_type, name, description, publish status, etc.)

+create

  • Read LARKSUITE_CLI_AGENT_NAME env var via envvars.AgentName() and pass as source_agent in request body

+init

  • Query app type via GET /apps/{id} (queryAppType) to determine init behavior
  • Introduce appTypePolicy for per-type control: skipInstall, skipEnvPull, skipSkillsSync
  • modern_html apps skip dependency install, env-pull, and skills sync
  • Pass --app-type <type> to miaoda-cli instead of --template
  • Add --source-path flag for incorporating existing HTML source files
  • Validate --source-path with filepath.Abs and control character rejection
  • Ensure default git identity (user.name/email) when missing
  • Add ConditionalScopes: ["spark:app:read"] for the queryAppType call
  • Use npmmirror registry for npx

+html-publish

  • Query app type; route by result:
    • modern_html: tar.gz → pre_release API (GET KV list) → TOS presigned PUT upload → internal release-create → return release_id
    • Other (including legacy html): existing multipart tar.gz flow → return url
  • Extract shared prepareHTMLPublishTarball to deduplicate validation+packaging
  • Add spark:app:read to scopes

+release-create

  • Surface sync field in response output

Shared

  • queryAppType in apps_meta.go: GET /apps/{id}, parse appInfo struct, normalize to lowercase, stderr warning on failure
  • Skill docs updated for +get, +html-publish output contract, SKILL.md intent routing

Test Plan

  • +create: env var set / empty / unset for source_agent
  • +get: success, missing app-id, empty app-id, dry-run, pretty output
  • +init: modern_html skips env-pull (fresh + already-initialized), full_stack passes template, explicit template override, nil meta fallback, appTypePolicy unit tests, scaffoldInitArgs with/without skip-install
  • +html-publish TOS path: success with httptest server, missing index.html, pre_release error, missing/empty kvs, upload failure
  • +release-create: sync field, buildPublishBody
  • queryAppType: success (HTML/FULL_STACK/MODERN_HTML), API error, missing app object, empty app_type
  • Full build go build ./... and full unit tests pass

Related Issues

  • Depends on server-side GET /apps/{id} endpoint and GET /apps/{id}/pre_release endpoint

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 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

This PR adds an environment-variable-derived source_agent field to app creation requests, introduces a queryAppType lookup for app metadata, and refactors init/scaffold template selection and output shaping to use the queried app type.

Changes

App creation and init flow updates

Layer / File(s) Summary
source_agent env var in apps create
shortcuts/apps/apps_create.go, shortcuts/apps/apps_create_test.go
Reads LARKSUITE_CLI_AGENT and conditionally adds source_agent to the create request body; new tests cover set, empty, and unset env var scenarios.
queryAppType metadata helper
shortcuts/apps/apps_meta.go, shortcuts/apps/apps_meta_test.go
Adds queryAppType, a typed GET call to fetch app_type, normalize it to lowercase, and return an empty string on failure or missing data; tests cover success and error cases.
Init/scaffold template resolution driven by appType
shortcuts/apps/apps_init.go, shortcuts/apps/apps_init_test.go
resolveTemplate now takes appType; runScaffold/scaffoldInitArgs select --template by precedence and support --source-path; appsInitExecute queries appType early and updates output envelopes; tests cover updated signatures and scaffold argument composition.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • larksuite/cli#1517 — Also changes shortcuts/apps/apps_init.go control flow around initialized app directories and appsInitExecute.

Suggested labels: feature

Suggested reviewers: liangshuo-1

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly summarizes the main change: modern_html support, TOS publish path, and app type querying.
Description check ✅ Passed The description follows the required template with Summary, Changes, Test Plan, and Related Issues sections and covers the main scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/doubao-miaoda-integration

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.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.80645% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.58%. Comparing base (f495cbb) to head (d33d594).
⚠️ Report is 21 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/apps/apps_html_publish.go 67.18% 16 Missing and 5 partials ⚠️
shortcuts/apps/apps_init.go 75.32% 14 Missing and 5 partials ⚠️
shortcuts/apps/apps_get.go 85.18% 2 Missing and 2 partials ⚠️
shortcuts/apps/apps_release_create.go 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1762      +/-   ##
==========================================
+ Coverage   74.40%   74.58%   +0.17%     
==========================================
  Files         860      863       +3     
  Lines       89215    90123     +908     
==========================================
+ Hits        66384    67220     +836     
+ Misses      17701    17696       -5     
- Partials     5130     5207      +77     

☔ 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 Jul 6, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/doubao-miaoda-integration -y -g

@anngo-nk anngo-nk changed the title feat(apps): support doubao-html app type with TOS upload path feat(apps): route init and html-publish by arch_type Jul 6, 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: 7

🧹 Nitpick comments (5)
shortcuts/apps/apps_meta.go (1)

25-30: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Remove the unused ctx parameter queryAppMeta never reads its context.Context, and rctx.CallAPITyped already uses RuntimeContext.ctx, so the extra parameter and call-site plumbing can be dropped.

🤖 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_meta.go` around lines 25 - 30, Remove the unused context
parameter from queryAppMeta and update its callers accordingly. The function
currently never reads ctx, and rctx.CallAPITyped already relies on
RuntimeContext.ctx, so simplify the signature of queryAppMeta and drop the extra
call-site plumbing wherever queryAppMeta is invoked.
shortcuts/apps/apps_init.go (1)

88-98: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Drop the unused meta branches from resolveTemplate, or pass app meta into DryRun if the preview should match execute-time selection. resolveTemplate only receives nil today, so the AppType/ArchType cases never run; the dry-run scaffold string stays generic instead of reflecting the meta-aware app init behavior.

🤖 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_init.go` around lines 88 - 98, The DryRun preview in
apps_init.go is not using the meta-aware template selection path, so the
scaffold description can diverge from what execute-time initialization does.
Update the DryRun closure that builds the common.NewDryRunAPI preview to either
pass the app meta into resolveTemplate or remove the unused AppType/ArchType
branches from resolveTemplate if meta is intentionally unavailable; make sure
the values used by Set("template", ...) and the scaffold string reflect the same
selection logic as the real app init flow.
shortcuts/apps/apps_html_publish.go (2)

281-343: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

pollDeployStatus bypasses the appsHTMLPublishTOSClient interface.

runHTMLPublishTOS takes both a tosClient interface and a raw *common.RuntimeContext solely to call pollDeployStatus directly, breaking the abstraction the interface exists for. This is why tests pass nil for rctx and none exercise the polling branch — doing so with nil would panic. Consider adding a PollStatus(ctx, appID, releaseID) (*deployResponse, error) method to appsHTMLPublishTOSClient so the whole flow is mockable and testable through one seam.

🤖 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_html_publish.go` around lines 281 - 343, The polling path
in runHTMLPublishTOS is bypassing the appsHTMLPublishTOSClient abstraction by
calling pollDeployStatus with a raw *common.RuntimeContext. Add a
PollStatus(ctx, appID, releaseID) method to appsHTMLPublishTOSClient and move
the polling call behind that interface so runHTMLPublishTOS uses only tosClient.
Update the mock/test implementations to cover the building/finished branch
through the same seam and remove the need for passing nil rctx just to avoid the
direct pollDeployStatus call.

128-140: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Output schema diverges between legacy and TOS publish paths.

The legacy path exposes out["url"], while the TOS path exposes out["online_url"]/out["release_id"] for the same +html-publish command (which has HasFormat: true). Scripts parsing structured output for a stable url/status field will silently break depending on the app's internal arch_type, which the caller has no way to predict.

Also applies to: 281-343

🤖 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_html_publish.go` around lines 128 - 140, The
`+html-publish` command is returning different structured fields in the legacy
and TOS paths, so normalize the output schema in `apps_html_publish.go` and the
shared publish flow used by `runHTMLPublishTOS`/legacy handling. Make both paths
expose the same stable fields for `url` and build state (for example, a
consistent URL plus status/release identifier), and update the `rctx.OutFormat`
callback to emit that unified schema regardless of `arch_type`. This should be
applied in the TOS branch here and in the corresponding legacy code path around
the referenced publish logic.
shortcuts/apps/html_publish_tos_client_test.go (1)

1-197: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for the "building" + polling branch.

No test drives deployResponse{Status: "building", ReleaseID: ...} through runHTMLPublishTOS, so pollDeployStatus's interaction and the resulting output fields (status/online_url/release_id/hint) are untested. This gap would have caught the status-masking issue flagged in apps_html_publish.go (a poll timeout/failure being reported as "building" instead of "failed"). Note pollDeployStatus is called directly on rctx (not through the appsHTMLPublishTOSClient interface), so testing this branch requires a real *common.RuntimeContext rather than nil.

🤖 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/html_publish_tos_client_test.go` around lines 1 - 197, Add
test coverage for the building/polling path in runHTMLPublishTOS by using a real
common.RuntimeContext and a fake TOS client that returns deployResponse with
Status set to "building" and a ReleaseID. Verify the branch exercises
pollDeployStatus and asserts the final output fields status, online_url,
release_id, and hint, so the behavior in appsHTMLPublishTOSClient and
pollDeployStatus is covered. Also include a case where polling fails or times
out to ensure the status is reported as failed rather than being left as
building.
🤖 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/apps_html_publish.go`:
- Around line 324-341: The publish flow in apps_html_publish.go is treating
every non-success poll as “still building”; update the logic around
pollDeployStatus in the app publish response assembly so failed polls and
polled.Status == "failed" are surfaced as failures instead of falling through to
the release_id/hint branch. In the block that builds out for spec.AppID and
resp.ReleaseID, branch on pollErr and the returned polled.Status explicitly,
preserve the actual error/status in out, and only keep the current “finished”
path when pollDeployStatus succeeds with polled.Status == "finished".
- Around line 122-142: queryAppMeta is swallowing API/parsing failures by
returning nil, which causes the doubao-html branch in appsHTMLPublish to
silently fall back to the legacy multipart path. Update queryAppMeta to return
an error (or a typed result) for lookup failures, and change the caller in
appsHTMLPublish to only use the legacy multipart path on an explicit legacy
response, not on transient errors; keep the special-case routing for
meta.AppType and meta.ArchType intact.

In `@shortcuts/apps/apps_init_test.go`:
- Around line 1649-1728: Add a test covering runScaffold/scaffoldInitArgs when
meta is non-nil but AppType is not 7, since current coverage only checks static
HTML, doubao-html, nil meta, and explicit template override. Create a case in
TestRunScaffold_* that uses a regular app meta with a non-HTML AppType and
verifies the npx args choose the expected template/flags behavior. Use
runScaffold and the scaffoldInitArgs behavior to confirm whether
--app-type/--arch-type should be omitted or included for this non-HTML metadata
path.

In `@shortcuts/apps/html_publish_tos_client.go`:
- Around line 86-108: The polling loop in pollDeployStatus ignores context
cancellation because it uses time.Sleep directly. Update pollDeployStatus to
respect ctx.Done() during each poll interval by waiting on a select between a
timer and ctx.Done(), and return promptly when the context is cancelled. Keep
the existing CallAPITyped/status handling intact while making the loop exit
early on cancellation.
- Around line 57-66: The TOS upload path currently uses
http.DefaultClient.Do(req), which can block indefinitely if the request context
has no deadline. Update the upload logic around the existing request creation
and Do call to use a client with an explicit timeout or ensure the request
context is always given a deadline before calling Do. Keep the same error
handling via appsExternalToolError and preserve the current status-code check
and response closing behavior.
- Around line 34-49: The TOS upload path in GetUploadURL and the surrounding
upload flow currently classifies request construction, Do failures, and non-2xx
responses as file I/O or external tool errors, which is the wrong subtype for
transport/server failures. Update the error wrapping in the
appsHTMLPublishTOSAPI path to use the network error subtype for
http.NewRequestWithContext, client.Do, and response-status failures so callers
can treat these as retryable network issues consistently.

In `@shortcuts/apps/html_publish_zip_test.go`:
- Around line 99-113: The error-path tests for writeHTMLPublishZipEntry
currently validate only error text, so update
TestWriteHTMLPublishZipEntry_OpenFailure,
TestWriteHTMLPublishZipEntry_CopyFailure, and
TestWriteHTMLPublishZipEntry_RejectsPathTraversal to assert typed metadata with
errs.ProblemOf instead of strings.Contains. Check the returned error for the
expected category/subtype/param values, and also verify the underlying cause is
preserved where applicable. Use the writeHTMLPublishZipEntry helper and the
htmlPublishCandidate fields to keep the assertions aligned with the specific
failure mode being exercised.

---

Nitpick comments:
In `@shortcuts/apps/apps_html_publish.go`:
- Around line 281-343: The polling path in runHTMLPublishTOS is bypassing the
appsHTMLPublishTOSClient abstraction by calling pollDeployStatus with a raw
*common.RuntimeContext. Add a PollStatus(ctx, appID, releaseID) method to
appsHTMLPublishTOSClient and move the polling call behind that interface so
runHTMLPublishTOS uses only tosClient. Update the mock/test implementations to
cover the building/finished branch through the same seam and remove the need for
passing nil rctx just to avoid the direct pollDeployStatus call.
- Around line 128-140: The `+html-publish` command is returning different
structured fields in the legacy and TOS paths, so normalize the output schema in
`apps_html_publish.go` and the shared publish flow used by
`runHTMLPublishTOS`/legacy handling. Make both paths expose the same stable
fields for `url` and build state (for example, a consistent URL plus
status/release identifier), and update the `rctx.OutFormat` callback to emit
that unified schema regardless of `arch_type`. This should be applied in the TOS
branch here and in the corresponding legacy code path around the referenced
publish logic.

In `@shortcuts/apps/apps_init.go`:
- Around line 88-98: The DryRun preview in apps_init.go is not using the
meta-aware template selection path, so the scaffold description can diverge from
what execute-time initialization does. Update the DryRun closure that builds the
common.NewDryRunAPI preview to either pass the app meta into resolveTemplate or
remove the unused AppType/ArchType branches from resolveTemplate if meta is
intentionally unavailable; make sure the values used by Set("template", ...) and
the scaffold string reflect the same selection logic as the real app init flow.

In `@shortcuts/apps/apps_meta.go`:
- Around line 25-30: Remove the unused context parameter from queryAppMeta and
update its callers accordingly. The function currently never reads ctx, and
rctx.CallAPITyped already relies on RuntimeContext.ctx, so simplify the
signature of queryAppMeta and drop the extra call-site plumbing wherever
queryAppMeta is invoked.

In `@shortcuts/apps/html_publish_tos_client_test.go`:
- Around line 1-197: Add test coverage for the building/polling path in
runHTMLPublishTOS by using a real common.RuntimeContext and a fake TOS client
that returns deployResponse with Status set to "building" and a ReleaseID.
Verify the branch exercises pollDeployStatus and asserts the final output fields
status, online_url, release_id, and hint, so the behavior in
appsHTMLPublishTOSClient and pollDeployStatus is covered. Also include a case
where polling fails or times out to ensure the status is reported as failed
rather than being left as building.
🪄 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: f79badbd-9f44-4be3-9c6a-eb9e0cc0db2c

📥 Commits

Reviewing files that changed from the base of the PR and between ee46e22 and 1625a9d.

📒 Files selected for processing (11)
  • shortcuts/apps/apps_create.go
  • shortcuts/apps/apps_create_test.go
  • shortcuts/apps/apps_html_publish.go
  • shortcuts/apps/apps_init.go
  • shortcuts/apps/apps_init_test.go
  • shortcuts/apps/apps_meta.go
  • shortcuts/apps/apps_meta_test.go
  • shortcuts/apps/html_publish_tos_client.go
  • shortcuts/apps/html_publish_tos_client_test.go
  • shortcuts/apps/html_publish_zip.go
  • shortcuts/apps/html_publish_zip_test.go

Comment thread shortcuts/apps/apps_html_publish.go Outdated
Comment thread shortcuts/apps/apps_html_publish.go Outdated
Comment thread shortcuts/apps/apps_init_test.go Outdated
Comment thread shortcuts/apps/html_publish_tos_client.go Outdated
Comment thread shortcuts/apps/html_publish_tos_client.go Outdated
Comment thread shortcuts/apps/html_publish_tos_client.go Outdated
Comment thread shortcuts/apps/html_publish_zip_test.go Outdated
@anngo-nk
anngo-nk force-pushed the feat/doubao-miaoda-integration branch from 1625a9d to 13a24b7 Compare July 6, 2026 11:13
@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 Jul 7, 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.

Caution

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

⚠️ Outside diff range comments (1)
shortcuts/apps/apps_create_test.go (1)

337-364: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Test relies on ambient env, not explicit unset.

TestAppsCreate_AgentEnvVarNotSet never unsets LARKSUITE_CLI_AGENT; it only relies on the variable being absent from the process environment. If it happens to be exported in a developer's shell or CI runner (plausible, given it's meant to identify calling agents), this test becomes flaky/order-dependent instead of deterministically exercising the "unset" branch.

Explicitly unset the var (with restore) to guarantee test isolation:

🔧 Proposed fix
 func TestAppsCreate_AgentEnvVarNotSet(t *testing.T) {
+	if prev, ok := os.LookupEnv("LARKSUITE_CLI_AGENT"); ok {
+		os.Unsetenv("LARKSUITE_CLI_AGENT")
+		t.Cleanup(func() { os.Setenv("LARKSUITE_CLI_AGENT", prev) })
+	}
 	factory, stdout, reg := newAppsExecuteFactory(t)
🤖 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_test.go` around lines 337 - 364,
TestAppsCreate_AgentEnvVarNotSet is relying on the ambient process environment
instead of explicitly exercising the unset case. Update this test to temporarily
clear LARKSUITE_CLI_AGENT before calling runAppsShortcut, and restore the
original value afterward so the behavior is deterministic and isolated. Keep the
existing assertions against the captured request body in the same test.
🧹 Nitpick comments (2)
shortcuts/apps/apps_create_test.go (1)

277-364: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider table-driven consolidation.

The three tests share nearly identical setup/execute/decode logic, differing only in the env var value and assertion. A table-driven test would reduce duplication.

🤖 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_test.go` around lines 277 - 364, Consolidate
TestAppsCreate_WithAgentEnvVar, TestAppsCreate_WithoutAgentEnvVar, and
TestAppsCreate_AgentEnvVarNotSet into a table-driven test because they repeat
the same setup, runAppsShortcut execution, and JSON decoding logic. Keep the
shared flow in one loop, vary only the LARKSUITE_CLI_AGENT value and the
expected source_agent assertion, and reuse newAppsExecuteFactory,
runAppsShortcut, and the stub registration to reduce duplication.
shortcuts/apps/apps_init.go (1)

127-137: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

resolveTemplate and scaffoldInitArgs duplicate the same precedence logic.

Both implement identical "explicit template → appType → defaultTemplate" resolution independently. resolveTemplate is only exercised by DryRun (Line 89); the real Execute path bypasses it and reimplements the same three-way branching inside scaffoldInitArgs. If the precedence or trimming rules change in one place, dry-run output and actual scaffold behavior can silently diverge.

Consider having scaffoldInitArgs accept a single already-resolved template string (computed once via resolveTemplate-equivalent logic) instead of re-deriving it from appType/explicitTemplate.

♻️ Proposed consolidation
-func scaffoldInitArgs(appType, appID, explicitTemplate string) []string {
-	base := []string{"-y", "--prefer-online", miaodaCLIPkg, "app", "init"}
-	if explicitTemplate != "" {
-		return append(base, "--template", explicitTemplate, "--app-id", appID)
-	}
-	if appType != "" {
-		return append(base, "--template", appType, "--app-id", appID)
-	}
-	return append(base, "--template", defaultTemplate, "--app-id", appID)
-}
+func scaffoldInitArgs(appID, resolvedTemplate string) []string {
+	base := []string{"-y", "--prefer-online", miaodaCLIPkg, "app", "init"}
+	return append(base, "--template", resolvedTemplate, "--app-id", appID)
+}

Then compute resolvedTemplate once (e.g. via a shared helper mirroring resolveTemplate's precedence) and pass it into both runScaffold/scaffoldInitArgs and the dry-run path.

Also applies to: 355-368

🤖 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_init.go` around lines 127 - 137, `resolveTemplate` and
`scaffoldInitArgs` currently duplicate the same template precedence logic, which
can cause DryRun and Execute to drift. Refactor the
`runScaffold`/`scaffoldInitArgs` flow so the template is resolved once using the
existing `resolveTemplate` precedence (explicit template, then appType, then
defaultTemplate), and pass that single resolved value into both the dry-run and
real scaffold paths. Keep `resolveTemplate` as the single source of truth and
remove the re-derivation from `scaffoldInitArgs`.
🤖 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.

Outside diff comments:
In `@shortcuts/apps/apps_create_test.go`:
- Around line 337-364: TestAppsCreate_AgentEnvVarNotSet is relying on the
ambient process environment instead of explicitly exercising the unset case.
Update this test to temporarily clear LARKSUITE_CLI_AGENT before calling
runAppsShortcut, and restore the original value afterward so the behavior is
deterministic and isolated. Keep the existing assertions against the captured
request body in the same test.

---

Nitpick comments:
In `@shortcuts/apps/apps_create_test.go`:
- Around line 277-364: Consolidate TestAppsCreate_WithAgentEnvVar,
TestAppsCreate_WithoutAgentEnvVar, and TestAppsCreate_AgentEnvVarNotSet into a
table-driven test because they repeat the same setup, runAppsShortcut execution,
and JSON decoding logic. Keep the shared flow in one loop, vary only the
LARKSUITE_CLI_AGENT value and the expected source_agent assertion, and reuse
newAppsExecuteFactory, runAppsShortcut, and the stub registration to reduce
duplication.

In `@shortcuts/apps/apps_init.go`:
- Around line 127-137: `resolveTemplate` and `scaffoldInitArgs` currently
duplicate the same template precedence logic, which can cause DryRun and Execute
to drift. Refactor the `runScaffold`/`scaffoldInitArgs` flow so the template is
resolved once using the existing `resolveTemplate` precedence (explicit
template, then appType, then defaultTemplate), and pass that single resolved
value into both the dry-run and real scaffold paths. Keep `resolveTemplate` as
the single source of truth and remove the re-derivation from `scaffoldInitArgs`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 853bb83e-4731-4ddf-8704-64f2d1ee1c17

📥 Commits

Reviewing files that changed from the base of the PR and between 13a24b7 and 0a8e879.

📒 Files selected for processing (6)
  • shortcuts/apps/apps_create.go
  • shortcuts/apps/apps_create_test.go
  • shortcuts/apps/apps_init.go
  • shortcuts/apps/apps_init_test.go
  • shortcuts/apps/apps_meta.go
  • shortcuts/apps/apps_meta_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/apps/apps_create.go

@anngo-nk
anngo-nk force-pushed the feat/doubao-miaoda-integration branch from db77bd6 to b16f1d3 Compare July 8, 2026 04:13
@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jul 8, 2026
@anngo-nk anngo-nk changed the title feat(apps): route init and html-publish by arch_type feat(apps): support modern_html app type with TOS publish path and app type querying Jul 13, 2026
liangshuo-1
liangshuo-1 previously approved these changes Jul 13, 2026
@anngo-nk
anngo-nk merged commit 1ab8530 into main Jul 13, 2026
24 checks passed
@anngo-nk
anngo-nk deleted the feat/doubao-miaoda-integration branch July 13, 2026 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants