@buaa_smat/hometrans 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +194 -136
  2. package/agents/build-fixer.md +38 -48
  3. package/agents/code-reviewer.md +20 -20
  4. package/agents/logic-coder.md +8 -8
  5. package/agents/logic-context-builder.md +5 -5
  6. package/agents/review-fixer.md +16 -16
  7. package/agents/self-test-fixer.md +15 -15
  8. package/agents/self-tester.md +56 -55
  9. package/agents/spec-generator.md +16 -16
  10. package/dist/cli/config-store.js +120 -9
  11. package/dist/cli/config.js +4 -4
  12. package/dist/cli/env-vars.js +129 -0
  13. package/dist/cli/init.js +315 -276
  14. package/dist/cli/uninstall.js +152 -17
  15. package/dist/context/index.js +10 -197
  16. package/env-requirements.json +181 -181
  17. package/package.json +1 -1
  18. package/resource/choose_editor.png +0 -0
  19. package/resource/common_config.png +0 -0
  20. package/resource/integration_test_config.png +0 -0
  21. package/resource/migration_process.svg +94 -0
  22. package/resource/migration_process_transparent.svg +93 -0
  23. package/resource/set_env.png +0 -0
  24. package/resource/ui_align_config.png +0 -0
  25. package/skills/hmos-batch-ui-align/SKILL.md +10 -0
  26. package/skills/hmos-batch-ui-align/references/conversion-procedure.md +180 -180
  27. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -2533
  28. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -555
  29. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -117
  30. package/skills/hmos-batch-ui-align/references/mvvm/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -648
  31. package/skills/hmos-batch-ui-align/references/mvvm/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2088 -2088
  32. package/skills/hmos-batch-ui-align/references/mvvm/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -1033
  33. package/skills/hmos-batch-ui-align/references/mvvm/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -1183
  34. package/skills/hmos-batch-ui-align/references/mvvm/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -576
  35. package/skills/hmos-batch-ui-align/references/mvvm/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -297
  36. package/skills/hmos-batch-ui-align/references/mvvm/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -395
  37. package/skills/hmos-batch-ui-align/references/mvvm/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +902 -902
  38. package/skills/hmos-batch-ui-align/references/mvvm/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -106
  39. package/skills/hmos-batch-ui-align/references/mvvm/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -1178
  40. package/skills/hmos-batch-ui-align/references/mvvm/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -911
  41. package/skills/hmos-batch-ui-align/references/mvvm/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +354 -354
  42. package/skills/hmos-batch-ui-align/references/mvvm//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -11
  43. package/skills/hmos-convert-pipeline/SKILL.md +63 -49
  44. package/skills/hmos-fix-build-errors/SKILL.md +5 -6
  45. package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +219 -219
  46. package/skills/hmos-fix-build-errors/references/known-patterns.md +157 -157
  47. package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +131 -131
  48. package/skills/hmos-incremental-ui-align/{readme.md → README.md} +28 -21
  49. package/skills/hmos-incremental-ui-align/SKILL.md +46 -27
  50. package/skills/hmos-incremental-ui-align/diff_analysis.md +52 -52
  51. package/skills/hmos-incremental-ui-align/page_align.md +62 -62
  52. package/skills/hmos-incremental-ui-align/references/Comparison_Template.md +2 -2
  53. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -648
  54. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2088 -2088
  55. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -1033
  56. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -1183
  57. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -576
  58. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -297
  59. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -395
  60. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +902 -902
  61. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -106
  62. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -1178
  63. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217V1.md +911 -911
  64. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +354 -354
  65. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -11
  66. package/skills/hmos-incremental-ui-align/references/UI_Analysis_Template.md +3 -3
  67. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -2533
  68. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -555
  69. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -117
  70. package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +37 -37
  71. package/skills/hmos-integration-test/{readme.md → README.md} +38 -38
  72. package/skills/hmos-integration-test/SKILL.md +63 -52
  73. package/skills/hmos-resources-convert/SKILL.md +5 -5
  74. package/skills/hmos-resources-convert/references/conversion-rules.md +663 -663
  75. package/skills/hmos-resources-convert/references/dependency-analysis-rules.md +388 -388
  76. package/skills/hmos-resources-convert/references/resource-mapping-rules.md +457 -457
  77. package/skills/hmos-resources-convert/references/xml-drawable-to-svg-rules.md +513 -513
  78. package/skills/hmos-spec-generate/SKILL.md +19 -19
  79. package/skills/hmos-spec-generate/references/android-platform-tokens.md +105 -105
  80. package/skills/hmos-spec-generate/references/spec-sample-1.md +78 -78
  81. package/skills/hmos-spec-generate/references/spec-sample-2.md +58 -58
  82. package/skills/hmos-spec-generate/references/spec-sample-3.md +116 -116
  83. package/skills/hmos-spec-generate/references/step4-report-template.md +33 -33
  84. package/tools/test-tools/autotest/README.md +33 -17
  85. package/tools/test-tools/autotest/self_test_runner.py +109 -15
  86. package/resource/hometrans_config.png +0 -0
  87. package/skills/hmos-incremental-ui-align/config-example.json +0 -11
  88. package/tools/test-tools/autotest/config.yaml.example +0 -58
@@ -29,22 +29,22 @@ This skill uses GitNexus as the code-graph backend: the `gitnexus-cli` skill for
29
29
 
30
30
  ## Expected Input
31
31
 
32
- - `requirement-description-file`: absolute path to a single `.txt` file containing one or more REQ blocks separated by blank lines. Within each block, the first line is the REQ title (often a dash-separated settings path like `Settings-UserInterface-ImmersionMode`), and the remaining lines are the body (behavior, default values, toggles). Required.
33
- - `android-project-path`: absolute path to the Android project root (must be inside a Git repo). Required.
34
- - `spec-output-dir`: absolute path to the directory where spec files will be written (will be created if missing). Required.
32
+ - `requirement_description_file`: absolute path to a single `.txt` file containing one or more REQ blocks separated by blank lines. Within each block, the first line is the REQ title (often a dash-separated settings path like `Settings-UserInterface-ImmersionMode`), and the remaining lines are the body (behavior, default values, toggles). Required.
33
+ - `android_project_dir`: absolute path to the Android project root (must be inside a Git repo). Required.
34
+ - `spec_output_dir`: absolute path to the directory where spec files will be written (will be created if missing). Required.
35
35
 
36
36
  **Caller example**:
37
37
 
38
38
  ```
39
- requirement-description-file: C:\proj\reqs\req-batch2-zh.txt
40
- android-project-path: C:\proj\SaltPlayer\
41
- spec-output-dir: C:\proj\specs-out\
39
+ requirement_description_file: C:\proj\reqs\req-batch2-zh.txt
40
+ android_project_dir: C:\proj\SaltPlayer\
41
+ spec_output_dir: C:\proj\specs-out\
42
42
  ```
43
43
 
44
44
  ## Expected Output
45
45
 
46
- - One markdown spec per REQ block, written to `<spec-output-dir>/<feature>-SPEC.md`. `<feature>` is the ≤ 20-character slug distilled in 3.1 (use the REQ's own language for the slug; ASCII / kebab-case acceptable when shorter).
47
- - One intermediate code-trace file per REQ block, written to `<spec-output-dir>/.trace/<feature>.md` (same slug). 3.5 synthesis MUST `Read` this file rather than recalling from conversation context.
46
+ - One markdown spec per REQ block, written to `<spec_output_dir>/<feature>-SPEC.md`. `<feature>` is the ≤ 20-character slug distilled in 3.1 (use the REQ's own language for the slug; ASCII / kebab-case acceptable when shorter).
47
+ - One intermediate code-trace file per REQ block, written to `<spec_output_dir>/.trace/<feature>.md` (same slug). 3.5 synthesis MUST `Read` this file rather than recalling from conversation context.
48
48
  - Both files overwrite if they already exist.
49
49
 
50
50
  ---
@@ -108,9 +108,9 @@ Mimic the samples' voice, scenario granularity, and structure — NOT their voca
108
108
 
109
109
  ### Step 0 — Validate inputs and parse REQ blocks
110
110
 
111
- 1. Verify `requirement-description-file` exists and is a file. If not, stop and report.
112
- 2. Verify `android-project-path` exists and is a directory. If not, stop and report.
113
- 3. Ensure `spec-output-dir` exists (create if missing). Ensure `<spec-output-dir>/.trace/` exists (create if missing).
111
+ 1. Verify `requirement_description_file` exists and is a file. If not, stop and report.
112
+ 2. Verify `android_project_dir` exists and is a directory. If not, stop and report.
113
+ 3. Ensure `spec_output_dir` exists (create if missing). Ensure `<spec_output_dir>/.trace/` exists (create if missing).
114
114
  4. **Parse the input `.txt`** (UTF-8):
115
115
  - Split into REQ blocks by blank lines. Each block: first non-blank line = `title`, remaining non-blank lines = `body`.
116
116
  - If a block has empty `body`, mark it for skip with reason `empty body`; do not abort the whole batch.
@@ -125,15 +125,15 @@ Step 0 output: an ordered list of `(title, body, feature)` tuples plus a skip li
125
125
 
126
126
  ### Step 1 — Confirm the Android project is a Git repo
127
127
 
128
- Run `git rev-parse --is-inside-work-tree` inside `android-project-path`.
128
+ Run `git rev-parse --is-inside-work-tree` inside `android_project_dir`.
129
129
 
130
130
  - Output is `true` → proceed to Step 2.
131
131
  - Otherwise → STOP. Tell the user:
132
132
 
133
- > `android-project-path` is not a Git repository. GitNexus indexes by Git identity. Please run:
133
+ > `android_project_dir` is not a Git repository. GitNexus indexes by Git identity. Please run:
134
134
  >
135
135
  > ```
136
- > cd <android-project-path>
136
+ > cd <android_project_dir>
137
137
  > git init && git add . && git commit -m "init"
138
138
  > ```
139
139
  >
@@ -150,11 +150,11 @@ GitNexus exposes two surfaces:
150
150
 
151
151
  Procedure:
152
152
 
153
- 1. Invoke `gitnexus-cli` skill with `status` against `android-project-path`.
153
+ 1. Invoke `gitnexus-cli` skill with `status` against `android_project_dir`.
154
154
  2. Decide based on the output:
155
155
  - **Not registered** or **stale** → invoke `gitnexus-cli` with `analyze`, wait for completion.
156
156
  - **Fresh** → proceed.
157
- 3. Obtain `<repo-id>` via `mcp__gitnexus__list_repos()`; find the entry whose `path` matches `android-project-path`; take its `repo` (or equivalent identifier) field.
157
+ 3. Obtain `<repo-id>` via `mcp__gitnexus__list_repos()`; find the entry whose `path` matches `android_project_dir`; take its `repo` (or equivalent identifier) field.
158
158
 
159
159
  **Hard fail policy** — any of the following stops the skill and surfaces the error to the user; do NOT degrade to `Read` + `Grep`:
160
160
 
@@ -206,7 +206,7 @@ Run both paths in parallel within the same turn (emit all mcp calls together); t
206
206
  - Path 1 + Path 2 both return zero, before writing `no_recall`.
207
207
  - Deviations from `REQ_DESC` exceed five AND touch core behavior (REQ may be stale; confirm before proceeding).
208
208
 
209
- #### 3.3 Trace — Explore code and write `<spec-output-dir>/.trace/<feature>.md`
209
+ #### 3.3 Trace — Explore code and write `<spec_output_dir>/.trace/<feature>.md`
210
210
 
211
211
  The trace file is the sole machine-readable contract delivered to 3.5. Exploration and writing form a single unit.
212
212
 
@@ -231,7 +231,7 @@ The trace file is the sole machine-readable contract delivered to 3.5. Explorati
231
231
  - **Application scope / boundary · Exhaustive entry enumeration** — ALL UI paths touching this feature / state, beyond REQ text. For state keys: reverse-lookup writers + lift to UI hosts. For readers: enumerate consumers + non-consumers. One field block per entry; omitted here = scenario omitted in spec.
232
232
  - **Consumer list & non-consumers** — who reads this state, plus which UI surfaces explicitly do NOT. Non-consumer claims use the structured field block (`claim` / `closure_layers` / `tools` / `zero_hits`).
233
233
 
234
- **Trace file template** (write to `<spec-output-dir>/.trace/<feature>.md`):
234
+ **Trace file template** (write to `<spec_output_dir>/.trace/<feature>.md`):
235
235
 
236
236
  ```markdown
237
237
  # Code trace · <feature>
@@ -308,7 +308,7 @@ Any check failing → return to 3.3 (rewrite / supplement / fix). Judge converge
308
308
 
309
309
  #### 3.5 Synthesize — Write the final spec
310
310
 
311
- `Read` the trace from 3.3 / 3.4, then synthesize the spec following `## Principles` and the style references under `references/`. Write to `<spec-output-dir>/<feature>-SPEC.md` (overwrite if exists).
311
+ `Read` the trace from 3.3 / 3.4, then synthesize the spec following `## Principles` and the style references under `references/`. Write to `<spec_output_dir>/<feature>-SPEC.md` (overwrite if exists).
312
312
 
313
313
  **Synthesis discipline**:
314
314
 
@@ -1,105 +1,105 @@
1
- # Android Platform Tokens — Strip List
2
-
3
- **Read when**: 3.5 Synthesize, for the platform-token strip list (Principle 6).
4
-
5
- The spec MUST NOT contain Android platform tokens. During 3.5 synthesis, strip every match from the trace's natural-language behavior text and replace with behavior-level Chinese vocabulary. The trace itself may use these tokens (they live in `file:line` anchors and code-layer notes); only the **final spec** must be platform-token-free.
6
-
7
- ## Strip list (by category)
8
-
9
- ### Components
10
- `Activity`, `Fragment`, `Composable`, `Service`, `ForegroundService`, `BroadcastReceiver`, `ContentProvider`, `Application`, `Worker`, `IntentService`, `JobIntentService`, `JobScheduler`
11
-
12
- ### IPC / data carriers
13
- `Intent`, `PendingIntent`, `Bundle`, `Parcelable`, `Messenger`, `AIDL`, `Binder`, `IBinder`
14
-
15
- ### State / architecture
16
- `ViewModel`, `LiveData`, `MutableLiveData`, `StateFlow`, `SharedFlow`, `Flow` (when meaning Kotlin Flow), `mutableStateOf`, `ViewBinding`, `DataBinding`, `Repository`, `UseCase`, `Presenter`
17
-
18
- ### Persistence
19
- `Room`, `RoomDatabase`, `DAO`, `@Entity`, `DataStore`, `Preferences DataStore`, `Proto DataStore`, `SharedPreferences`, `MMKV`, `SQLiteOpenHelper`, `ContentResolver`
20
-
21
- ### Lifecycle
22
- `onCreate`, `onStart`, `onResume`, `onPause`, `onStop`, `onDestroy`, `Lifecycle`, `LifecycleOwner`, `ProcessLifecycleOwner`, `viewLifecycleOwner`, `lifecycleScope`
23
-
24
- ### UI containers / widgets
25
- `RecyclerView`, `Adapter`, `ViewHolder`, `ConstraintLayout`, `LinearLayout`, `FrameLayout`, `RelativeLayout`, `ScrollView`, `ListView`, `Spinner`, `ViewPager`, `TabLayout`
26
-
27
- ### UI feedback
28
- `Toast`, `Snackbar`, `Dialog`, `AlertDialog`, `BottomSheetDialog`, `ProgressDialog`, `FloatingActionButton`
29
-
30
- ### Navigation
31
- `NavController`, `NavGraph`, `NavHostFragment`, `Navigation Component`, `startActivity`, `startActivityForResult`
32
-
33
- ### Resources / IDs
34
- `R.id.*`, `R.layout.*`, `R.string.*`, `R.drawable.*`, `R.color.*`, `R.dimen.*`, `R.menu.*`, `R.xml.*`, `R.array.*`, `R.style.*`, `@+id/...`, `@string/...`, `@drawable/...`, `@color/...`
35
-
36
- ### Coroutines / threading
37
- `Coroutine`, `suspend`, `CoroutineScope`, `Job`, `viewModelScope`, `withContext`, `Dispatchers.*`, `async`, `await`, `launch`, `Handler`, `Looper`, `HandlerThread`, `AsyncTask`, `Executor`
38
-
39
- ### Compose (lifecycle / state)
40
- `@Composable`, `remember`, `derivedStateOf`, `rememberSaveable`, `MutableState`, `LaunchedEffect`, `DisposableEffect`, `SideEffect`, `CompositionLocal`, `produceState`
41
-
42
- ### Compose Shape
43
- `CircleShape`, `RoundedCornerShape`, `RectangleShape`, `CutCornerShape`
44
-
45
- ### Compose Animation
46
- `LinearEasing`, `FastOutSlowInEasing`, `EaseInOut`, `EaseOut`, `tween`, `spring`, `keyframes`, `infiniteRepeatable`, `animateXxxAsState`, `Animatable`, `AnimationSpec`
47
-
48
- ### Compose Layout / Modifier
49
- `ContentScale` (Fit / Crop / FillBounds / Inside / None), `Alignment`, `Arrangement`, `Modifier.clip`, `Modifier.background`, `Modifier.size`, `Modifier.padding`, `Modifier.fillMaxSize`, `Modifier.wrapContentSize`, `Modifier.aspectRatio`, `Modifier.weight`
50
-
51
- ### Build / Manifest
52
- `AndroidManifest`, `build.gradle`, `gradle`, `BuildConfig`, `applicationId`, `versionCode`, `minSdkVersion`, `targetSdkVersion`, `compileSdkVersion`, `ProGuard`, `R8`
53
-
54
- ### DI
55
- `Hilt`, `Dagger`, `@Inject`, `@Module`, `@Provides`, `@Singleton`, `Koin`, `ServiceLocator`
56
-
57
- ### System services / media
58
- `ContextCompat`, `getSystemService`, `NotificationManager`, `NotificationChannel`, `AlarmManager`, `PowerManager`, `ConnectivityManager`, `AudioManager`, `MediaSession`, `MediaPlayer`, `ExoPlayer`, `MediaBrowserServiceCompat`
59
-
60
- ### Implementation constants (NEVER appear in spec)
61
-
62
- - **Hardcoded dimensions** (`8dp`, `48.dp`, `16.sp`, `2.dp`) — strip entirely. Spec describes shape/size semantically: "圆形" / "小圆点" / "歌词字号比正文略大". 不要保留单位 ("8 dp" 也不行).
63
- - **Hardcoded durations** (`25000ms`, `300L`, `Duration.seconds(2)`) — restate as semantic time: "约 25 秒一圈" / "短暂淡入". 不要写原始数值.
64
- - **Persistence key literals** (`circle_playback_cover`, `karaoke_mode_compat`, `floating_lyric_enabled`) — NEVER. Describe the user-visible setting, not the storage key.
65
-
66
- ## Critical: Chinese translations of platform concepts are ALSO forbidden
67
-
68
- The strip list above uses English API names. But platform concepts translated into Chinese (e.g. `活动基类` for Activity / `主活动页面` for MainActivity / `媒体会话信息` for MediaSession / `短边模式` for DISPLAY_CUTOUT_MODE / `广播接收器` for BroadcastReceiver / `视图模型` for ViewModel) are STILL platform tokens — restate them in user-facing behavior language per the replacement vocabulary below. Translating a platform concept does NOT make it user-facing.
69
-
70
- ## Replacement vocabulary (behavior-level Chinese)
71
-
72
- | Stripped token | Spec vocabulary |
73
- |---|---|
74
- | Activity / Fragment / Composable | 页面 |
75
- | Dialog / AlertDialog / BottomSheet | 弹窗 / 对话框 |
76
- | Toast / Snackbar | toast 提示 / 浮动提示 |
77
- | ViewModel / LiveData / StateFlow / mutableStateOf | 状态 / 状态写入 / 状态刷新 |
78
- | Room / DAO / DataStore / SharedPreferences / MMKV | 持久化 / 数据库 / 配置存储 |
79
- | RecyclerView + Adapter / ListView | 列表 / 列表项 |
80
- | onClick / onLongClick / onTap | 点击 / 长按 |
81
- | Intent / startActivity / Navigation | 跳转 / 进入<目标页> |
82
- | BroadcastReceiver / sendBroadcast | 系统事件监听 / 广播 |
83
- | Service / ForegroundService | 后台服务 / 前台服务 |
84
- | Coroutine / launch / withContext | 异步 / 异步执行 |
85
- | MediaPlayer / ExoPlayer / MediaSession | 播放器 / 播放控制 |
86
- | Notification / NotificationManager / NotificationChannel | 通知 / 通知栏 / 通知分组 |
87
- | ContentResolver / ContentProvider | 数据访问 / 数据共享 |
88
- | build.gradle flag / BuildConfig | 编译开关 / 配置项 |
89
- | ConnectivityManager | 网络状态 / 网络可达性 |
90
- | AudioManager / audio focus | 音频焦点 / 音频通道 |
91
- | PowerManager / WakeLock | 屏幕唤醒 / 锁屏唤醒 |
92
- | CircleShape / RoundedCornerShape / RectangleShape / CutCornerShape | 圆形 / 圆角矩形 / 矩形 / 切角矩形 |
93
- | LinearEasing / FastOutSlowInEasing / EaseInOut / EaseOut | 线性 / 减速 / 缓入缓出 / 减速出 |
94
- | tween / spring / keyframes / infiniteRepeatable / Animatable | 持续N秒动画 / 弹性动画 / 关键帧动画 / 循环动画 / 动画对象 |
95
- | ContentScale.Fit / Crop / FillBounds / Inside / None | 等比缩放适配 / 裁剪填充 / 拉伸填充 / 等比居中 / 不缩放 |
96
- | Modifier.clip / .size / .padding / .fillMaxSize / .aspectRatio | 裁剪为X形 / 设定尺寸 / 内边距 / 填满父容器 / 宽高比 |
97
- | Modifier.wrapContentSize / .weight / .background | 内容自适应 / 权重占比 / 背景 |
98
- | animateXxxAsState | 动画过渡到目标值 |
99
-
100
- ## Items to keep verbatim (do NOT strip)
101
-
102
- - **Business entity names** (歌单, 歌曲, 专辑, 艺术家, 播放页, ...) — these are domain language, not platform tokens.
103
- - **User-visible resource string content** (toast text, button labels, error messages) — translate the displayed content into the spec; strip the `R.string.xxx` reference but keep the message text.
104
- - **Standard permission semantics** — describe permissions in user language ("录音权限", "通知权限", "存储访问权限"), NOT by code constant (`RECORD_AUDIO`, `POST_NOTIFICATIONS`, ...).
105
- - **Persistence key literals** are usually internal — do NOT surface them in the spec unless they appear in user-visible UI (rare). If a key appears in the trace's `interaction` field, describe its behavior, not its name.
1
+ # Android Platform Tokens — Strip List
2
+
3
+ **Read when**: 3.5 Synthesize, for the platform-token strip list (Principle 6).
4
+
5
+ The spec MUST NOT contain Android platform tokens. During 3.5 synthesis, strip every match from the trace's natural-language behavior text and replace with behavior-level Chinese vocabulary. The trace itself may use these tokens (they live in `file:line` anchors and code-layer notes); only the **final spec** must be platform-token-free.
6
+
7
+ ## Strip list (by category)
8
+
9
+ ### Components
10
+ `Activity`, `Fragment`, `Composable`, `Service`, `ForegroundService`, `BroadcastReceiver`, `ContentProvider`, `Application`, `Worker`, `IntentService`, `JobIntentService`, `JobScheduler`
11
+
12
+ ### IPC / data carriers
13
+ `Intent`, `PendingIntent`, `Bundle`, `Parcelable`, `Messenger`, `AIDL`, `Binder`, `IBinder`
14
+
15
+ ### State / architecture
16
+ `ViewModel`, `LiveData`, `MutableLiveData`, `StateFlow`, `SharedFlow`, `Flow` (when meaning Kotlin Flow), `mutableStateOf`, `ViewBinding`, `DataBinding`, `Repository`, `UseCase`, `Presenter`
17
+
18
+ ### Persistence
19
+ `Room`, `RoomDatabase`, `DAO`, `@Entity`, `DataStore`, `Preferences DataStore`, `Proto DataStore`, `SharedPreferences`, `MMKV`, `SQLiteOpenHelper`, `ContentResolver`
20
+
21
+ ### Lifecycle
22
+ `onCreate`, `onStart`, `onResume`, `onPause`, `onStop`, `onDestroy`, `Lifecycle`, `LifecycleOwner`, `ProcessLifecycleOwner`, `viewLifecycleOwner`, `lifecycleScope`
23
+
24
+ ### UI containers / widgets
25
+ `RecyclerView`, `Adapter`, `ViewHolder`, `ConstraintLayout`, `LinearLayout`, `FrameLayout`, `RelativeLayout`, `ScrollView`, `ListView`, `Spinner`, `ViewPager`, `TabLayout`
26
+
27
+ ### UI feedback
28
+ `Toast`, `Snackbar`, `Dialog`, `AlertDialog`, `BottomSheetDialog`, `ProgressDialog`, `FloatingActionButton`
29
+
30
+ ### Navigation
31
+ `NavController`, `NavGraph`, `NavHostFragment`, `Navigation Component`, `startActivity`, `startActivityForResult`
32
+
33
+ ### Resources / IDs
34
+ `R.id.*`, `R.layout.*`, `R.string.*`, `R.drawable.*`, `R.color.*`, `R.dimen.*`, `R.menu.*`, `R.xml.*`, `R.array.*`, `R.style.*`, `@+id/...`, `@string/...`, `@drawable/...`, `@color/...`
35
+
36
+ ### Coroutines / threading
37
+ `Coroutine`, `suspend`, `CoroutineScope`, `Job`, `viewModelScope`, `withContext`, `Dispatchers.*`, `async`, `await`, `launch`, `Handler`, `Looper`, `HandlerThread`, `AsyncTask`, `Executor`
38
+
39
+ ### Compose (lifecycle / state)
40
+ `@Composable`, `remember`, `derivedStateOf`, `rememberSaveable`, `MutableState`, `LaunchedEffect`, `DisposableEffect`, `SideEffect`, `CompositionLocal`, `produceState`
41
+
42
+ ### Compose Shape
43
+ `CircleShape`, `RoundedCornerShape`, `RectangleShape`, `CutCornerShape`
44
+
45
+ ### Compose Animation
46
+ `LinearEasing`, `FastOutSlowInEasing`, `EaseInOut`, `EaseOut`, `tween`, `spring`, `keyframes`, `infiniteRepeatable`, `animateXxxAsState`, `Animatable`, `AnimationSpec`
47
+
48
+ ### Compose Layout / Modifier
49
+ `ContentScale` (Fit / Crop / FillBounds / Inside / None), `Alignment`, `Arrangement`, `Modifier.clip`, `Modifier.background`, `Modifier.size`, `Modifier.padding`, `Modifier.fillMaxSize`, `Modifier.wrapContentSize`, `Modifier.aspectRatio`, `Modifier.weight`
50
+
51
+ ### Build / Manifest
52
+ `AndroidManifest`, `build.gradle`, `gradle`, `BuildConfig`, `applicationId`, `versionCode`, `minSdkVersion`, `targetSdkVersion`, `compileSdkVersion`, `ProGuard`, `R8`
53
+
54
+ ### DI
55
+ `Hilt`, `Dagger`, `@Inject`, `@Module`, `@Provides`, `@Singleton`, `Koin`, `ServiceLocator`
56
+
57
+ ### System services / media
58
+ `ContextCompat`, `getSystemService`, `NotificationManager`, `NotificationChannel`, `AlarmManager`, `PowerManager`, `ConnectivityManager`, `AudioManager`, `MediaSession`, `MediaPlayer`, `ExoPlayer`, `MediaBrowserServiceCompat`
59
+
60
+ ### Implementation constants (NEVER appear in spec)
61
+
62
+ - **Hardcoded dimensions** (`8dp`, `48.dp`, `16.sp`, `2.dp`) — strip entirely. Spec describes shape/size semantically: "圆形" / "小圆点" / "歌词字号比正文略大". 不要保留单位 ("8 dp" 也不行).
63
+ - **Hardcoded durations** (`25000ms`, `300L`, `Duration.seconds(2)`) — restate as semantic time: "约 25 秒一圈" / "短暂淡入". 不要写原始数值.
64
+ - **Persistence key literals** (`circle_playback_cover`, `karaoke_mode_compat`, `floating_lyric_enabled`) — NEVER. Describe the user-visible setting, not the storage key.
65
+
66
+ ## Critical: Chinese translations of platform concepts are ALSO forbidden
67
+
68
+ The strip list above uses English API names. But platform concepts translated into Chinese (e.g. `活动基类` for Activity / `主活动页面` for MainActivity / `媒体会话信息` for MediaSession / `短边模式` for DISPLAY_CUTOUT_MODE / `广播接收器` for BroadcastReceiver / `视图模型` for ViewModel) are STILL platform tokens — restate them in user-facing behavior language per the replacement vocabulary below. Translating a platform concept does NOT make it user-facing.
69
+
70
+ ## Replacement vocabulary (behavior-level Chinese)
71
+
72
+ | Stripped token | Spec vocabulary |
73
+ |---|---|
74
+ | Activity / Fragment / Composable | 页面 |
75
+ | Dialog / AlertDialog / BottomSheet | 弹窗 / 对话框 |
76
+ | Toast / Snackbar | toast 提示 / 浮动提示 |
77
+ | ViewModel / LiveData / StateFlow / mutableStateOf | 状态 / 状态写入 / 状态刷新 |
78
+ | Room / DAO / DataStore / SharedPreferences / MMKV | 持久化 / 数据库 / 配置存储 |
79
+ | RecyclerView + Adapter / ListView | 列表 / 列表项 |
80
+ | onClick / onLongClick / onTap | 点击 / 长按 |
81
+ | Intent / startActivity / Navigation | 跳转 / 进入<目标页> |
82
+ | BroadcastReceiver / sendBroadcast | 系统事件监听 / 广播 |
83
+ | Service / ForegroundService | 后台服务 / 前台服务 |
84
+ | Coroutine / launch / withContext | 异步 / 异步执行 |
85
+ | MediaPlayer / ExoPlayer / MediaSession | 播放器 / 播放控制 |
86
+ | Notification / NotificationManager / NotificationChannel | 通知 / 通知栏 / 通知分组 |
87
+ | ContentResolver / ContentProvider | 数据访问 / 数据共享 |
88
+ | build.gradle flag / BuildConfig | 编译开关 / 配置项 |
89
+ | ConnectivityManager | 网络状态 / 网络可达性 |
90
+ | AudioManager / audio focus | 音频焦点 / 音频通道 |
91
+ | PowerManager / WakeLock | 屏幕唤醒 / 锁屏唤醒 |
92
+ | CircleShape / RoundedCornerShape / RectangleShape / CutCornerShape | 圆形 / 圆角矩形 / 矩形 / 切角矩形 |
93
+ | LinearEasing / FastOutSlowInEasing / EaseInOut / EaseOut | 线性 / 减速 / 缓入缓出 / 减速出 |
94
+ | tween / spring / keyframes / infiniteRepeatable / Animatable | 持续N秒动画 / 弹性动画 / 关键帧动画 / 循环动画 / 动画对象 |
95
+ | ContentScale.Fit / Crop / FillBounds / Inside / None | 等比缩放适配 / 裁剪填充 / 拉伸填充 / 等比居中 / 不缩放 |
96
+ | Modifier.clip / .size / .padding / .fillMaxSize / .aspectRatio | 裁剪为X形 / 设定尺寸 / 内边距 / 填满父容器 / 宽高比 |
97
+ | Modifier.wrapContentSize / .weight / .background | 内容自适应 / 权重占比 / 背景 |
98
+ | animateXxxAsState | 动画过渡到目标值 |
99
+
100
+ ## Items to keep verbatim (do NOT strip)
101
+
102
+ - **Business entity names** (歌单, 歌曲, 专辑, 艺术家, 播放页, ...) — these are domain language, not platform tokens.
103
+ - **User-visible resource string content** (toast text, button labels, error messages) — translate the displayed content into the spec; strip the `R.string.xxx` reference but keep the message text.
104
+ - **Standard permission semantics** — describe permissions in user language ("录音权限", "通知权限", "存储访问权限"), NOT by code constant (`RECORD_AUDIO`, `POST_NOTIFICATIONS`, ...).
105
+ - **Persistence key literals** are usually internal — do NOT surface them in the spec unless they appear in user-visible UI (rare). If a key appears in the trace's `interaction` field, describe its behavior, not its name.
@@ -1,78 +1,78 @@
1
- # Spec Sample 1 — Boundary-and-happy-path Decomposition
2
-
3
- **Style focus**: how to slice one feature into `empty / over-length / valid / cancel` atomic scenarios on a single-entry trigger flow. Mimic the voice, scenario granularity, and structure — NOT the vocabulary or domain.
4
-
5
- **Read when**: 3.5 Synthesize.
6
-
7
- ---
8
-
9
- # 新建歌单SPEC
10
-
11
- 创建新歌单
12
-
13
- ## 场景一
14
-
15
- ### 场景概述
16
-
17
- 用户点击创建歌单,但输入的歌单名称为空并且创建歌单
18
-
19
- ### 场景逻辑步骤
20
-
21
- - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
22
- - 2. 弹出"新建歌单对话框"
23
- - 3. 用户在输入框中输入空白歌单名称并点击确定按钮
24
- - 4. 弹出toast"歌单名称不得为空"并且关闭"新建歌单对话框"
25
-
26
- ## 场景二
27
-
28
- ### 场景概述
29
-
30
- 用户点击创建歌单,但输入的歌单名称超过最大长度并且创建歌单
31
-
32
- ### 场景逻辑步骤
33
-
34
- - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
35
- - 2. 弹出"新建歌单对话框"
36
- - 3. 用户在输入框中输入歌单名称并且歌单名称超过100个字符,然后点击确定按钮
37
- - 4. 弹出toast"歌单名称过长"并且关闭"新建歌单对话框"
38
-
39
- ## 场景三
40
-
41
- ### 场景概述
42
-
43
- 用户点击创建歌单,输入有效歌单名称并且创建歌单
44
-
45
- ### 场景逻辑步骤
46
-
47
- - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
48
- - 2. 弹出"新建歌单对话框"
49
- - 3. 用户在输入框中输入有效歌单名称,即用户输入到歌单名称不为空并且歌单名称没有超过100个字符,然后点击确定按钮
50
- - 4. 去除歌单名称首尾空白字符
51
- - 5. 把新建的歌单数据写入数据库中的歌单数据库表
52
- - 6. 如果是在"歌单页面",那么从数据库中读取新建歌单的数据,并且在"歌单页面"创建新建歌单item,实时刷新歌单页面,在歌单页面列表中的第一个位置上显示新建的歌单
53
- - 7. 如果是在"添加到歌单弹窗",那么从数据库中读取新建歌单的数据,并且在"添加到歌单弹窗"创建新建歌单item,实时刷新歌单页面,在添加到歌单弹窗列表中的第一个位置上显示新建的歌单
54
-
55
- > [偏差] 需求要求歌单名为空时禁用"确定"按钮,但实际代码允许点击后弹出 toast 提示(参见场景一步骤 4)。
56
-
57
- ## 场景四
58
-
59
- ### 场景概述
60
-
61
- 用户点击创建歌单,输入或者不输入歌单名称,然后点击取消按钮
62
-
63
- ### 场景逻辑步骤
64
-
65
- - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
66
- - 2. 弹出"新建歌单对话框"
67
- - 3. 无论用户是否在输入框中输入歌单名称,只要用户点击取消按钮,那么就关闭"新建歌单对话框",无需执行其他操作
68
-
69
- ## 场景五
70
-
71
- ### 场景概述
72
-
73
- "新建歌单"功能的作用范围与不作用范围
74
-
75
- ### 场景逻辑步骤
76
-
77
- - 1. **仅作用于** 以下入口: "歌单页面"的"更多菜单 - 新建歌单"按钮; "添加到歌单弹窗"的"新建歌单"按钮
78
- - 2. **不作用于** 以下位置: "歌单详情页"(无新建入口) / "播放页" / "首页推荐区域" / "搜索结果页" / "我的页面" — 这些位置既不显示新建歌单入口, 也不响应新建歌单事件
1
+ # Spec Sample 1 — Boundary-and-happy-path Decomposition
2
+
3
+ **Style focus**: how to slice one feature into `empty / over-length / valid / cancel` atomic scenarios on a single-entry trigger flow. Mimic the voice, scenario granularity, and structure — NOT the vocabulary or domain.
4
+
5
+ **Read when**: 3.5 Synthesize.
6
+
7
+ ---
8
+
9
+ # 新建歌单SPEC
10
+
11
+ 创建新歌单
12
+
13
+ ## 场景一
14
+
15
+ ### 场景概述
16
+
17
+ 用户点击创建歌单,但输入的歌单名称为空并且创建歌单
18
+
19
+ ### 场景逻辑步骤
20
+
21
+ - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
22
+ - 2. 弹出"新建歌单对话框"
23
+ - 3. 用户在输入框中输入空白歌单名称并点击确定按钮
24
+ - 4. 弹出toast"歌单名称不得为空"并且关闭"新建歌单对话框"
25
+
26
+ ## 场景二
27
+
28
+ ### 场景概述
29
+
30
+ 用户点击创建歌单,但输入的歌单名称超过最大长度并且创建歌单
31
+
32
+ ### 场景逻辑步骤
33
+
34
+ - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
35
+ - 2. 弹出"新建歌单对话框"
36
+ - 3. 用户在输入框中输入歌单名称并且歌单名称超过100个字符,然后点击确定按钮
37
+ - 4. 弹出toast"歌单名称过长"并且关闭"新建歌单对话框"
38
+
39
+ ## 场景三
40
+
41
+ ### 场景概述
42
+
43
+ 用户点击创建歌单,输入有效歌单名称并且创建歌单
44
+
45
+ ### 场景逻辑步骤
46
+
47
+ - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
48
+ - 2. 弹出"新建歌单对话框"
49
+ - 3. 用户在输入框中输入有效歌单名称,即用户输入到歌单名称不为空并且歌单名称没有超过100个字符,然后点击确定按钮
50
+ - 4. 去除歌单名称首尾空白字符
51
+ - 5. 把新建的歌单数据写入数据库中的歌单数据库表
52
+ - 6. 如果是在"歌单页面",那么从数据库中读取新建歌单的数据,并且在"歌单页面"创建新建歌单item,实时刷新歌单页面,在歌单页面列表中的第一个位置上显示新建的歌单
53
+ - 7. 如果是在"添加到歌单弹窗",那么从数据库中读取新建歌单的数据,并且在"添加到歌单弹窗"创建新建歌单item,实时刷新歌单页面,在添加到歌单弹窗列表中的第一个位置上显示新建的歌单
54
+
55
+ > [偏差] 需求要求歌单名为空时禁用"确定"按钮,但实际代码允许点击后弹出 toast 提示(参见场景一步骤 4)。
56
+
57
+ ## 场景四
58
+
59
+ ### 场景概述
60
+
61
+ 用户点击创建歌单,输入或者不输入歌单名称,然后点击取消按钮
62
+
63
+ ### 场景逻辑步骤
64
+
65
+ - 1. 用户在"歌单页面"点击"更多菜单"中的"新建歌单按钮"或者用户在"添加到歌单弹窗"中点击"新建歌单按钮"
66
+ - 2. 弹出"新建歌单对话框"
67
+ - 3. 无论用户是否在输入框中输入歌单名称,只要用户点击取消按钮,那么就关闭"新建歌单对话框",无需执行其他操作
68
+
69
+ ## 场景五
70
+
71
+ ### 场景概述
72
+
73
+ "新建歌单"功能的作用范围与不作用范围
74
+
75
+ ### 场景逻辑步骤
76
+
77
+ - 1. **仅作用于** 以下入口: "歌单页面"的"更多菜单 - 新建歌单"按钮; "添加到歌单弹窗"的"新建歌单"按钮
78
+ - 2. **不作用于** 以下位置: "歌单详情页"(无新建入口) / "播放页" / "首页推荐区域" / "搜索结果页" / "我的页面" — 这些位置既不显示新建歌单入口, 也不响应新建歌单事件
@@ -1,58 +1,58 @@
1
- # Spec Sample 2 — Nested Sub-bullet Decomposition
2
-
3
- **Style focus**: how to express per-field present/absent fallback rules as nested sub-bullets within a single scenario's flow. Mimic the structure, NOT the vocabulary or domain.
4
-
5
- **Read when**: 3.5 Synthesize.
6
-
7
- ---
8
-
9
- # 歌曲信息页信息展示与信息更新SPEC
10
-
11
- 歌曲信息页展示音频信息、出自专辑、参与创作的艺术家,以及播放界面保持屏幕唤醒、沉浸模式内容。
12
-
13
- ## 场景一
14
-
15
- ### 场景概述
16
-
17
- 进入歌曲信息页后,展示当前播放歌曲的信息及相关功能入口
18
-
19
- ### 场景逻辑步骤
20
-
21
- - 1. 在播放页右滑进入歌曲信息页
22
- - 2. 歌曲信息页读取信息并展示:
23
- - 2.1 音频信息展示:
24
- - 当当前播放歌曲的音频格式存在时,显示当前播放歌曲的音频格式
25
- - 当当前播放歌曲的音频格式缺失时,显示当前播放歌曲的文件扩展名;若文件扩展名也为空,则显示为空白
26
- - 当当前播放歌曲的声道数存在时,显示声道数
27
- - 当当前播放歌曲的声道数缺失时,隐藏该字段
28
- - 当当前播放歌曲的采样率存在时,显示采样率
29
- - 当当前播放歌曲的采样率缺失时,隐藏该字段
30
- - 当当前播放歌曲的比特率存在时,显示比特率
31
- - 当当前播放歌曲的比特率缺失时,显示 0 Kbps
32
- - 2.2 出自专辑展示:
33
- - 当当前播放歌曲的专辑封面存在时,显示专辑封面
34
- - 当当前播放歌曲的专辑封面缺失时,显示默认专辑封面图标
35
- - 当当前播放歌曲的专辑标题存在时,显示专辑标题
36
- - 当当前播放歌曲的专辑标题缺失时,显示"未知专辑标题"
37
- - 当当前播放歌曲的专辑艺术家存在时,显示专辑艺术家
38
- - 当当前播放歌曲的专辑艺术家缺失时,显示"未知专辑艺术家"
39
- - 2.3 参与创作的艺术家展示:
40
- - 当当前播放歌曲的艺术家头像存在时,显示艺术家头像
41
- - 当当前播放歌曲的艺术家头像缺失时,显示默认歌曲封面图标
42
- - 当当前播放歌曲的艺术家名称存在时,显示艺术家名称
43
- - 当当前播放歌曲的艺术家名称缺失时,显示"未知艺术家"
44
- - 当当前播放歌曲的艺术家音轨数量(歌曲数量)存在时,显示艺术家音轨数量(歌曲数量)
45
- - 当当前播放歌曲的艺术家音轨数量(歌曲数量)缺失时,显示 0
46
-
47
-
48
- ## 场景二
49
-
50
- ### 场景概述
51
-
52
- 切换播放歌曲后,歌曲信息页面同步刷新
53
-
54
- ### 场景逻辑步骤
55
-
56
- - 1. 在播放页右滑进入歌曲信息页
57
- - 2. 用户通过上一首、下一首、播放队列切歌或自动切歌等方式切换当前播放歌曲
58
- - 3. 歌曲信息页中的音频信息、专辑信息、艺术家信息同步刷新为新歌曲对应内容
1
+ # Spec Sample 2 — Nested Sub-bullet Decomposition
2
+
3
+ **Style focus**: how to express per-field present/absent fallback rules as nested sub-bullets within a single scenario's flow. Mimic the structure, NOT the vocabulary or domain.
4
+
5
+ **Read when**: 3.5 Synthesize.
6
+
7
+ ---
8
+
9
+ # 歌曲信息页信息展示与信息更新SPEC
10
+
11
+ 歌曲信息页展示音频信息、出自专辑、参与创作的艺术家,以及播放界面保持屏幕唤醒、沉浸模式内容。
12
+
13
+ ## 场景一
14
+
15
+ ### 场景概述
16
+
17
+ 进入歌曲信息页后,展示当前播放歌曲的信息及相关功能入口
18
+
19
+ ### 场景逻辑步骤
20
+
21
+ - 1. 在播放页右滑进入歌曲信息页
22
+ - 2. 歌曲信息页读取信息并展示:
23
+ - 2.1 音频信息展示:
24
+ - 当当前播放歌曲的音频格式存在时,显示当前播放歌曲的音频格式
25
+ - 当当前播放歌曲的音频格式缺失时,显示当前播放歌曲的文件扩展名;若文件扩展名也为空,则显示为空白
26
+ - 当当前播放歌曲的声道数存在时,显示声道数
27
+ - 当当前播放歌曲的声道数缺失时,隐藏该字段
28
+ - 当当前播放歌曲的采样率存在时,显示采样率
29
+ - 当当前播放歌曲的采样率缺失时,隐藏该字段
30
+ - 当当前播放歌曲的比特率存在时,显示比特率
31
+ - 当当前播放歌曲的比特率缺失时,显示 0 Kbps
32
+ - 2.2 出自专辑展示:
33
+ - 当当前播放歌曲的专辑封面存在时,显示专辑封面
34
+ - 当当前播放歌曲的专辑封面缺失时,显示默认专辑封面图标
35
+ - 当当前播放歌曲的专辑标题存在时,显示专辑标题
36
+ - 当当前播放歌曲的专辑标题缺失时,显示"未知专辑标题"
37
+ - 当当前播放歌曲的专辑艺术家存在时,显示专辑艺术家
38
+ - 当当前播放歌曲的专辑艺术家缺失时,显示"未知专辑艺术家"
39
+ - 2.3 参与创作的艺术家展示:
40
+ - 当当前播放歌曲的艺术家头像存在时,显示艺术家头像
41
+ - 当当前播放歌曲的艺术家头像缺失时,显示默认歌曲封面图标
42
+ - 当当前播放歌曲的艺术家名称存在时,显示艺术家名称
43
+ - 当当前播放歌曲的艺术家名称缺失时,显示"未知艺术家"
44
+ - 当当前播放歌曲的艺术家音轨数量(歌曲数量)存在时,显示艺术家音轨数量(歌曲数量)
45
+ - 当当前播放歌曲的艺术家音轨数量(歌曲数量)缺失时,显示 0
46
+
47
+
48
+ ## 场景二
49
+
50
+ ### 场景概述
51
+
52
+ 切换播放歌曲后,歌曲信息页面同步刷新
53
+
54
+ ### 场景逻辑步骤
55
+
56
+ - 1. 在播放页右滑进入歌曲信息页
57
+ - 2. 用户通过上一首、下一首、播放队列切歌或自动切歌等方式切换当前播放歌曲
58
+ - 3. 歌曲信息页中的音频信息、专辑信息、艺术家信息同步刷新为新歌曲对应内容