theslopmachine 0.6.2 → 0.7.0
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.
- package/MANUAL.md +21 -6
- package/README.md +55 -7
- package/RELEASE.md +15 -0
- package/assets/agents/developer.md +41 -1
- package/assets/agents/slopmachine-claude.md +100 -60
- package/assets/agents/slopmachine.md +40 -17
- package/assets/claude/agents/developer.md +42 -5
- package/assets/skills/clarification-gate/SKILL.md +25 -5
- package/assets/skills/claude-worker-management/SKILL.md +280 -57
- package/assets/skills/developer-session-lifecycle/SKILL.md +81 -37
- package/assets/skills/development-guidance/SKILL.md +21 -1
- package/assets/skills/evaluation-triage/SKILL.md +32 -23
- package/assets/skills/final-evaluation-orchestration/SKILL.md +86 -50
- package/assets/skills/hardening-gate/SKILL.md +17 -3
- package/assets/skills/integrated-verification/SKILL.md +3 -3
- package/assets/skills/planning-gate/SKILL.md +32 -3
- package/assets/skills/planning-guidance/SKILL.md +72 -13
- package/assets/skills/retrospective-analysis/SKILL.md +2 -2
- package/assets/skills/scaffold-guidance/SKILL.md +129 -124
- package/assets/skills/submission-packaging/SKILL.md +33 -27
- package/assets/skills/verification-gates/SKILL.md +44 -14
- package/assets/slopmachine/backend-evaluation-prompt.md +1 -1
- package/assets/slopmachine/frontend-evaluation-prompt.md +5 -5
- package/assets/slopmachine/scaffold-playbooks/android-kotlin-compose.md +81 -0
- package/assets/slopmachine/scaffold-playbooks/android-kotlin-views.md +191 -0
- package/assets/slopmachine/scaffold-playbooks/android-native-java.md +203 -0
- package/assets/slopmachine/scaffold-playbooks/angular-default.md +181 -0
- package/assets/slopmachine/scaffold-playbooks/backend-baseline.md +142 -0
- package/assets/slopmachine/scaffold-playbooks/backend-family-matrix.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/database-module-matrix.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/django-default.md +166 -0
- package/assets/slopmachine/scaffold-playbooks/docker-baseline.md +189 -0
- package/assets/slopmachine/scaffold-playbooks/docker-shared-contract.md +334 -0
- package/assets/slopmachine/scaffold-playbooks/electron-vite-default.md +124 -0
- package/assets/slopmachine/scaffold-playbooks/expo-react-native-default.md +73 -0
- package/assets/slopmachine/scaffold-playbooks/fastapi-default.md +134 -0
- package/assets/slopmachine/scaffold-playbooks/frontend-baseline.md +160 -0
- package/assets/slopmachine/scaffold-playbooks/frontend-family-matrix.md +134 -0
- package/assets/slopmachine/scaffold-playbooks/generic-unknown-tech-guide.md +136 -0
- package/assets/slopmachine/scaffold-playbooks/go-chi-default.md +160 -0
- package/assets/slopmachine/scaffold-playbooks/ios-linux-portable.md +93 -0
- package/assets/slopmachine/scaffold-playbooks/ios-native-objective-c.md +151 -0
- package/assets/slopmachine/scaffold-playbooks/ios-native-swift.md +188 -0
- package/assets/slopmachine/scaffold-playbooks/laravel-default.md +216 -0
- package/assets/slopmachine/scaffold-playbooks/livewire-default.md +265 -0
- package/assets/slopmachine/scaffold-playbooks/overlay-module-matrix.md +130 -0
- package/assets/slopmachine/scaffold-playbooks/platform-family-matrix.md +79 -0
- package/assets/slopmachine/scaffold-playbooks/selection-matrix.md +72 -0
- package/assets/slopmachine/scaffold-playbooks/spring-boot-default.md +182 -0
- package/assets/slopmachine/scaffold-playbooks/tauri-default.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/vue-vite-default.md +162 -0
- package/assets/slopmachine/scaffold-playbooks/web-default.md +96 -0
- package/assets/slopmachine/templates/AGENTS.md +41 -3
- package/assets/slopmachine/templates/CLAUDE.md +111 -0
- package/assets/slopmachine/utils/claude_create_session.mjs +1 -0
- package/assets/slopmachine/utils/claude_live_channel.mjs +188 -0
- package/assets/slopmachine/utils/claude_live_common.mjs +406 -0
- package/assets/slopmachine/utils/claude_live_hook.py +47 -0
- package/assets/slopmachine/utils/claude_live_launch.mjs +181 -0
- package/assets/slopmachine/utils/claude_live_status.mjs +25 -0
- package/assets/slopmachine/utils/claude_live_stop.mjs +45 -0
- package/assets/slopmachine/utils/claude_live_turn.mjs +250 -0
- package/assets/slopmachine/utils/claude_resume_session.mjs +1 -0
- package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.mjs +23 -0
- package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.sh +5 -0
- package/assets/slopmachine/utils/claude_worker_common.mjs +224 -4
- package/assets/slopmachine/utils/cleanup_delivery_artifacts.py +4 -0
- package/assets/slopmachine/utils/export_ai_session.mjs +1 -1
- package/assets/slopmachine/utils/normalize_claude_session.py +153 -0
- package/assets/slopmachine/utils/package_claude_session.mjs +96 -0
- package/assets/slopmachine/utils/prepare_strict_audit_workspace.mjs +65 -0
- package/package.json +1 -1
- package/src/constants.js +42 -3
- package/src/init.js +173 -28
- package/src/install.js +75 -0
- package/src/send-data.js +56 -57
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Platform Family Scaffold Matrix
|
|
2
|
+
|
|
3
|
+
Use this matrix to choose a real scaffold family for Android, iOS, and desktop requests.
|
|
4
|
+
Do **not** collapse these into one generic `mobile` or `desktop` bucket: the bootstrap path, Linux-proof boundary, and wrapper-script meaning differ too much across families.
|
|
5
|
+
|
|
6
|
+
## Family selection rule
|
|
7
|
+
|
|
8
|
+
1. follow the prompt and existing repo first
|
|
9
|
+
2. choose a concrete family, not a generic platform bucket
|
|
10
|
+
3. apply that family's official/bootstrap path and proof boundary honestly
|
|
11
|
+
4. keep `docker compose up --build` and `./run_tests.sh` real for every family
|
|
12
|
+
5. treat `./run_app.sh` as an optional helper only
|
|
13
|
+
|
|
14
|
+
## Current defaults vs backlog
|
|
15
|
+
|
|
16
|
+
- **current default families**
|
|
17
|
+
- `android-java-views`
|
|
18
|
+
- `ios-expo-react-native`
|
|
19
|
+
- `desktop-electron-vite`
|
|
20
|
+
- **current opt-in families when the prompt or repo clearly requires them**
|
|
21
|
+
- `android-kotlin-views`
|
|
22
|
+
- `ios-native-swift` → see [`ios-native-swift.md`](./ios-native-swift.md)
|
|
23
|
+
- **current non-default families with a concrete playbook**
|
|
24
|
+
- `android-kotlin-compose` → see [`android-kotlin-compose.md`](./android-kotlin-compose.md)
|
|
25
|
+
- `ios-native-objective-c` → see [`ios-native-objective-c.md`](./ios-native-objective-c.md)
|
|
26
|
+
- **future / non-default backlog families**
|
|
27
|
+
- none
|
|
28
|
+
|
|
29
|
+
## Android families
|
|
30
|
+
|
|
31
|
+
| Family | Use when | Official/bootstrap/init path | Safe default versions/config direction | What `docker compose up --build` means | What `./run_tests.sh` means | `./run_app.sh` helpful? | Honest Linux proof | Status |
|
|
32
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
33
|
+
| `android-java-views` | prompt says native Android and does not require Kotlin or Compose | official Android Studio phone/tablet **Empty Views Activity** in **Java**; for automation, commit the equivalent Gradle/AGP skeleton rather than pretending there is a stable non-interactive official CLI | AGP `8.5.x`, Gradle `8.7`, Java `17`, `compileSdk = 34`, `targetSdk = 34`, `minSdk = 29`, XML Views | containerized Gradle build path that at least lints and assembles a debug APK or equivalent artifact; no emulator claims | containerized lint + assemble + JVM/Robolectric tests + schema verification when Room exists | **yes**; useful to normalize `JAVA_HOME` / `ANDROID_HOME`, build a debug APK, and optionally install via `adb` when available | a real APK/debug artifact is produced and JVM tests pass on Linux; no device/emulator proof claimed | **current default, experimentally verified** |
|
|
34
|
+
| `android-kotlin-views` | prompt or repo explicitly requires Kotlin but not Compose | official Android Studio **Empty Views Activity** in **Kotlin** | same Android baseline as Java Views, but pin one AGP-compatible Kotlin plugin version and keep XML Views unless prompt says otherwise | same containerized assemble/lint artifact path as Java Views | same broad path as Java Views, but using Kotlin sources | **yes**; same value as Java family | Kotlin Android app assembles on Linux and passes JVM/Robolectric proof without pretending emulator coverage | **current opt-in** |
|
|
35
|
+
| `android-kotlin-compose` | prompt explicitly requires Compose or existing repo already uses Compose | official Android Studio **Empty Activity** / Compose-first app template in **Kotlin** | keep AGP `8.5.x`, Gradle `8.7`, Java `17`, SDK levels aligned with other Android families; pin one AGP-compatible Kotlin version and one tested stable Compose BOM; keep Material 3 defaults | containerized Compose-capable build path that assembles the app and emits the artifact; do not pretend `docker compose` proves interactive device UX | lint + assemble + JVM/unit coverage that is honest on Linux; only include instrumentation/device checks when a real device/emulator path exists outside the portable baseline | **yes**; useful for local build/install convenience | Compose code now assembles on Linux, `docker compose up --build` reaches artifact-serving healthy state, and containerized lint/JVM tests pass; still no emulator/device proof | **current opt-in, experimentally verified** |
|
|
36
|
+
|
|
37
|
+
## iOS families
|
|
38
|
+
|
|
39
|
+
| Family | Use when | Official/bootstrap/init path | Safe default versions/config direction | What `docker compose up --build` means | What `./run_tests.sh` means | `./run_app.sh` helpful? | Honest Linux proof | Status |
|
|
40
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
41
|
+
| `ios-expo-react-native` | work is iOS-targeted but running from Linux, and the prompt does not require a native-only iOS codebase | `npx create-expo-app@latest <app> --template blank-typescript` | Expo-managed workflow, TypeScript, current stable Expo SDK, Jest, React Native Testing Library; keep native modules minimal until a real native requirement exists | containerized Expo-oriented baseline such as dependency install plus Expo dev-server startup and/or `expo export --platform ios`; this proves shared RN wiring, not native iOS runtime | `tsc --noEmit`, `jest --runInBand`, and `expo export --platform ios` or equivalent portable iOS build-shape checks | **yes**; useful to wrap `npx expo start` and print the closest device-adjacent flow | shared JS/TS code, tests, and iOS-targeted Expo export pass on Linux; no Xcode, CocoaPods, simulator, signing, or archive proof claimed | **current default on Linux** |
|
|
42
|
+
| `ios-native-swift` | prompt explicitly requires native Swift iOS or repo already is a native Swift iOS app | official Xcode **App** template in **Swift**; UIKit vs SwiftUI follows prompt/repo; detailed rules live in [`ios-native-swift.md`](./ios-native-swift.md) | treat Xcode/iOS SDK selection as a macOS checkpoint; on Linux, only portable SwiftPM/shared-module defaults may be pinned and tested honestly | on Linux, this means a real **partial-proof** container path: portable SwiftPM build/test when such modules exist, plus static repo-shape validation; it must **not** claim `.app`, simulator, or archive proof | portable Swift package tests, build/lint when available, and static validation only; if there are no portable modules, the script must say native proof requires macOS/Xcode rather than faking success | **usually no** on Linux; only add it if it cleanly hands off to a documented macOS/Xcode flow | shared SwiftPM modules and static Xcode-shape validation are experimentally verified on Linux; the actual iOS app target remains unproven until a real macOS/Xcode checkpoint | **current opt-in, experimentally verified partial-proof** |
|
|
43
|
+
| `ios-native-objective-c` | prompt explicitly requires native Objective-C iOS or repo already is Objective-C | official Xcode **App** template in **Objective-C**; detailed Linux-boundary rules live in [`ios-native-objective-c.md`](./ios-native-objective-c.md) | same macOS/Xcode dependency as native Swift; do not invent a Linux-first default beyond portable shared modules if they exist | on Linux, this means a real verification/support container for static checks and any portable modules only; never pretend it builds or runs the native iOS app | static validation plus any portable shared-module tests only; if there are no portable modules, keep this as a real static gate rather than fake native success | **usually no** on Linux; only add it when it is an honest macOS/Xcode handoff helper | static Xcode-project validation is experimentally verified on Linux; native iOS app proof is still blocked on macOS/Xcode | **current explicit opt-in, experimentally verified partial-proof** |
|
|
44
|
+
|
|
45
|
+
### iOS honesty boundary
|
|
46
|
+
|
|
47
|
+
For native Swift and Objective-C families, Linux is a **partial-proof** environment only.
|
|
48
|
+
Honest proof on Linux does **not** include Xcode build success, CocoaPods integration quality, simulator behavior, signing, archives, or App Store readiness.
|
|
49
|
+
|
|
50
|
+
## Desktop families
|
|
51
|
+
|
|
52
|
+
| Family | Use when | Official/bootstrap/init path | Safe default versions/config direction | What `docker compose up --build` means | What `./run_tests.sh` means | `./run_app.sh` helpful? | Honest Linux proof | Status |
|
|
53
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
54
|
+
| `desktop-electron-vite` | prompt says desktop app and does not require another desktop shell | `npm create @quick-start/electron@latest <app> -- --template vanilla-ts`, then harden/pin the generated baseline | Electron + Vite + TypeScript, repo-tested pinned versions, `contextIsolation` on, no unnecessary `nodeIntegration`, explicit preload bridge, Linux packaging kept to `electron-builder --linux dir` at scaffold time | containerized build/package/smoke gate: install deps, build renderer/main, create unpacked Linux output, and run one headless smoke under Xvfb/Playwright or equivalent | unit/renderer/main tests plus the headless Electron smoke/build check | **yes**; useful for host-side launch convenience | an unpacked Linux Electron build launches a real window process headlessly and passes smoke/build checks | **current default, experimentally verified** |
|
|
55
|
+
| `desktop-tauri` | prompt explicitly requires Tauri, Rust footprint, or existing repo already uses Tauri | official Tauri bootstrap such as `npm create tauri-app@latest <app>` | Tauri `2.x`, Rust stable, TS frontend by default, Linux WebView/runtime dependencies documented explicitly; do not default to Tauri when prompt is open | containerized Rust + frontend build path that emits a Linux binary/bundle when dependencies permit; keep claims limited to what the container actually proves | `cargo test` plus frontend tests and static checks such as clippy/typecheck as appropriate | **yes** when host Rust/WebView deps are present | Linux now proves a Tauri build/bundle/startup baseline honestly through Docker, but this remains an explicit opt-in family rather than the generic default | **current non-default, experimentally verified** |
|
|
56
|
+
|
|
57
|
+
## Wrapper meaning by family
|
|
58
|
+
|
|
59
|
+
- `docker compose up --build`
|
|
60
|
+
- always means a **real** containerized baseline path
|
|
61
|
+
- for Android: build/lint/test/artifact proof without pretending emulator runtime
|
|
62
|
+
- for Expo iOS on Linux: shared-code/runtime-export proof without pretending Xcode proof
|
|
63
|
+
- for native iOS families: only partial Linux proof; for Swift, follow [`ios-native-swift.md`](./ios-native-swift.md) and do not choose it as a default; for Objective-C, follow [`ios-native-objective-c.md`](./ios-native-objective-c.md) and keep it explicit opt-in only
|
|
64
|
+
- for desktop: build/package/headless-smoke proof rather than pretending a container is the final end-user desktop runtime
|
|
65
|
+
- `./run_tests.sh`
|
|
66
|
+
- always means the broad portable verification path
|
|
67
|
+
- should be the command an owner can run on a clean Linux machine with Docker
|
|
68
|
+
- must never silently downgrade into `NO-SOURCE`, placeholder, or documentation-only success
|
|
69
|
+
- `./run_app.sh`
|
|
70
|
+
- useful for Android, Expo, Electron, and often Tauri
|
|
71
|
+
- usually **not** useful for native iOS-on-Linux families unless it is explicitly a macOS/Xcode handoff helper
|
|
72
|
+
- never replaces the Docker baseline contract
|
|
73
|
+
|
|
74
|
+
## Decision summary
|
|
75
|
+
|
|
76
|
+
- when the prompt says **Android**, split into `android-java-views`, `android-kotlin-views`, or `android-kotlin-compose` instead of one generic native-mobile bucket
|
|
77
|
+
- when the prompt says **iOS on Linux**, default to `ios-expo-react-native`; only choose native Swift or Objective-C families when the prompt explicitly requires them and the proof boundary is documented honestly; both native families now have experimentally verified partial-proof Linux baselines
|
|
78
|
+
- when the prompt says **desktop**, default to `desktop-electron-vite`; treat Tauri as explicit opt-in, and currently only partial-lab-state rather than fully verified
|
|
79
|
+
- if a family cannot produce honest Linux proof for the requested baseline, keep it out of the default path and label it backlog or exception-driven
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Scaffold Playbook Selection Matrix
|
|
2
|
+
|
|
3
|
+
Use this as owner-side reference when composing the scaffold request.
|
|
4
|
+
|
|
5
|
+
## Selection order
|
|
6
|
+
|
|
7
|
+
1. follow the original prompt and existing repo first
|
|
8
|
+
2. read `docker-shared-contract.md`
|
|
9
|
+
3. if the stack is not directly covered, read `generic-unknown-tech-guide.md`
|
|
10
|
+
4. choose the primary platform family using `platform-family-matrix.md`
|
|
11
|
+
5. choose the frontend family using `frontend-family-matrix.md` when a frontend surface exists
|
|
12
|
+
6. choose the backend family and database module using `backend-family-matrix.md` and `database-module-matrix.md` when a backend surface exists
|
|
13
|
+
7. choose the matching concrete scaffold playbook for the selected family default
|
|
14
|
+
8. add any scaffold-time overlays from `overlay-module-matrix.md`
|
|
15
|
+
9. choose the framework bootstrap path that best matches the prompt
|
|
16
|
+
10. restate the relevant directives in the developer prompt instead of passing external file paths
|
|
17
|
+
|
|
18
|
+
## Shared references
|
|
19
|
+
|
|
20
|
+
- shared Docker contract:
|
|
21
|
+
- `docker-shared-contract.md`
|
|
22
|
+
- generic fallback guide:
|
|
23
|
+
- `generic-unknown-tech-guide.md`
|
|
24
|
+
- family matrices:
|
|
25
|
+
- `frontend-family-matrix.md`
|
|
26
|
+
- `backend-family-matrix.md`
|
|
27
|
+
- `database-module-matrix.md`
|
|
28
|
+
- `platform-family-matrix.md`
|
|
29
|
+
- `overlay-module-matrix.md`
|
|
30
|
+
|
|
31
|
+
## Primary playbooks
|
|
32
|
+
|
|
33
|
+
- open-ended web product with no narrower family already selected:
|
|
34
|
+
- `web-default.md`
|
|
35
|
+
- for explicit frontend families, prefer `frontend-baseline.md`, `vue-vite-default.md`, or `angular-default.md` as appropriate
|
|
36
|
+
- for explicit backend families, prefer `backend-baseline.md`, `fastapi-default.md`, `spring-boot-default.md`, `django-default.md`, `laravel-default.md`, or `go-chi-default.md` as appropriate
|
|
37
|
+
- for explicit Laravel server-driven UI work, prefer `livewire-default.md`
|
|
38
|
+
- native Android request:
|
|
39
|
+
- `android-native-java.md` (current experimentally verified default)
|
|
40
|
+
- `android-kotlin-views.md` when the prompt explicitly requires Kotlin + Views
|
|
41
|
+
- `android-kotlin-compose.md` when the prompt explicitly requires Compose; now experimentally verified
|
|
42
|
+
- if the prompt explicitly requires Kotlin or Compose, keep the Android runtime/test contract but adapt the language/UI defaults accordingly
|
|
43
|
+
- cross-platform mobile request with no native-only requirement:
|
|
44
|
+
- `expo-react-native-default.md`
|
|
45
|
+
- desktop app request:
|
|
46
|
+
- `electron-vite-default.md` (current experimentally verified default)
|
|
47
|
+
- `tauri-default.md` only when the prompt explicitly requires Tauri; experimentally verified but still explicit opt-in only
|
|
48
|
+
- iOS-targeted work on Linux:
|
|
49
|
+
- `ios-linux-portable.md`
|
|
50
|
+
- if the prompt explicitly requires native Swift, use `ios-native-swift.md` (experimentally verified partial-proof baseline)
|
|
51
|
+
- if the prompt explicitly requires native Objective-C, use `ios-native-objective-c.md` (experimentally verified partial-proof baseline)
|
|
52
|
+
|
|
53
|
+
## Framework bootstrap guidance
|
|
54
|
+
|
|
55
|
+
- when the prompt explicitly names a framework with a strong official starter, use that framework's official or best-known bootstrap path and then apply the matching playbook contract
|
|
56
|
+
- examples:
|
|
57
|
+
- Next.js, Nuxt, Laravel, Rails, Django, Expo, Electron
|
|
58
|
+
- when the prompt names only a language or only a placeholder label, resolve that through the corresponding family matrix before picking a bootstrap command
|
|
59
|
+
- when the prompt leaves the framework open, use the safest package default for that platform family rather than inventing a custom starter
|
|
60
|
+
|
|
61
|
+
## Runtime contract reminders
|
|
62
|
+
|
|
63
|
+
- web always requires working `docker compose up --build`
|
|
64
|
+
- web always requires containerized `./run_tests.sh`
|
|
65
|
+
- Android, mobile, iOS, and desktop projects also require working `docker compose up --build` plus containerized `./run_tests.sh`
|
|
66
|
+
- for non-web app platforms, the Docker runtime command may start a meaningful build, artifact, preview, or support environment rather than pretending to be native runtime proof
|
|
67
|
+
- `./run_app.sh` may still exist for non-web local convenience, but it does not replace the Docker-based baseline contract
|
|
68
|
+
|
|
69
|
+
## Scaffold stop rule
|
|
70
|
+
|
|
71
|
+
Stop scaffold once the baseline stack, required technologies, runtime contract, wrapper scripts, minimal real tests, and honest README are in place.
|
|
72
|
+
Do not start prompt-specific feature implementation during scaffold unless the runtime baseline genuinely depends on it.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Spring Boot Default Scaffold Playbook
|
|
2
|
+
|
|
3
|
+
Use this playbook when the prompt explicitly asks for Spring Boot, Java backend conventions, or a JVM-first backend baseline.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Create a Spring Boot scaffold baseline that:
|
|
8
|
+
|
|
9
|
+
- starts from the official Spring Initializr bootstrap path
|
|
10
|
+
- keeps defaults pinned and boring
|
|
11
|
+
- proves one real API plus one real persistence path
|
|
12
|
+
- exposes `docker compose up --build` as the runtime contract
|
|
13
|
+
- exposes `./run_tests.sh` as the broad containerized verification path
|
|
14
|
+
- stays baseline-only and honest about exclusions
|
|
15
|
+
|
|
16
|
+
Verified lab: `/Users/yohannesakd/code/eaglepoint/demonstration/scaffold-lab/spring-boot-baseline`
|
|
17
|
+
|
|
18
|
+
## Chosen baseline defaults
|
|
19
|
+
|
|
20
|
+
- Spring Boot `3.5.13`
|
|
21
|
+
- Java `21`
|
|
22
|
+
- Maven Wrapper `3.9.14`
|
|
23
|
+
- dependencies: `web`, `actuator`, `data-jpa`, `validation`, `h2`
|
|
24
|
+
- database pattern: file-backed H2 stored in Docker-managed volumes
|
|
25
|
+
|
|
26
|
+
Why these defaults:
|
|
27
|
+
|
|
28
|
+
- Spring Initializr is the official bootstrap path and yields the wrapper, parent BOM, and baseline Maven layout cleanly
|
|
29
|
+
- Spring Boot `3.5.x` is the safer practical line than jumping straight to Boot `4.x` for a neutral baseline
|
|
30
|
+
- Java `21` is a current LTS choice with wide container availability
|
|
31
|
+
- H2 file mode gives real persistence without introducing credentials or a second infrastructure service
|
|
32
|
+
|
|
33
|
+
## Official bootstrap command
|
|
34
|
+
|
|
35
|
+
Use the official starter generator, then adapt only what is needed for Docker, DB wiring, tests, and README honesty:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
curl -fsSL "https://start.spring.io/starter.zip?type=maven-project&language=java&bootVersion=3.5.13&baseDir=spring-boot-baseline&groupId=com.eaglepoint&artifactId=spring-boot-baseline&name=spring-boot-baseline&description=Verified%20Spring%20Boot%20baseline%20lab&packageName=com.eaglepoint.springbaseline&packaging=jar&javaVersion=21&dependencies=web,actuator,data-jpa,h2,validation" -o /tmp/spring-boot-baseline.zip
|
|
39
|
+
unzip -q /tmp/spring-boot-baseline.zip -d .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Safe config / database pattern
|
|
43
|
+
|
|
44
|
+
- do not require `.env`
|
|
45
|
+
- import optional runtime config from `/runtime/config/application-runtime.properties`
|
|
46
|
+
- generate that file at container startup and before containerized tests
|
|
47
|
+
- point Spring Data at `jdbc:h2:file:/runtime/db/spring-boot-baseline...`
|
|
48
|
+
- keep runtime config and DB files in named Docker volumes
|
|
49
|
+
- expose only the app port to loopback with a random host port
|
|
50
|
+
|
|
51
|
+
This is the recommended local-only baseline when the prompt does not require Postgres/MySQL yet.
|
|
52
|
+
|
|
53
|
+
## Docker / Compose pattern
|
|
54
|
+
|
|
55
|
+
- `compose.yaml` with one `app` service and one `test` service behind the `test` profile
|
|
56
|
+
- multi-stage Dockerfile: Maven test/build stages plus a smaller runtime stage
|
|
57
|
+
- real app healthcheck against `http://127.0.0.1:8080/actuator/health`
|
|
58
|
+
- host port binding: `127.0.0.1::8080`
|
|
59
|
+
- named volumes for runtime config and file-backed H2 state
|
|
60
|
+
|
|
61
|
+
## Minimum API surface
|
|
62
|
+
|
|
63
|
+
At scaffold time include at least:
|
|
64
|
+
|
|
65
|
+
- `GET /health` proving app boot and DB query success
|
|
66
|
+
- `POST /items` creating one persisted record
|
|
67
|
+
- `GET /items` listing persisted records
|
|
68
|
+
|
|
69
|
+
This is enough to prove API routing, JSON handling, persistence, and Docker readiness without pretending the app is product-ready.
|
|
70
|
+
|
|
71
|
+
## Minimum test floor
|
|
72
|
+
|
|
73
|
+
- `./run_tests.sh` must start the app container, wait for health, and smoke the real routes with `curl`
|
|
74
|
+
- the test container must run `./mvnw -q verify`
|
|
75
|
+
- JUnit tests should use `@SpringBootTest(webEnvironment = RANDOM_PORT)` or equivalent so HTTP and DB wiring are both exercised
|
|
76
|
+
|
|
77
|
+
## README requirements
|
|
78
|
+
|
|
79
|
+
`README.md` must explicitly state:
|
|
80
|
+
|
|
81
|
+
- that the scaffold is baseline-only
|
|
82
|
+
- the pinned Spring Boot / Java / Maven defaults
|
|
83
|
+
- required runtime command: `docker compose up --build`
|
|
84
|
+
- required broad test command: `./run_tests.sh`
|
|
85
|
+
- how the runtime config file is generated without `.env`
|
|
86
|
+
- why H2 file mode is the chosen default database pattern
|
|
87
|
+
- what is intentionally excluded
|
|
88
|
+
|
|
89
|
+
## Verification commands actually run
|
|
90
|
+
|
|
91
|
+
Experimentally verified: **yes**.
|
|
92
|
+
|
|
93
|
+
Commands run in `/Users/yohannesakd/code/eaglepoint/demonstration/scaffold-lab/spring-boot-baseline`:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
docker compose build
|
|
97
|
+
docker compose up --build -d && docker compose ps && docker compose port app 8080
|
|
98
|
+
python3 - <<'PY'
|
|
99
|
+
import json, time, urllib.request
|
|
100
|
+
base = 'http://127.0.0.1:32785'
|
|
101
|
+
last_error = None
|
|
102
|
+
for _ in range(60):
|
|
103
|
+
try:
|
|
104
|
+
with urllib.request.urlopen(base + '/health', timeout=5) as response:
|
|
105
|
+
payload = json.load(response)
|
|
106
|
+
if payload.get('status') == 'ok' and payload.get('database') == 'ok':
|
|
107
|
+
print('HEALTH', json.dumps(payload, separators=(',', ':')))
|
|
108
|
+
break
|
|
109
|
+
except Exception as exc:
|
|
110
|
+
last_error = exc
|
|
111
|
+
time.sleep(2)
|
|
112
|
+
else:
|
|
113
|
+
raise SystemExit(f'Health endpoint never became ready: {last_error}')
|
|
114
|
+
|
|
115
|
+
req = urllib.request.Request(base + '/items', data=b'{"name":"manual-smoke-item"}', headers={'Content-Type': 'application/json'}, method='POST')
|
|
116
|
+
with urllib.request.urlopen(req, timeout=5) as response:
|
|
117
|
+
created = json.load(response)
|
|
118
|
+
print('CREATE', json.dumps(created, separators=(',', ':')))
|
|
119
|
+
with urllib.request.urlopen(base + '/items', timeout=5) as response:
|
|
120
|
+
items = json.load(response)
|
|
121
|
+
print('LIST', json.dumps(items, separators=(',', ':')))
|
|
122
|
+
PY
|
|
123
|
+
docker compose down --volumes --remove-orphans
|
|
124
|
+
./run_tests.sh
|
|
125
|
+
python3 - <<'PY'
|
|
126
|
+
import json
|
|
127
|
+
import signal
|
|
128
|
+
import subprocess
|
|
129
|
+
import time
|
|
130
|
+
import urllib.request
|
|
131
|
+
|
|
132
|
+
cwd = '/Users/yohannesakd/code/eaglepoint/demonstration/scaffold-lab/spring-boot-baseline'
|
|
133
|
+
proc = subprocess.Popen(['docker', 'compose', 'up', '--build'], cwd=cwd)
|
|
134
|
+
error = None
|
|
135
|
+
try:
|
|
136
|
+
deadline = time.time() + 240
|
|
137
|
+
while time.time() < deadline:
|
|
138
|
+
try:
|
|
139
|
+
port_output = subprocess.check_output(['docker', 'compose', 'port', 'app', '8080'], cwd=cwd, stderr=subprocess.DEVNULL, text=True).strip()
|
|
140
|
+
if port_output:
|
|
141
|
+
host, port = port_output.rsplit(':', 1)
|
|
142
|
+
base_url = f'http://127.0.0.1:{port}'
|
|
143
|
+
with urllib.request.urlopen(base_url + '/health', timeout=3) as response:
|
|
144
|
+
payload = json.load(response)
|
|
145
|
+
if payload.get('status') == 'ok' and payload.get('database') == 'ok':
|
|
146
|
+
print(f'interactive compose reached ready health at {base_url}')
|
|
147
|
+
break
|
|
148
|
+
except Exception as exc:
|
|
149
|
+
error = exc
|
|
150
|
+
time.sleep(2)
|
|
151
|
+
else:
|
|
152
|
+
raise RuntimeError(f'interactive docker compose up --build never reached readiness: {error}')
|
|
153
|
+
finally:
|
|
154
|
+
proc.send_signal(signal.SIGINT)
|
|
155
|
+
try:
|
|
156
|
+
proc.wait(timeout=30)
|
|
157
|
+
except subprocess.TimeoutExpired:
|
|
158
|
+
proc.kill()
|
|
159
|
+
proc.wait(timeout=30)
|
|
160
|
+
subprocess.run(['docker', 'compose', 'down', '--volumes', '--remove-orphans'], cwd=cwd, check=True)
|
|
161
|
+
PY
|
|
162
|
+
docker compose --profile test run --rm test sh -lc 'sh /workspace/scripts/bootstrap_config.sh && ./mvnw -U test'
|
|
163
|
+
docker compose down --volumes --remove-orphans
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Observed results:
|
|
167
|
+
|
|
168
|
+
- `docker compose up --build -d` published the app on `127.0.0.1:32785`
|
|
169
|
+
- smoke verification returned healthy JSON plus a persisted `manual-smoke-item`
|
|
170
|
+
- `./run_tests.sh` passed and printed `Spring Boot baseline smoke and container tests passed at http://127.0.0.1:32787`
|
|
171
|
+
- interactive `docker compose up --build` reached ready health at `http://127.0.0.1:32789`
|
|
172
|
+
- `docker compose --profile test run --rm test ... ./mvnw -U test` reported `Tests run: 2, Failures: 0, Errors: 0, Skipped: 0` and `BUILD SUCCESS`
|
|
173
|
+
|
|
174
|
+
## Acceptance checklist
|
|
175
|
+
|
|
176
|
+
Baseline is acceptable when:
|
|
177
|
+
|
|
178
|
+
- `docker compose up --build` works
|
|
179
|
+
- `./run_tests.sh` works
|
|
180
|
+
- a real API route and a real persistence route are verified
|
|
181
|
+
- the Docker path does not require `.env`
|
|
182
|
+
- the README is honest about scope and exclusions
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Tauri Default Scaffold Playbook
|
|
2
|
+
|
|
3
|
+
Use this playbook only when the prompt explicitly requires Tauri or the existing repo is already Tauri-based.
|
|
4
|
+
|
|
5
|
+
## Current status
|
|
6
|
+
|
|
7
|
+
This family is now **experimentally verified** for an honest Linux Docker baseline.
|
|
8
|
+
|
|
9
|
+
Verified lab:
|
|
10
|
+
|
|
11
|
+
- `/Users/yohannesakd/code/eaglepoint/demonstration/scaffold-lab/tauri-baseline`
|
|
12
|
+
|
|
13
|
+
## What was achieved in the verified lab
|
|
14
|
+
|
|
15
|
+
The verified lab now proves all of the following:
|
|
16
|
+
|
|
17
|
+
- Tauri + Vite + TypeScript scaffold exists
|
|
18
|
+
- Rust shell under `src-tauri/` exists
|
|
19
|
+
- Dockerfile and Compose report-service strategy exist
|
|
20
|
+
- `run_tests.sh` exists
|
|
21
|
+
- built frontend assets exist under `dist/`
|
|
22
|
+
- verification helper scripts exist under `.docker/`
|
|
23
|
+
- README documents a plausible Linux Docker verification boundary
|
|
24
|
+
- `docker compose up --build --wait` reaches a stable healthy report service
|
|
25
|
+
- containerized `./run_tests.sh` passes
|
|
26
|
+
- a Linux `.deb` bundle is generated and preserved under the verified artifact path
|
|
27
|
+
- the packaged Tauri binary passes the documented headless smoke path
|
|
28
|
+
|
|
29
|
+
## Safe default stack
|
|
30
|
+
|
|
31
|
+
- Tauri `2.x`
|
|
32
|
+
- Vite `8.x`
|
|
33
|
+
- TypeScript `6.x`
|
|
34
|
+
- Rust stable compatible with the chosen Tauri version
|
|
35
|
+
|
|
36
|
+
## Runtime contract
|
|
37
|
+
|
|
38
|
+
- required Docker command: `docker compose up --build`
|
|
39
|
+
- required broad test command: `./run_tests.sh`
|
|
40
|
+
- both are now confirmed working in the verified lab
|
|
41
|
+
|
|
42
|
+
## Intended Docker strategy
|
|
43
|
+
|
|
44
|
+
This family should follow the desktop shared contract with a Tauri-specific interpretation:
|
|
45
|
+
|
|
46
|
+
1. build frontend assets inside Docker
|
|
47
|
+
2. compile the Rust/Tauri shell inside Docker
|
|
48
|
+
3. produce a meaningful Linux-side artifact or bundle
|
|
49
|
+
4. run one honest Linux smoke/proof path if feasible
|
|
50
|
+
5. converge Compose to a stable report/support service rather than a one-shot exited container
|
|
51
|
+
|
|
52
|
+
## Honest Linux proof boundary
|
|
53
|
+
|
|
54
|
+
For the verified Linux baseline, Docker honestly proves only:
|
|
55
|
+
|
|
56
|
+
- Tauri frontend builds
|
|
57
|
+
- Rust shell compiles
|
|
58
|
+
- Linux-side bundle/build path works
|
|
59
|
+
- any documented smoke path actually runs
|
|
60
|
+
|
|
61
|
+
It should **not** claim full cross-platform desktop UX proof outside Linux.
|
|
62
|
+
|
|
63
|
+
## Verified rerun evidence
|
|
64
|
+
|
|
65
|
+
The successful rerun established these concrete facts:
|
|
66
|
+
|
|
67
|
+
- the multi-stage Docker build completed end-to-end
|
|
68
|
+
- `npm run test:unit` passed
|
|
69
|
+
- `npx tauri build --bundles deb --ci` passed
|
|
70
|
+
- `cargo test --release --manifest-path src-tauri/Cargo.toml` passed
|
|
71
|
+
- the headless smoke path passed under `dbus-run-session` + `Xvfb`
|
|
72
|
+
- verification artifacts were copied out of the cache-mounted build target into `.verified/`
|
|
73
|
+
- the final Compose service reached `Healthy`
|
|
74
|
+
- `./run_tests.sh` returned a verified summary endpoint
|
|
75
|
+
|
|
76
|
+
## Guidance
|
|
77
|
+
|
|
78
|
+
- treat Tauri as explicit opt-in only
|
|
79
|
+
- do not auto-select it for open-ended desktop work yet because Electron remains the lighter generic default
|
|
80
|
+
- it is now safe to treat this family as experimentally verified rather than partial
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Vue Vite Default Scaffold Playbook
|
|
2
|
+
|
|
3
|
+
Use this when the prompt explicitly wants a Vue frontend on top of Vite and does not already require a broader runtime such as Nuxt.
|
|
4
|
+
|
|
5
|
+
## Decision summary
|
|
6
|
+
|
|
7
|
+
- **chosen default:** Vue 3 + Vite + TypeScript via `create-vue`
|
|
8
|
+
- **why:** official Vue-owned bootstrap path, easy to keep baseline-only, and straightforward to verify with Docker plus Vitest component tests
|
|
9
|
+
- **verified runtime:** `docker compose up --build`
|
|
10
|
+
- **verified broad test path:** `./run_tests.sh`
|
|
11
|
+
- **experimentally verified lab:** `/Users/yohannesakd/code/eaglepoint/demonstration/scaffold-lab/vue-vite-baseline`
|
|
12
|
+
|
|
13
|
+
## Official bootstrap matrix
|
|
14
|
+
|
|
15
|
+
| Stack | Official/bootstrap path | Good fit | Why not the default prototype here |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| Vue + Vite via `create-vue` | `npm create vue@latest <project-name> -- --ts --vitest --eslint --bare` | Best Vue-first SPA baseline with first-party feature flags | Chosen default |
|
|
18
|
+
| Vite Vue TypeScript template | `npm create vite@latest <project-name> -- --template vue-ts` | Good fallback when only a raw Vue/Vite template is needed | Slightly less aligned with Vue's recommended starter path |
|
|
19
|
+
| Nuxt | `npm exec nuxi@latest init <project-name>` | Best when SSR, file routing, or server APIs are required | Larger runtime model than a baseline SPA needs |
|
|
20
|
+
|
|
21
|
+
## Evidence basis for the matrix
|
|
22
|
+
|
|
23
|
+
- Vue docs recommend `npm create vue@latest` for scaffolding a Vue SPA locally.
|
|
24
|
+
- The `create-vue` repository describes itself as the recommended way to start a Vite-powered Vue project and documents feature flags such as `--ts`, `--vitest`, `--eslint`, and `--bare`.
|
|
25
|
+
- Vite docs document `npm create vite@latest <project-name> -- --template vue` / `vue-ts` as the direct template path and surface the Vue starter as the official Vue option.
|
|
26
|
+
|
|
27
|
+
For a **Vue-specific frontend baseline**, the safest verified prototype is the smallest official Vue-owned starter that still prewires type-checking, linting, and unit tests. That is `create-vue` with `--ts --vitest --eslint --bare` here.
|
|
28
|
+
|
|
29
|
+
## Chosen default stack and version pins
|
|
30
|
+
|
|
31
|
+
Verified prototype pins:
|
|
32
|
+
|
|
33
|
+
- Node image: `node:22.21.1-alpine3.22`
|
|
34
|
+
- Vue: `3.5.32`
|
|
35
|
+
- Vite: `8.0.8`
|
|
36
|
+
- TypeScript: `6.0.2`
|
|
37
|
+
- `@vitejs/plugin-vue`: `6.0.6`
|
|
38
|
+
- Vitest: `4.1.4`
|
|
39
|
+
- `@vue/test-utils`: `2.4.6`
|
|
40
|
+
- ESLint: `10.2.0`
|
|
41
|
+
- `@vue/eslint-config-typescript`: `14.7.0`
|
|
42
|
+
- `@vitest/eslint-plugin`: `1.6.15`
|
|
43
|
+
- `oxlint`: `1.57.0`
|
|
44
|
+
- `vue-tsc`: `3.2.6`
|
|
45
|
+
- `jsdom`: `29.0.2`
|
|
46
|
+
|
|
47
|
+
Compatibility pins used in this verified lab:
|
|
48
|
+
|
|
49
|
+
- `@emnapi/core`: `1.9.2`
|
|
50
|
+
- `@emnapi/runtime`: `1.9.2`
|
|
51
|
+
- `@rolldown/binding-darwin-arm64`: `1.0.0-rc.15` as an optional dependency for current macOS arm64 local installs
|
|
52
|
+
|
|
53
|
+
## Safe defaults
|
|
54
|
+
|
|
55
|
+
- no `.env` file required
|
|
56
|
+
- no secrets committed
|
|
57
|
+
- baseline-only SPA, not a feature-complete product
|
|
58
|
+
- no router, state store, API client, SSR, or E2E browser tooling by default
|
|
59
|
+
- Docker host port bound to `127.0.0.1` with a random host port to reduce local collisions
|
|
60
|
+
- healthcheck required before the smoke step proceeds
|
|
61
|
+
- exact dependency versions pinned in `package.json` and `package-lock.json`
|
|
62
|
+
|
|
63
|
+
## Docker / Compose pattern
|
|
64
|
+
|
|
65
|
+
Recommended baseline pattern:
|
|
66
|
+
|
|
67
|
+
1. **multi-stage Dockerfile**
|
|
68
|
+
- shared `npm ci` base
|
|
69
|
+
- `development` target runs `vite` on `0.0.0.0:5173`
|
|
70
|
+
- `verify` target runs `npm run verify`
|
|
71
|
+
2. **Compose services**
|
|
72
|
+
- `web` service for `docker compose up --build`
|
|
73
|
+
- `test` service behind a `test` profile for containerized verification
|
|
74
|
+
3. **port strategy**
|
|
75
|
+
- expose only the app port
|
|
76
|
+
- prefer `127.0.0.1::5173` so parallel local worktrees do not collide
|
|
77
|
+
4. **health strategy**
|
|
78
|
+
- wait for `wget http://127.0.0.1:5173` healthcheck before curl smoke tests
|
|
79
|
+
|
|
80
|
+
## Testing baseline
|
|
81
|
+
|
|
82
|
+
Minimum real testing floor for this playbook:
|
|
83
|
+
|
|
84
|
+
- Vitest component tests
|
|
85
|
+
- Vue Test Utils rendering assertions
|
|
86
|
+
- one small interaction test (`Show verification commands` toggle)
|
|
87
|
+
- one containerized smoke check that confirms the app shell is served through Compose
|
|
88
|
+
- one containerized broad path that runs lint + unit tests + production build
|
|
89
|
+
|
|
90
|
+
Suggested scripts:
|
|
91
|
+
|
|
92
|
+
- `npm run test:unit`
|
|
93
|
+
- `npm run verify`
|
|
94
|
+
- `./run_tests.sh`
|
|
95
|
+
|
|
96
|
+
`./run_tests.sh` should:
|
|
97
|
+
|
|
98
|
+
1. build Docker images
|
|
99
|
+
2. start `web`
|
|
100
|
+
3. wait for health
|
|
101
|
+
4. `curl` the served HTML shell
|
|
102
|
+
5. run the `test` profile container
|
|
103
|
+
6. tear down cleanly
|
|
104
|
+
|
|
105
|
+
## README requirements
|
|
106
|
+
|
|
107
|
+
The scaffold `README.md` should explicitly state:
|
|
108
|
+
|
|
109
|
+
- that this is a **baseline scaffold**
|
|
110
|
+
- chosen stack and why it was picked
|
|
111
|
+
- exact bootstrap command used
|
|
112
|
+
- `docker compose up --build`
|
|
113
|
+
- `./run_tests.sh`
|
|
114
|
+
- any optional local iteration commands
|
|
115
|
+
- what is included now vs intentionally deferred
|
|
116
|
+
- no `.env` / no secrets policy
|
|
117
|
+
- main files worth reusing later
|
|
118
|
+
|
|
119
|
+
## Verification commands actually run in the verified prototype
|
|
120
|
+
|
|
121
|
+
User-facing commands verified:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm create vue@latest vue-vite-baseline -- --ts --vitest --eslint --bare
|
|
125
|
+
npm install
|
|
126
|
+
npm run verify
|
|
127
|
+
docker compose up --build
|
|
128
|
+
./run_tests.sh
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Supporting commands used during verification:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
docker compose port web 5173
|
|
135
|
+
curl -fsS http://127.0.0.1:<mapped-port>
|
|
136
|
+
docker compose down --remove-orphans
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Observed verification results in the prototype lab:
|
|
140
|
+
|
|
141
|
+
- local `npm run verify`: passed
|
|
142
|
+
- containerized `./run_tests.sh`: passed
|
|
143
|
+
- runtime `docker compose up --build`: passed and served the app shell
|
|
144
|
+
|
|
145
|
+
## Known caveats
|
|
146
|
+
|
|
147
|
+
- The curl smoke check validates the served HTML shell, not hydrated browser DOM behavior. Keep Vitest component tests for actual UI assertions.
|
|
148
|
+
- `create-vue` is interactive by default; the verified baseline uses feature flags so the scaffold stays reproducible and baseline-only.
|
|
149
|
+
- Nuxt remains a documented alternative, not the verified prototype, because its runtime model is intentionally broader than a baseline SPA.
|
|
150
|
+
|
|
151
|
+
## What to reuse later
|
|
152
|
+
|
|
153
|
+
Reuse these parts directly for later Vue frontend prompts:
|
|
154
|
+
|
|
155
|
+
- the official `create-vue` bootstrap path with baseline-only flags
|
|
156
|
+
- the multi-stage Dockerfile pattern
|
|
157
|
+
- random localhost host-port mapping
|
|
158
|
+
- healthcheck + curl smoke test flow
|
|
159
|
+
- `./run_tests.sh` as the canonical broad-path wrapper
|
|
160
|
+
- the README honesty checklist
|
|
161
|
+
|
|
162
|
+
Do **not** treat this playbook as a signal to pre-add routing, Pinia, auth, API clients, or E2E browsers unless the prompt explicitly needs them.
|