@lazycatcloud/lzc-cli 1.3.14 → 2.0.0-pre.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.
Files changed (101) hide show
  1. package/README.md +30 -5
  2. package/changelog.md +4 -0
  3. package/lib/app/index.js +174 -58
  4. package/lib/app/lpk_build.js +192 -17
  5. package/lib/app/lpk_build_images.js +728 -0
  6. package/lib/app/lpk_create.js +93 -21
  7. package/lib/app/lpk_create_generator.js +144 -9
  8. package/lib/app/lpk_devshell.js +33 -19
  9. package/lib/app/lpk_embed_images.js +257 -0
  10. package/lib/app/lpk_installer.js +14 -7
  11. package/lib/app/project_cp.js +64 -0
  12. package/lib/app/project_deploy.js +33 -0
  13. package/lib/app/project_exec.js +45 -0
  14. package/lib/app/project_info.js +106 -0
  15. package/lib/app/project_log.js +67 -0
  16. package/lib/app/project_runtime.js +261 -0
  17. package/lib/app/project_start.js +100 -0
  18. package/lib/box/index.js +101 -4
  19. package/lib/box/ssh_remote.js +259 -0
  20. package/lib/build_remote.js +22 -0
  21. package/lib/config/index.js +1 -1
  22. package/lib/debug_bridge.js +837 -46
  23. package/lib/docker/index.js +30 -10
  24. package/lib/i18n/index.js +1 -0
  25. package/lib/i18n/locales/en/translation.json +17 -5
  26. package/lib/i18n/locales/zh/translation.json +16 -4
  27. package/lib/lpk/core.js +487 -0
  28. package/lib/lpk/index.js +210 -0
  29. package/lib/sig/core.js +254 -0
  30. package/lib/sig/index.js +88 -0
  31. package/lib/utils.js +3 -1
  32. package/package.json +2 -1
  33. package/scripts/cli.js +4 -0
  34. package/template/_lpk/README.md +11 -3
  35. package/template/_lpk/gui-vnc.manifest.yml.in +27 -0
  36. package/template/_lpk/manifest.yml.in +4 -2
  37. package/template/_lpk/todolist-golang.manifest.yml.in +16 -0
  38. package/template/_lpk/todolist-java.manifest.yml.in +15 -0
  39. package/template/_lpk/todolist-python.manifest.yml.in +15 -0
  40. package/template/_lpk/vue.lzc-build.yml.in +0 -44
  41. package/template/blank/_gitignore +1 -0
  42. package/template/blank/lzc-build.yml +25 -40
  43. package/template/blank/lzc-manifest.yml +14 -7
  44. package/template/golang/Dockerfile +19 -0
  45. package/template/golang/README.md +33 -0
  46. package/template/golang/_gitignore +3 -0
  47. package/template/golang/go.mod +3 -0
  48. package/template/golang/lzc-build.yml +21 -0
  49. package/template/golang/lzc-icon.png +0 -0
  50. package/template/golang/main.go +252 -0
  51. package/template/golang/run.sh +3 -0
  52. package/template/golang/web/index.html +238 -0
  53. package/template/gui-vnc/README.md +19 -0
  54. package/template/gui-vnc/_gitignore +2 -0
  55. package/template/gui-vnc/images/Dockerfile +30 -0
  56. package/template/gui-vnc/images/kasmvnc.yaml +33 -0
  57. package/template/gui-vnc/images/startup-script.desktop +9 -0
  58. package/template/gui-vnc/images/startup-script.sh +6 -0
  59. package/template/gui-vnc/lzc-build.yml +23 -0
  60. package/template/gui-vnc/lzc-icon.png +0 -0
  61. package/template/python/Dockerfile +15 -0
  62. package/template/python/README.md +33 -0
  63. package/template/python/_gitignore +3 -0
  64. package/template/python/app.py +110 -0
  65. package/template/python/lzc-build.yml +21 -0
  66. package/template/python/lzc-icon.png +0 -0
  67. package/template/python/requirements.txt +1 -0
  68. package/template/python/run.sh +3 -0
  69. package/template/python/web/index.html +238 -0
  70. package/template/springboot/Dockerfile +20 -0
  71. package/template/springboot/README.md +33 -0
  72. package/template/springboot/_gitignore +3 -0
  73. package/template/springboot/lzc-build.yml +21 -0
  74. package/template/springboot/lzc-icon.png +0 -0
  75. package/template/springboot/pom.xml +38 -0
  76. package/template/springboot/run.sh +3 -0
  77. package/template/springboot/src/main/java/cloud/lazycat/app/Application.java +132 -0
  78. package/template/springboot/src/main/resources/application.properties +1 -0
  79. package/template/springboot/src/main/resources/static/index.html +238 -0
  80. package/template/vue/README.md +17 -7
  81. package/template/vue/_gitignore +1 -0
  82. package/template/vue/lzc-build.yml +31 -42
  83. package/template/vue/src/App.vue +36 -25
  84. package/template/vue/src/style.css +106 -49
  85. package/template/vue-minidb/README.md +34 -0
  86. package/template/vue-minidb/_gitignore +26 -0
  87. package/template/vue-minidb/index.html +13 -0
  88. package/template/vue-minidb/lzc-build.yml +48 -0
  89. package/template/vue-minidb/lzc-icon.png +0 -0
  90. package/template/vue-minidb/package.json +21 -0
  91. package/template/vue-minidb/public/vite.svg +1 -0
  92. package/template/vue-minidb/src/App.vue +206 -0
  93. package/template/vue-minidb/src/assets/vue.svg +1 -0
  94. package/template/vue-minidb/src/main.ts +5 -0
  95. package/template/vue-minidb/src/style.css +136 -0
  96. package/template/vue-minidb/src/vite-env.d.ts +1 -0
  97. package/template/vue-minidb/tsconfig.app.json +24 -0
  98. package/template/vue-minidb/tsconfig.json +7 -0
  99. package/template/vue-minidb/tsconfig.node.json +22 -0
  100. package/template/vue-minidb/vite.config.ts +10 -0
  101. /package/template/{vue → vue-minidb}/src/components/HelloWorld.vue +0 -0
@@ -0,0 +1,238 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Lazycat Java Todo Template</title>
7
+ <style>
8
+ :root {
9
+ --bg-1: #f8fbff;
10
+ --bg-2: #ecf6ff;
11
+ --card: #ffffff;
12
+ --text: #142033;
13
+ --muted: #4e617b;
14
+ --line: #d8e4f2;
15
+ --brand: #0076d6;
16
+ --brand-2: #00a5a5;
17
+ }
18
+ * { box-sizing: border-box; }
19
+ body {
20
+ margin: 0;
21
+ min-height: 100vh;
22
+ display: grid;
23
+ place-items: center;
24
+ padding: 24px;
25
+ font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
26
+ background: radial-gradient(circle at top right, var(--bg-2), var(--bg-1) 42%);
27
+ color: var(--text);
28
+ }
29
+ .card {
30
+ width: min(920px, 100%);
31
+ background: var(--card);
32
+ border: 1px solid var(--line);
33
+ border-radius: 22px;
34
+ padding: 26px;
35
+ box-shadow: 0 18px 48px rgba(20, 32, 51, 0.08);
36
+ }
37
+ .tag {
38
+ margin: 0;
39
+ color: var(--brand);
40
+ font-weight: 700;
41
+ letter-spacing: .08em;
42
+ text-transform: uppercase;
43
+ font-size: .85rem;
44
+ }
45
+ h1 { margin: 10px 0 12px; font-size: clamp(1.8rem, 3.2vw, 2.7rem); }
46
+ p { margin: 0; color: var(--muted); }
47
+ .btns {
48
+ margin-top: 18px;
49
+ display: flex;
50
+ gap: 10px;
51
+ flex-wrap: wrap;
52
+ }
53
+ a {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ text-decoration: none;
58
+ border-radius: 10px;
59
+ padding: 10px 14px;
60
+ border: 1px solid var(--line);
61
+ color: var(--text);
62
+ font-weight: 600;
63
+ }
64
+ a.primary {
65
+ color: #fff;
66
+ border-color: transparent;
67
+ background: linear-gradient(135deg, var(--brand), var(--brand-2));
68
+ }
69
+ .panel {
70
+ margin-top: 22px;
71
+ border: 1px solid var(--line);
72
+ border-radius: 14px;
73
+ padding: 14px;
74
+ background: #fbfdff;
75
+ }
76
+ .sync-note {
77
+ margin-top: 8px;
78
+ font-size: .92rem;
79
+ }
80
+ .form {
81
+ margin-top: 12px;
82
+ display: flex;
83
+ gap: 10px;
84
+ }
85
+ .form input {
86
+ flex: 1;
87
+ border: 1px solid var(--line);
88
+ border-radius: 10px;
89
+ padding: 10px 12px;
90
+ min-width: 0;
91
+ }
92
+ button {
93
+ border: 1px solid var(--line);
94
+ border-radius: 10px;
95
+ padding: 9px 12px;
96
+ cursor: pointer;
97
+ background: #fff;
98
+ }
99
+ ul {
100
+ margin: 12px 0 0;
101
+ padding: 0;
102
+ list-style: none;
103
+ display: grid;
104
+ gap: 10px;
105
+ }
106
+ li {
107
+ border: 1px solid var(--line);
108
+ border-radius: 10px;
109
+ padding: 10px 12px;
110
+ display: flex;
111
+ justify-content: space-between;
112
+ align-items: center;
113
+ gap: 8px;
114
+ background: #fff;
115
+ }
116
+ label {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 8px;
120
+ }
121
+ .done {
122
+ text-decoration: line-through;
123
+ color: var(--muted);
124
+ }
125
+ .danger {
126
+ color: #a63e37;
127
+ }
128
+ @media (max-width: 640px) {
129
+ .form {
130
+ flex-direction: column;
131
+ }
132
+ li {
133
+ flex-direction: column;
134
+ align-items: flex-start;
135
+ }
136
+ }
137
+ </style>
138
+ </head>
139
+ <body>
140
+ <main class="card">
141
+ <p class="tag">Java Version</p>
142
+ <h1>Todo demo powered by Spring Boot</h1>
143
+ <p>
144
+ This template includes a Java backend and a simple Todo app to help you start fast.
145
+ </p>
146
+
147
+ <div class="btns">
148
+ <a class="primary" href="https://lazycat.cloud/" target="_blank" rel="noreferrer">Visit lazycat.cloud</a>
149
+ <a href="https://developer.lazycat.cloud/" target="_blank" rel="noreferrer">Open Developer Docs</a>
150
+ </div>
151
+
152
+ <section class="panel">
153
+ <strong>Todo quick demo</strong>
154
+ <p class="sync-note">Data syncs automatically across devices when opened with the same app account.</p>
155
+ <div class="form">
156
+ <input id="todoInput" placeholder="Add a task for your app kickoff" />
157
+ <button id="addBtn" type="button">Add</button>
158
+ </div>
159
+ <ul id="todoList"></ul>
160
+ </section>
161
+ </main>
162
+ <script>
163
+ const todoInput = document.getElementById('todoInput');
164
+ const addBtn = document.getElementById('addBtn');
165
+ const todoList = document.getElementById('todoList');
166
+
167
+ async function fetchTodos() {
168
+ const resp = await fetch('/api/todos');
169
+ const data = await resp.json();
170
+ return Array.isArray(data.items) ? data.items : [];
171
+ }
172
+
173
+ function renderTodos(items) {
174
+ todoList.innerHTML = '';
175
+ for (const todo of items) {
176
+ const li = document.createElement('li');
177
+
178
+ const label = document.createElement('label');
179
+ const checkbox = document.createElement('input');
180
+ checkbox.type = 'checkbox';
181
+ checkbox.checked = !!todo.done;
182
+ checkbox.addEventListener('change', async () => {
183
+ await fetch(`/api/todos/${todo.id}/toggle`, { method: 'PUT' });
184
+ await refreshTodos();
185
+ });
186
+
187
+ const span = document.createElement('span');
188
+ span.textContent = todo.title;
189
+ if (todo.done) {
190
+ span.className = 'done';
191
+ }
192
+ label.append(checkbox, span);
193
+
194
+ const delBtn = document.createElement('button');
195
+ delBtn.type = 'button';
196
+ delBtn.className = 'danger';
197
+ delBtn.textContent = 'Delete';
198
+ delBtn.addEventListener('click', async () => {
199
+ await fetch(`/api/todos/${todo.id}`, { method: 'DELETE' });
200
+ await refreshTodos();
201
+ });
202
+
203
+ li.append(label, delBtn);
204
+ todoList.appendChild(li);
205
+ }
206
+ }
207
+
208
+ async function refreshTodos() {
209
+ const items = await fetchTodos();
210
+ renderTodos(items);
211
+ }
212
+
213
+ async function addTodo() {
214
+ const title = todoInput.value.trim();
215
+ if (!title) return;
216
+ await fetch('/api/todos', {
217
+ method: 'POST',
218
+ headers: { 'Content-Type': 'application/json' },
219
+ body: JSON.stringify({ title }),
220
+ });
221
+ todoInput.value = '';
222
+ await refreshTodos();
223
+ }
224
+
225
+ addBtn.addEventListener('click', addTodo);
226
+ todoInput.addEventListener('keyup', async (event) => {
227
+ if (event.key === 'Enter') {
228
+ await addTodo();
229
+ }
230
+ });
231
+
232
+ refreshTodos();
233
+ setInterval(refreshTodos, 2500);
234
+ document.addEventListener('visibilitychange', refreshTodos);
235
+ window.addEventListener('focus', refreshTodos);
236
+ </script>
237
+ </body>
238
+ </html>
@@ -1,14 +1,24 @@
1
1
  # 懒猫云应用
2
2
 
3
- ## 开发
3
+ ## 第一次部署(先看到结果)
4
4
  ```
5
- lzc-cli project devshell
5
+ lzc-cli project deploy
6
+ lzc-cli project info
6
7
  ```
7
8
 
8
- 进入应用容器,并且自动同步当前目录内容到容器
9
- 然后就可以启动你的应用了,例如前端
10
- npm install
11
- npm run dev
9
+ 执行完成后:
10
+ 1. 在微服启动器点击应用图标打开。
11
+ 2. 或根据 `project info` 输出中的域名在手机/PC浏览器访问。
12
+
13
+ ## 修改源码后再次部署
14
+ ```bash
15
+ lzc-cli project deploy
16
+ ```
17
+
18
+ 建议同时打开日志排查问题:
19
+ ```bash
20
+ lzc-cli project log -f
21
+ ```
12
22
 
13
23
  ## 构建
14
24
  ```
@@ -19,7 +29,7 @@ lzc-cli project build -o you-awesome.lpk
19
29
 
20
30
  ## 安装
21
31
  ```
22
- lzc-cli app install you-awesome.lpk
32
+ lzc-cli lpk install you-awesome.lpk
23
33
  ```
24
34
 
25
35
  会安装在你的微服应用中,安装成功后可在懒猫微服启动器中查看!
@@ -23,3 +23,4 @@ pnpm-debug.log*
23
23
  *.sw?
24
24
  .temp
25
25
  .cache
26
+ lzc-build.base.yml
@@ -1,9 +1,9 @@
1
- # 整个文件中,可以通过 ${var} 的方式,使用 manifest 字段指定的文件定义的值
1
+ # 可选基础文件: lzc-build.base.yml(与当前文件同目录,先加载再与当前文件合并)
2
2
 
3
3
  # buildscript
4
4
  # - 可以为构建脚本的路径地址
5
5
  # - 如果构建命令简单,也可以直接写 sh 的命令
6
- buildscript: npm run build
6
+ buildscript: npm install && npm run build
7
7
 
8
8
  # manifest: 指定 lpk 包的 manifest.yml 文件路径
9
9
  manifest: ./lzc-manifest.yml
@@ -11,49 +11,38 @@ manifest: ./lzc-manifest.yml
11
11
  # contentdir: 指定打包的内容,将会打包到 lpk 中
12
12
  contentdir: ./dist
13
13
 
14
+ # images: 在盒子侧构建镜像并写入 lpk v2 images 目录
15
+ # - key 是 image alias
16
+ # - 在 lzc-manifest.yml 中通过 embed:alias 引用
17
+ # - dockerfile 与 dockerfile-content 二选一
18
+ # - context 可选,默认是 dockerfile 所在目录
19
+ # images: 在盒子侧构建镜像并写入 lpk v2 images 目录
20
+ # - key 是 image alias
21
+ # - 在 lzc-manifest.yml 中通过 embed:alias 引用
22
+ # - dockerfile 与 dockerfile-content 二选一
23
+ # - context 可选,默认是 dockerfile 所在目录
24
+ # images:
25
+ # my-nginx:
26
+ # context: ./image
27
+ # dockerfile: ./image/Dockerfile
28
+ # # 可选,默认 registry.lazycat.cloud
29
+ # upstream-match: registry.lazycat.cloud
30
+ # other-image:
31
+ # dockerfile: ./other/Dockerfile
32
+ # inline-image:
33
+ # context: ./
34
+ # dockerfile-content: |
35
+ # FROM alpine:3.20
36
+ # RUN echo "hello"
37
+ #
38
+ # 构建时默认是混合模式:
39
+ # - 先沿父镜像链向上找 upstream
40
+ # - 找到 upstream 后,仅 embed 非 upstream 的 layers
41
+ # - 如果未匹配到 upstream,则自动全量 embed
42
+
14
43
  # pkgout: lpk 包的输出路径
15
44
  pkgout: ./
16
45
 
17
46
  # icon 指定 lpk 包 icon 的路径路径,如果不指定将会警告
18
47
  # icon 仅仅允许 png 后缀的文件
19
48
  icon: ./lzc-icon.png
20
-
21
- # devshell 自定义应用的开发容器环境
22
- # - routes 指定应用容器的访问路由
23
-
24
- # devshell 没有指定 image 的情况,将会默认使用 registry.lazycat.cloud/lzc-cli/devshell:v0.0.5
25
- # devshell:
26
- # routes:
27
- # - /=http://127.0.0.1:8080
28
-
29
- # devshell 指定 image 的情况
30
- # devshell:
31
- # routes:
32
- # - /=http://127.0.0.1:3000
33
- # image: registry.lazycat.cloud/lzc-cli/devshell:v0.0.5
34
-
35
- # devshell 指定构建Dockerfile
36
- # image 字段如果没有定义,将默认使用 ${package}-devshell:${version}
37
- # devshell:
38
- # routes:
39
- # - /=http://127.0.0.1:3000
40
- # image: ${package}-devshell:${version}
41
- # pull_policy: build
42
- # build: .
43
-
44
- # dvshell 指定开发依赖的情况
45
- # 这种情况下,选用 alpine:latest 作为基础镜像,在 dependencies 中添加所需要的开发依赖即可
46
- # 如果 dependencies 和 build 同时存在,将会优先使用 dependencies
47
- devshell:
48
- routes:
49
- - /=http://127.0.0.1:3000
50
- dependencies:
51
- - nodejs
52
- - npm
53
- # setupscript 每次进入到app container后都会执行的配置脚本
54
- # - 可以为脚本的路径地址
55
- # - 如果构建命令简单,也可以直接写 sh 的命令
56
- # setupscript: export GOPROXY=https://goproxy.cn
57
- # setupscript: ./setupscript.sh
58
- setupscript: |
59
- export npm_config_registry=https://registry.npmmirror.com
@@ -1,30 +1,41 @@
1
1
  <script setup lang="ts">
2
- import HelloWorld from './components/HelloWorld.vue'
2
+ const highlights = [
3
+ {
4
+ title: 'Cross-platform by default',
5
+ detail: 'Build once and publish to desktop and mobile experiences in one flow.',
6
+ },
7
+ {
8
+ title: 'Fast local iteration',
9
+ detail: 'Use lzc-cli deploy/start loop to validate UI changes quickly.',
10
+ },
11
+ {
12
+ title: 'Production packaging',
13
+ detail: 'Ship your app as an LPK package with predictable release behavior.',
14
+ },
15
+ ]
3
16
  </script>
4
17
 
5
18
  <template>
6
- <div>
7
- <a href="https://vitejs.dev" target="_blank">
8
- <img src="/vite.svg" class="logo" alt="Vite logo" />
9
- </a>
10
- <a href="https://vuejs.org/" target="_blank">
11
- <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
12
- </a>
13
- </div>
14
- <HelloWorld msg="Vite + Vue" />
15
- </template>
19
+ <main class="hero-shell">
20
+ <section class="hero-card">
21
+ <p class="tag">Lazycat Cloud App Template</p>
22
+ <h1>Welcome to Lazycat Microservice</h1>
23
+ <p class="lead">
24
+ This Vue starter is tailored for Lazycat Cloud. Build your app UI, deploy with lzc-cli,
25
+ and deliver a consistent experience across devices.
26
+ </p>
27
+
28
+ <div class="cta-group">
29
+ <a class="btn primary" href="https://lazycat.cloud/" target="_blank" rel="noreferrer">Visit lazycat.cloud</a>
30
+ <a class="btn" href="https://developer.lazycat.cloud/" target="_blank" rel="noreferrer">Open Developer Docs</a>
31
+ </div>
16
32
 
17
- <style scoped>
18
- .logo {
19
- height: 6em;
20
- padding: 1.5em;
21
- will-change: filter;
22
- transition: filter 300ms;
23
- }
24
- .logo:hover {
25
- filter: drop-shadow(0 0 2em #646cffaa);
26
- }
27
- .logo.vue:hover {
28
- filter: drop-shadow(0 0 2em #42b883aa);
29
- }
30
- </style>
33
+ <ul class="highlight-grid">
34
+ <li v-for="item in highlights" :key="item.title" class="highlight-item">
35
+ <h2>{{ item.title }}</h2>
36
+ <p>{{ item.detail }}</p>
37
+ </li>
38
+ </ul>
39
+ </section>
40
+ </main>
41
+ </template>
@@ -1,79 +1,136 @@
1
1
  :root {
2
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
2
+ --bg-1: #f8fbff;
3
+ --bg-2: #ecf6ff;
4
+ --card: #ffffff;
5
+ --text: #142033;
6
+ --muted: #4e617b;
7
+ --line: #d8e4f2;
8
+ --brand: #0076d6;
9
+ --brand-2: #00a5a5;
10
+ font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
3
11
  line-height: 1.5;
4
12
  font-weight: 400;
5
-
6
- color-scheme: light dark;
7
- color: rgba(255, 255, 255, 0.87);
8
- background-color: #242424;
9
-
10
- font-synthesis: none;
13
+ color: var(--text);
11
14
  text-rendering: optimizeLegibility;
12
15
  -webkit-font-smoothing: antialiased;
13
16
  -moz-osx-font-smoothing: grayscale;
14
17
  }
15
18
 
16
- a {
17
- font-weight: 500;
18
- color: #646cff;
19
- text-decoration: inherit;
20
- }
21
- a:hover {
22
- color: #535bf2;
19
+ * {
20
+ box-sizing: border-box;
23
21
  }
24
22
 
25
23
  body {
26
24
  margin: 0;
27
- display: flex;
28
- place-items: center;
29
25
  min-width: 320px;
26
+ background: radial-gradient(circle at top right, var(--bg-2), var(--bg-1) 42%);
27
+ }
28
+
29
+ #app {
30
30
  min-height: 100vh;
31
31
  }
32
32
 
33
+ .hero-shell {
34
+ min-height: 100vh;
35
+ display: grid;
36
+ place-items: center;
37
+ padding: 28px;
38
+ }
39
+
40
+ .hero-card {
41
+ width: min(960px, 100%);
42
+ background: var(--card);
43
+ border: 1px solid var(--line);
44
+ border-radius: 22px;
45
+ padding: 28px;
46
+ box-shadow: 0 18px 48px rgba(20, 32, 51, 0.08);
47
+ }
48
+
49
+ .tag {
50
+ margin: 0;
51
+ color: var(--brand);
52
+ font-size: 0.85rem;
53
+ font-weight: 700;
54
+ letter-spacing: 0.08em;
55
+ text-transform: uppercase;
56
+ }
57
+
33
58
  h1 {
34
- font-size: 3.2em;
35
- line-height: 1.1;
59
+ margin: 10px 0 12px;
60
+ font-size: clamp(1.8rem, 3.2vw, 2.7rem);
61
+ line-height: 1.15;
36
62
  }
37
63
 
38
- button {
39
- border-radius: 8px;
40
- border: 1px solid transparent;
41
- padding: 0.6em 1.2em;
42
- font-size: 1em;
43
- font-weight: 500;
44
- font-family: inherit;
45
- background-color: #1a1a1a;
46
- cursor: pointer;
47
- transition: border-color 0.25s;
64
+ .lead {
65
+ margin: 0;
66
+ color: var(--muted);
67
+ max-width: 70ch;
68
+ }
69
+
70
+ .cta-group {
71
+ display: flex;
72
+ flex-wrap: wrap;
73
+ gap: 10px;
74
+ margin-top: 18px;
48
75
  }
49
- button:hover {
50
- border-color: #646cff;
76
+
77
+ .btn {
78
+ display: inline-flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ text-decoration: none;
82
+ padding: 10px 14px;
83
+ border-radius: 10px;
84
+ border: 1px solid var(--line);
85
+ color: var(--text);
86
+ font-weight: 600;
87
+ transition: transform 120ms ease, box-shadow 120ms ease;
51
88
  }
52
- button:focus,
53
- button:focus-visible {
54
- outline: 4px auto -webkit-focus-ring-color;
89
+
90
+ .btn:hover {
91
+ transform: translateY(-1px);
92
+ box-shadow: 0 8px 20px rgba(20, 32, 51, 0.08);
55
93
  }
56
94
 
57
- .card {
58
- padding: 2em;
95
+ .btn.primary {
96
+ color: #fff;
97
+ border-color: transparent;
98
+ background: linear-gradient(135deg, var(--brand), var(--brand-2));
59
99
  }
60
100
 
61
- #app {
62
- max-width: 1280px;
63
- margin: 0 auto;
64
- padding: 2rem;
65
- text-align: center;
101
+ .highlight-grid {
102
+ list-style: none;
103
+ margin: 22px 0 0;
104
+ padding: 0;
105
+ display: grid;
106
+ grid-template-columns: repeat(3, minmax(0, 1fr));
107
+ gap: 12px;
66
108
  }
67
109
 
68
- @media (prefers-color-scheme: light) {
69
- :root {
70
- color: #213547;
71
- background-color: #ffffff;
72
- }
73
- a:hover {
74
- color: #747bff;
110
+ .highlight-item {
111
+ border: 1px solid var(--line);
112
+ border-radius: 14px;
113
+ padding: 14px;
114
+ background: #fbfdff;
115
+ }
116
+
117
+ .highlight-item h2 {
118
+ margin: 0;
119
+ font-size: 1rem;
120
+ }
121
+
122
+ .highlight-item p {
123
+ margin: 8px 0 0;
124
+ color: var(--muted);
125
+ font-size: 0.93rem;
126
+ }
127
+
128
+ @media (max-width: 900px) {
129
+ .highlight-grid {
130
+ grid-template-columns: 1fr;
75
131
  }
76
- button {
77
- background-color: #f9f9f9;
132
+
133
+ .hero-card {
134
+ padding: 20px;
78
135
  }
79
136
  }
@@ -0,0 +1,34 @@
1
+ # Lazycat Vue MiniDB App
2
+
3
+ ## First Deploy
4
+ ```bash
5
+ lzc-cli project deploy
6
+ lzc-cli project info
7
+ ```
8
+
9
+ Then open the app from launcher or browser.
10
+
11
+ ## What this template includes
12
+ - Vue 3 + Vite
13
+ - @lazycatcloud/minidb
14
+ - A minimal todo example with add/update/delete
15
+
16
+ ## Redeploy after code changes
17
+ ```bash
18
+ lzc-cli project deploy
19
+ ```
20
+
21
+ ## Troubleshooting
22
+ ```bash
23
+ lzc-cli project log -f
24
+ ```
25
+
26
+ ## Build LPK
27
+ ```bash
28
+ lzc-cli project build -o vue-minidb-app.lpk
29
+ ```
30
+
31
+ ## Install
32
+ ```bash
33
+ lzc-cli lpk install vue-minidb-app.lpk
34
+ ```
@@ -0,0 +1,26 @@
1
+ .DS_Store
2
+ node_modules
3
+ dist
4
+ *.lpk
5
+
6
+ # local env files
7
+ .env.local
8
+ .env.*.local
9
+
10
+ # Log files
11
+ npm-debug.log*
12
+ yarn-debug.log*
13
+ yarn-error.log*
14
+ pnpm-debug.log*
15
+
16
+ # Editor directories and files
17
+ .idea
18
+ .vscode
19
+ *.suo
20
+ *.ntvs*
21
+ *.njsproj
22
+ *.sln
23
+ *.sw?
24
+ .temp
25
+ .cache
26
+ lzc-build.base.yml