@kmlckj/licos-ai-cli 0.0.39 → 0.0.41
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/lib/__templates__/taro/AGENTS.md +12 -3
- package/lib/__templates__/taro/eslint.config.mjs +8 -11
- package/lib/__templates__/taro/src/components/ui/context-menu.tsx +4 -4
- package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +4 -4
- package/lib/__templates__/taro/src/components/ui/menubar.tsx +4 -4
- package/lib/__templates__/taro/src/components/ui/popover.tsx +1 -1
- package/lib/cli.js +1 -1
- package/package.json +1 -1
|
@@ -23,8 +23,9 @@ pnpm remove <package> # 移除依赖
|
|
|
23
23
|
- React hooks 必须从 `react` 导入,例如 `import { useMemo, useState } from 'react'`;不要从 `@tarojs/taro` 导入 `useState`、`useEffect`、`useMemo`。
|
|
24
24
|
- 不要重复导入同一个包。`@tarojs/taro`、`@tarojs/components`、`react`、`lucide-react-taro` 每个文件最多一个 import 语句。
|
|
25
25
|
- 需要在 `src/` 展示构建环境或项目域名时,直接读取全局常量:`LICOS_TARO_ENV || 'unknown'`、`PROJECT_DOMAIN || ''`,不要写 `process.env.TARO_ENV` 或 `process.env.PROJECT_DOMAIN`。
|
|
26
|
-
-
|
|
26
|
+
- 需要引用 `src/assets/...` 源码资源时使用 ESM import,例如 `import logoUrl from '@/assets/images/logo.svg'`,不要在 `src/` 中写 CommonJS `require(...)`。
|
|
27
27
|
- 根目录 `assets/` 是 H5 公开静态目录,不是 `@/assets` 源码别名。放在根 `assets/images/foo.svg` 的文件必须用相对 URL `assets/images/foo.svg`,不要写 `import foo from '@/assets/images/foo.svg'`。只有文件真实存在于 `src/assets/...` 时,才允许从 `@/assets/...` 导入。
|
|
28
|
+
- 部署路径是 IP + `/p/{projectId}/` 子路径,页面中禁止写根路径 `/assets/...` 或上级路径 `../assets/...`。根目录 `assets/` 文件只能写成相对 URL `assets/...`,否则部署后资源会 404。
|
|
28
29
|
- 不要使用浏览器 DOM 全局做资源探测。禁止 `window`、`document`、`new Image()`、`window.Image`、`globalThis.Image`;图片状态通过 Taro `<Image onLoad onError />` 或直接渲染处理。
|
|
29
30
|
- 从第三方图标包导入前必须确认导出存在;不确定时优先使用已验证的 `Package`、`Globe`、`Cpu`、`Layers` 等基础图标,避免引入不存在的命名导出导致构建失败。
|
|
30
31
|
- 禁止输出不完整模板字符串、占位引号或非法 TS 字符串,例如 `"""`、未闭合的引号、未转义的英文单引号。文案中包含引号时使用反引号或正确转义。
|
|
@@ -35,7 +36,6 @@ pnpm remove <package> # 移除依赖
|
|
|
35
36
|
```tsx
|
|
36
37
|
import { View, Text, Image } from '@tarojs/components'
|
|
37
38
|
import Taro, { useLoad } from '@tarojs/taro'
|
|
38
|
-
import logoUrl from '@/assets/images/logo.svg'
|
|
39
39
|
import { Textarea } from '@/components/ui/textarea'
|
|
40
40
|
|
|
41
41
|
export default function IndexPage() {
|
|
@@ -45,6 +45,7 @@ export default function IndexPage() {
|
|
|
45
45
|
|
|
46
46
|
const envName = LICOS_TARO_ENV || 'unknown'
|
|
47
47
|
const projectDomain = PROJECT_DOMAIN || '未配置'
|
|
48
|
+
const logoUrl = 'assets/images/logo.svg'
|
|
48
49
|
|
|
49
50
|
return (
|
|
50
51
|
<View>
|
|
@@ -61,6 +62,13 @@ export default function IndexPage() {
|
|
|
61
62
|
|
|
62
63
|
项目根 `assets/` 是 H5 预览/部署的公开静态资源目录,服务端映射到 `/assets/*`。H5 页面按 URL 引用少量静态文件时优先使用相对路径 `assets/name.ext`,避免部署在 `/p/{projectId}/` 子路径时资源 404;大图片、视频和用户上传内容仍走对象存储。不要把根 `assets/` 文件当作 `src/assets` 导入。
|
|
63
64
|
|
|
65
|
+
部署资源路径硬性要求:
|
|
66
|
+
|
|
67
|
+
- 根目录 `assets/` 文件在页面中只能写相对 URL,例如 `assets/images/logo.svg`。
|
|
68
|
+
- 禁止写 `/assets/images/logo.svg`,它会绕过 `/p/{projectId}/` base path。
|
|
69
|
+
- 禁止写 `../assets/images/logo.svg`,不同页面层级下容易解析错误。
|
|
70
|
+
- 完成前必须自查 `src/`,不能残留 `/assets/`、`../assets/` 或 Tailwind 小数类名。
|
|
71
|
+
|
|
64
72
|
**强制规则**:图片、视频等静态资源必须通过 TOS 对象存储管理,代码中使用 TOS 返回的 URL 引用。
|
|
65
73
|
|
|
66
74
|
1. **资源存储方式**:
|
|
@@ -213,7 +221,8 @@ CRITICAL:
|
|
|
213
221
|
- 颜色、间距、圆角、边框、阴影、排版、flex/grid、宽高等常规样式必须收敛在 Tailwind 类名中。
|
|
214
222
|
- 禁止使用 `w-[340px]`、`text-[14px]`、`p-[16px]` 这类带 `px` 的 Tailwind 任意值。
|
|
215
223
|
- 禁止使用颜色不透明度简写,例如 `bg-primary/10`、`text-slate-500/70`、`border-white/20`;小程序端 opacity 容易丢失,必须拆成基础颜色类和 `bg-opacity-*` / `text-opacity-*` / `border-opacity-*`。
|
|
216
|
-
-
|
|
224
|
+
- 绝对禁止使用任何 Tailwind 小数值或斜杠分数类名,例如 `space-y-1.5`、`w-0.5`、`h-2.5`、`mt-0.5`、`h-3/5`。统一改成整数刻度,例如 `space-y-2`、`w-1`、`h-3`、`mt-1`。`mt-0.5` 这类写法会直接导致部署构建失败。
|
|
225
|
+
- 完成前必须搜索并消除 `className` 中所有 `字母-数字.数字` 形式的类名。常见错误包括 `mt-0.5`、`space-y-1.5`、`h-2.5`、`w-0.5`。
|
|
217
226
|
- 禁止使用 `peer-*`、`group-*`、`has-*`、复杂任意选择器和属性选择器类名;这些写法在小程序构建或上传时容易失败。
|
|
218
227
|
- 禁止使用 `style={{ width: '200px' }}`、`fontSize: '14px'` 这类硬编码尺寸。
|
|
219
228
|
- Taro 会通过 `pxtransform` 将尺寸转换为跨端单位(小程序 `rpx`、H5 `rem`),业务代码里直接写 `px` 容易导致不同端显示不一致。
|
|
@@ -74,9 +74,15 @@ const baseRestrictedSyntaxRules = [
|
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
selector:
|
|
77
|
-
'Literal[value=/\\b
|
|
77
|
+
'Literal[value=/\\b[a-zA-Z0-9-]+\\-[0-9]+\\.[0-9]+\\b/], TemplateElement[value.raw=/\\b[a-zA-Z0-9-]+\\-[0-9]+\\.[0-9]+\\b/]',
|
|
78
78
|
message:
|
|
79
|
-
'微信小程序兼容性:禁用 Tailwind 小数值类名(如 space-y-1.5、w-0.5),请用整数替代(如 space-y-2、w-1)。',
|
|
79
|
+
'微信小程序兼容性:禁用 Tailwind 小数值类名(如 mt-0.5、space-y-1.5、w-0.5、h-2.5),请用整数替代(如 mt-1、space-y-2、w-1、h-3)。',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
selector:
|
|
83
|
+
'Literal[value=/^(?:\\/|\\.\\.\\/)assets\\//], TemplateElement[value.raw=/^(?:\\/|\\.\\.\\/)assets\\//]',
|
|
84
|
+
message:
|
|
85
|
+
'部署路径兼容性:根目录 assets 资源必须使用相对 URL(如 assets/logo.svg),禁止 /assets/... 或 ../assets/...,否则部署到 /p/{projectId}/ 子路径后资源会 404。',
|
|
80
86
|
},
|
|
81
87
|
{
|
|
82
88
|
selector:
|
|
@@ -165,14 +171,6 @@ const pageRestrictedSyntaxRules = [
|
|
|
165
171
|
},
|
|
166
172
|
];
|
|
167
173
|
|
|
168
|
-
const indexPageRestrictedSyntaxRules = [
|
|
169
|
-
{
|
|
170
|
-
selector: 'JSXText[value=/\\s*应用开发中\\s*/]',
|
|
171
|
-
message:
|
|
172
|
-
'工程规范:检测到首页 (src/pages/index/index.tsx) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能与界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
|
|
173
|
-
},
|
|
174
|
-
];
|
|
175
|
-
|
|
176
174
|
export default [
|
|
177
175
|
...compat.extends('taro/react'),
|
|
178
176
|
{
|
|
@@ -241,7 +239,6 @@ export default [
|
|
|
241
239
|
'error',
|
|
242
240
|
...baseRestrictedSyntaxRules,
|
|
243
241
|
...pageRestrictedSyntaxRules,
|
|
244
|
-
...indexPageRestrictedSyntaxRules,
|
|
245
242
|
],
|
|
246
243
|
},
|
|
247
244
|
},
|
|
@@ -223,7 +223,7 @@ const ContextMenuItem = React.forwardRef<
|
|
|
223
223
|
data-inset={inset ? "" : undefined}
|
|
224
224
|
data-disabled={disabled ? "" : undefined}
|
|
225
225
|
className={cn(
|
|
226
|
-
"relative flex cursor-default select-none items-center gap-
|
|
226
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
227
227
|
inset && "pl-7",
|
|
228
228
|
disabled && "pointer-events-none opacity-50",
|
|
229
229
|
className
|
|
@@ -293,7 +293,7 @@ const ContextMenuCheckboxItem = React.forwardRef<
|
|
|
293
293
|
data-disabled={disabled ? "" : undefined}
|
|
294
294
|
data-state={checked ? "checked" : "unchecked"}
|
|
295
295
|
className={cn(
|
|
296
|
-
"relative flex cursor-default select-none items-center gap-
|
|
296
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
297
297
|
inset && "pl-7",
|
|
298
298
|
disabled && "pointer-events-none opacity-50",
|
|
299
299
|
className
|
|
@@ -336,7 +336,7 @@ const ContextMenuRadioItem = React.forwardRef<
|
|
|
336
336
|
data-disabled={disabled ? "" : undefined}
|
|
337
337
|
data-state={checked ? "checked" : "unchecked"}
|
|
338
338
|
className={cn(
|
|
339
|
-
"relative flex cursor-default select-none items-center gap-
|
|
339
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
340
340
|
inset && "pl-7",
|
|
341
341
|
disabled && "pointer-events-none opacity-50",
|
|
342
342
|
className
|
|
@@ -481,7 +481,7 @@ const ContextMenuSubTrigger = React.forwardRef<
|
|
|
481
481
|
data-disabled={disabled ? "" : undefined}
|
|
482
482
|
data-state={subContext?.open ? "open" : "closed"}
|
|
483
483
|
className={cn(
|
|
484
|
-
"relative flex cursor-default select-none items-center gap-
|
|
484
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
|
485
485
|
inset && "pl-7",
|
|
486
486
|
disabled && "pointer-events-none opacity-50",
|
|
487
487
|
className
|
|
@@ -278,7 +278,7 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
278
278
|
data-variant={variant}
|
|
279
279
|
data-disabled={disabled ? "" : undefined}
|
|
280
280
|
className={cn(
|
|
281
|
-
"relative flex cursor-default select-none items-center gap-
|
|
281
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
282
282
|
"data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive data-[variant=destructive]:focus:bg-opacity-10 data-[variant=destructive]:focus:text-destructive",
|
|
283
283
|
inset && "pl-7",
|
|
284
284
|
disabled && "pointer-events-none opacity-50",
|
|
@@ -313,7 +313,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
313
313
|
data-disabled={disabled ? "" : undefined}
|
|
314
314
|
data-state={checked ? "checked" : "unchecked"}
|
|
315
315
|
className={cn(
|
|
316
|
-
"relative flex cursor-default select-none items-center gap-
|
|
316
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
317
317
|
inset && "pl-7",
|
|
318
318
|
className
|
|
319
319
|
)}
|
|
@@ -354,7 +354,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|
|
354
354
|
data-disabled={disabled ? "" : undefined}
|
|
355
355
|
data-state={checked ? "checked" : "unchecked"}
|
|
356
356
|
className={cn(
|
|
357
|
-
"relative flex cursor-default select-none items-center gap-
|
|
357
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
358
358
|
inset && "pl-7",
|
|
359
359
|
className
|
|
360
360
|
)}
|
|
@@ -432,7 +432,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
432
432
|
data-disabled={disabled ? "" : undefined}
|
|
433
433
|
data-state={subContext?.open ? "open" : "closed"}
|
|
434
434
|
className={cn(
|
|
435
|
-
"relative flex cursor-default select-none items-center gap-
|
|
435
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
|
436
436
|
inset && "pl-7",
|
|
437
437
|
disabled && "pointer-events-none opacity-50",
|
|
438
438
|
className
|
|
@@ -218,7 +218,7 @@ const MenubarItem = React.forwardRef<
|
|
|
218
218
|
data-variant={variant}
|
|
219
219
|
data-disabled={disabled ? "" : undefined}
|
|
220
220
|
className={cn(
|
|
221
|
-
"relative flex cursor-default select-none items-center gap-
|
|
221
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
222
222
|
"data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive data-[variant=destructive]:focus:bg-opacity-10 data-[variant=destructive]:focus:text-destructive",
|
|
223
223
|
inset && "pl-7",
|
|
224
224
|
disabled && "pointer-events-none opacity-50",
|
|
@@ -255,7 +255,7 @@ const MenubarCheckboxItem = React.forwardRef<
|
|
|
255
255
|
data-disabled={disabled ? "" : undefined}
|
|
256
256
|
data-state={checked ? "checked" : "unchecked"}
|
|
257
257
|
className={cn(
|
|
258
|
-
"relative flex cursor-default select-none items-center gap-
|
|
258
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
259
259
|
inset && "pl-7",
|
|
260
260
|
disabled && "pointer-events-none opacity-50",
|
|
261
261
|
className
|
|
@@ -330,7 +330,7 @@ const MenubarRadioItem = React.forwardRef<
|
|
|
330
330
|
data-disabled={disabled ? "" : undefined}
|
|
331
331
|
data-state={checked ? "checked" : "unchecked"}
|
|
332
332
|
className={cn(
|
|
333
|
-
"relative flex cursor-default select-none items-center gap-
|
|
333
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md py-1 pr-8 pl-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
334
334
|
inset && "pl-7",
|
|
335
335
|
disabled && "pointer-events-none opacity-50",
|
|
336
336
|
className
|
|
@@ -461,7 +461,7 @@ const MenubarSubTrigger = React.forwardRef<
|
|
|
461
461
|
data-disabled={disabled ? "" : undefined}
|
|
462
462
|
data-state={subContext?.open ? "open" : "closed"}
|
|
463
463
|
className={cn(
|
|
464
|
-
"relative flex cursor-default select-none items-center gap-
|
|
464
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
|
465
465
|
inset && "pl-7",
|
|
466
466
|
disabled && "pointer-events-none opacity-50",
|
|
467
467
|
className
|
|
@@ -257,7 +257,7 @@ const PopoverHeader = React.forwardRef<
|
|
|
257
257
|
React.ElementRef<typeof View>,
|
|
258
258
|
React.ComponentPropsWithoutRef<typeof View>
|
|
259
259
|
>(({ className, ...props }, ref) => (
|
|
260
|
-
<View ref={ref} className={cn("grid gap-
|
|
260
|
+
<View ref={ref} className={cn("grid gap-2", className)} {...props} />
|
|
261
261
|
))
|
|
262
262
|
PopoverHeader.displayName = "PopoverHeader"
|
|
263
263
|
|
package/lib/cli.js
CHANGED
|
@@ -2109,7 +2109,7 @@ const EventBuilder = {
|
|
|
2109
2109
|
};
|
|
2110
2110
|
|
|
2111
2111
|
var name = "@kmlckj/licos-ai-cli";
|
|
2112
|
-
var version = "0.0.
|
|
2112
|
+
var version = "0.0.41";
|
|
2113
2113
|
var description = "LICOS AI coding workspace CLI - project template engine and dev tools";
|
|
2114
2114
|
var license = "MIT";
|
|
2115
2115
|
var author = "kmlckj";
|