@kmlckj/licos-ai-cli 0.0.42 → 0.0.44

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.
@@ -243,6 +243,8 @@ cd server && pnpm add --registry=https://registry.npmmirror.com axios cors
243
243
 
244
244
  - `client/assets/` 用于 Expo/React Native import 和 bundle 资源。
245
245
  - 项目根 `assets/` 用于 Web 部署时按 URL 访问的公开静态资源,服务端会映射到 `/assets/*`;H5 页面应优先用相对路径 `assets/name.ext`,避免部署子路径资源 404。开发预览中的跨端资源仍优先通过 `client/assets/` import。
246
+ - 新增或修改页面时,任何 `@/assets/...` import 都必须指向真实存在的文件;如需新图标/图片,先创建文件或复用模板已有 `client/assets/images/icon.png`、`react-logo.png`、`default-avatar.png` 等资源,禁止留下无法解析的本地资源引用。
247
+ - `.png`、`.jpg`、`.webp`、字体等资源文件必须是真实二进制文件;如果来源是 base64,必须先解码成二进制再写入,禁止把 base64 文本直接保存成图片后缀。
246
248
 
247
249
  ### 路径别名
248
250
 
@@ -248,6 +248,12 @@ import { Screen } from '@/components/Screen';
248
248
  import { Screen } from '../../../components/Screen';
249
249
  ```
250
250
 
251
+ ### 静态资源
252
+
253
+ 新增或修改页面时,任何 `@/assets/...` import 都必须指向真实存在的文件;如需新图标/图片,先创建文件或复用模板已有 `client/assets/images/icon.png`、`react-logo.png`、`default-avatar.png` 等资源,禁止留下无法解析的本地资源引用。
254
+
255
+ `.png`、`.jpg`、`.webp`、字体等资源文件必须是真实二进制文件;如果来源是 base64,必须先解码成二进制再写入,禁止把 base64 文本直接保存成图片后缀。
256
+
251
257
  ## 本地开发
252
258
 
253
259
  `licos dev`:用来首次启动前后端服务,也可以用来重启前后端服务(该命令会先尝试杀掉占用端口的进程,再启动服务)
@@ -3,3 +3,23 @@
3
3
  declare module 'expo-file-system/legacy' {
4
4
  export * from 'expo-file-system';
5
5
  }
6
+
7
+ declare module '*.png' {
8
+ const value: import('react-native').ImageSourcePropType;
9
+ export default value;
10
+ }
11
+
12
+ declare module '*.jpg' {
13
+ const value: import('react-native').ImageSourcePropType;
14
+ export default value;
15
+ }
16
+
17
+ declare module '*.jpeg' {
18
+ const value: import('react-native').ImageSourcePropType;
19
+ export default value;
20
+ }
21
+
22
+ declare module '*.webp' {
23
+ const value: import('react-native').ImageSourcePropType;
24
+ export default value;
25
+ }
@@ -39,7 +39,7 @@ Display an avatar image with automatic fallback handling.
39
39
 
40
40
  ```tsx
41
41
  <Avatar>
42
- <Avatar.Image source={{ uri: 'https://example.com/avatar.jpg' }} />
42
+ <Avatar.Image source={require('@/assets/images/default-avatar.png')} />
43
43
  <Avatar.Fallback>JD</Avatar.Fallback>
44
44
  </Avatar>
45
45
  ```
@@ -224,9 +224,9 @@ import { View } from 'react-native';
224
224
 
225
225
  export default function AvatarExample() {
226
226
  const users = [
227
- { id: 1, image: 'https://example.com/user1.jpg', name: 'John Doe' },
228
- { id: 2, image: 'https://example.com/user2.jpg', name: 'Jane Smith' },
229
- { id: 3, image: 'https://example.com/user3.jpg', name: 'Bob Johnson' },
227
+ { id: 1, image: require('@/assets/images/default-avatar.png'), name: 'John Doe' },
228
+ { id: 2, image: require('@/assets/images/default-avatar.png'), name: 'Jane Smith' },
229
+ { id: 3, image: require('@/assets/images/default-avatar.png'), name: 'Bob Johnson' },
230
230
  ];
231
231
 
232
232
  return (
@@ -10,9 +10,9 @@ import type { ImageSourcePropType } from 'react-native';
10
10
  * @example
11
11
  * ```ts
12
12
  * // Valid sources
13
- * isValidSource(require('./avatar.png')); // true (returns a number)
14
- * isValidSource({ uri: 'https://example.com/avatar.jpg' }); // true
15
- * isValidSource([{ uri: 'https://example.com/avatar.jpg' }]); // true
13
+ * isValidSource(require('@/assets/images/default-avatar.png')); // true (returns a number)
14
+ * isValidSource({ uri: avatarUrl }); // true
15
+ * isValidSource([{ uri: avatarUrl }]); // true
16
16
  *
17
17
  * // Invalid sources
18
18
  * isValidSource(undefined); // false
@@ -47,13 +47,13 @@ export function isValidSource(source?: ImageSourcePropType) {
47
47
  * @example
48
48
  * ```ts
49
49
  * // Same sources (different object references)
50
- * isSameSource({ uri: 'https://example.com/img.jpg' }, { uri: 'https://example.com/img.jpg' }); // true
50
+ * isSameSource({ uri: imageUrl }, { uri: imageUrl }); // true
51
51
  *
52
52
  * // Different sources
53
- * isSameSource({ uri: 'https://example.com/img1.jpg' }, { uri: 'https://example.com/img2.jpg' }); // false
53
+ * isSameSource({ uri: firstImageUrl }, { uri: secondImageUrl }); // false
54
54
  *
55
55
  * // Same require() values
56
- * isSameSource(require('./img.png'), require('./img.png')); // true (if same number)
56
+ * isSameSource(require('@/assets/images/default-avatar.png'), require('@/assets/images/default-avatar.png')); // true (if same number)
57
57
  * ```
58
58
  */
59
59
  export function isSameSource(
@@ -9,7 +9,8 @@ export default function DemoPage() {
9
9
  <View className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center">
10
10
  <Image
11
11
  className="w-[130px] h-[109px]"
12
- source="https://placeholder.local/static/expo/licos-loading.gif"
12
+ source={require('@/assets/images/icon.png')}
13
+ contentFit="contain"
13
14
  />
14
15
  <Text className="text-base font-bold text-foreground">APP 开发中</Text>
15
16
  <Text className="text-sm mt-2 text-muted">即将为您呈现应用界面</Text>
@@ -5,17 +5,27 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="description" content="LICOS AI - Your coding workspace" />
7
7
  <title>LICOS AI</title>
8
- <link rel="stylesheet" href="/styles/main.css" />
8
+ <link rel="stylesheet" href="styles/main.css" />
9
9
  </head>
10
10
  <body>
11
11
  <div id="app">
12
12
  <main class="main-wrapper">
13
13
  <div class="content-container">
14
- <img
15
- src="https://placeholder.local/static/icon/licos.gif"
16
- alt="LICOS Logo"
17
- class="logo-image"
18
- />
14
+ <div class="logo-image logo-mark" aria-label="LICOS Logo" role="img">
15
+ <svg viewBox="0 0 156 130" aria-hidden="true">
16
+ <defs>
17
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
18
+ <stop offset="0" stop-color="#0ea5e9" />
19
+ <stop offset="0.5" stop-color="#14b8a6" />
20
+ <stop offset="1" stop-color="#84cc16" />
21
+ </linearGradient>
22
+ </defs>
23
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
24
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
25
+ <circle cx="58" cy="55" r="8" fill="#fff" />
26
+ <circle cx="98" cy="55" r="8" fill="#fff" />
27
+ </svg>
28
+ </div>
19
29
  <div>
20
30
  <div class="text-container">
21
31
  <h1 class="heading">
@@ -93,6 +93,17 @@ body {
93
93
  object-fit: contain;
94
94
  }
95
95
 
96
+ .logo-mark {
97
+ display: grid;
98
+ place-items: center;
99
+ }
100
+
101
+ .logo-mark svg {
102
+ width: 100%;
103
+ height: 100%;
104
+ display: block;
105
+ }
106
+
96
107
  /* Text container */
97
108
  .text-container {
98
109
  display: flex;
@@ -1,5 +1,4 @@
1
1
  import type { Metadata } from 'next';
2
- import Image from 'next/image';
3
2
 
4
3
  export const metadata: Metadata = {
5
4
  title: 'LICOS AI - AI 开发伙伴',
@@ -12,12 +11,24 @@ export default function Home() {
12
11
  {/* 主容器 */}
13
12
  <main className="flex w-full h-full max-w-3xl flex-col items-center justify-center px-16 py-32 sm:items-center">
14
13
  <div className="flex flex-col items-center justify-between gap-4">
15
- <Image
16
- src="https://placeholder.local/static/icon/licos.gif"
17
- alt="LICOS AI Logo"
18
- width={156}
19
- height={130}
20
- />
14
+ <svg
15
+ role="img"
16
+ aria-label="LICOS AI Logo"
17
+ viewBox="0 0 156 130"
18
+ className="h-[130px] w-[156px]"
19
+ >
20
+ <defs>
21
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
22
+ <stop offset="0" stopColor="#0ea5e9" />
23
+ <stop offset="0.5" stopColor="#14b8a6" />
24
+ <stop offset="1" stopColor="#84cc16" />
25
+ </linearGradient>
26
+ </defs>
27
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
28
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" strokeWidth="10" strokeLinecap="round" />
29
+ <circle cx="58" cy="55" r="8" fill="#fff" />
30
+ <circle cx="98" cy="55" r="8" fill="#fff" />
31
+ </svg>
21
32
  <div>
22
33
  <div className="flex flex-col items-center gap-2 text-center sm:items-center sm:text-center">
23
34
  <h1 className="max-w-xl text-base font-semibold leading-tight tracking-tight text-foreground dark:text-foreground">
@@ -2,13 +2,26 @@
2
2
  <div class="flex min-h-screen items-center justify-center">
3
3
  <main class="flex w-full max-w-3xl flex-col items-center justify-center px-16 py-32">
4
4
  <div class="flex flex-col items-center gap-4">
5
- <img
6
- src="https://placeholder.local/static/icon/licos.gif"
7
- alt="LICOS Logo"
5
+ <svg
6
+ role="img"
7
+ aria-label="LICOS Logo"
8
+ viewBox="0 0 156 130"
8
9
  width="156"
9
10
  height="130"
10
- style="width: 156px; height: 130px; object-fit: contain"
11
- />
11
+ style="width: 156px; height: 130px; display: block"
12
+ >
13
+ <defs>
14
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
15
+ <stop offset="0" stop-color="#0ea5e9" />
16
+ <stop offset="0.5" stop-color="#14b8a6" />
17
+ <stop offset="1" stop-color="#84cc16" />
18
+ </linearGradient>
19
+ </defs>
20
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
21
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
22
+ <circle cx="58" cy="55" r="8" fill="#fff" />
23
+ <circle cx="98" cy="55" r="8" fill="#fff" />
24
+ </svg>
12
25
  <div class="flex flex-col items-center gap-2 text-center">
13
26
  <h1 class="max-w-xl text-base font-semibold leading-tight tracking-tight">
14
27
  应用开发中
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156 130" role="img" aria-label="LICOS Logo">
2
+ <defs>
3
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
4
+ <stop offset="0" stop-color="#0ea5e9" />
5
+ <stop offset="0.5" stop-color="#14b8a6" />
6
+ <stop offset="1" stop-color="#84cc16" />
7
+ </linearGradient>
8
+ </defs>
9
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
10
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
11
+ <circle cx="58" cy="55" r="8" fill="#fff" />
12
+ <circle cx="98" cy="55" r="8" fill="#fff" />
13
+ </svg>
@@ -132,17 +132,6 @@ export default defineNuxtConfig({
132
132
  },
133
133
  },
134
134
 
135
- image: {
136
- domains: ['placeholder.local'],
137
- remotePatterns: [
138
- {
139
- protocol: 'https',
140
- hostname: 'placeholder.local',
141
- pathname: '/**',
142
- },
143
- ],
144
- },
145
-
146
135
  // Security headers (Content Security Policy)
147
136
  nitro: {
148
137
  publicAssets: [
@@ -155,7 +144,7 @@ export default defineNuxtConfig({
155
144
  '/**': {
156
145
  headers: {
157
146
  'Content-Security-Policy':
158
- "img-src 'self' data: https://placeholder.local;",
147
+ "img-src 'self' data:;",
159
148
  },
160
149
  },
161
150
  },
@@ -28,6 +28,7 @@ pnpm remove <package> # 移除依赖
28
28
  - 需要引用 `src/assets/...` 源码资源时使用 ESM import,例如 `import logoUrl from '@/assets/images/logo.svg'`,不要在 `src/` 中写 CommonJS `require(...)`。
29
29
  - 根目录 `assets/` 是 H5 公开静态目录,不是 `@/assets` 源码别名。放在根 `assets/images/foo.svg` 的文件必须用相对 URL `assets/images/foo.svg`,不要写 `import foo from '@/assets/images/foo.svg'`。只有文件真实存在于 `src/assets/...` 时,才允许从 `@/assets/...` 导入。
30
30
  - 部署路径是 IP + `/p/{projectId}/` 子路径,页面中禁止写根路径 `/assets/...` 或上级路径 `../assets/...`。根目录 `assets/` 文件只能写成相对 URL `assets/...`,否则部署后资源会 404。
31
+ - 静态资源不要通过 `Network.request`、`Taro.request` 或 `fetch` 访问。根 `assets/` 文件直接用于 `<Image src="assets/...">`、链接或页面展示;`Network.request` 只用于 `/api/...` 业务接口。
31
32
  - 不要使用浏览器 DOM 全局做资源探测。禁止 `window`、`document`、`new Image()`、`window.Image`、`globalThis.Image`;图片状态通过 Taro `<Image onLoad onError />` 或直接渲染处理。
32
33
  - 从第三方图标包导入前必须确认导出存在;不确定时优先使用已验证的 `Package`、`Globe`、`Cpu`、`Layers` 等基础图标,避免引入不存在的命名导出导致构建失败。
33
34
  - 禁止输出不完整模板字符串、占位引号或非法 TS 字符串,例如 `"""`、未闭合的引号、未转义的英文单引号。文案中包含引号时使用反引号或正确转义。
@@ -70,6 +71,7 @@ export default function IndexPage() {
70
71
  - 根目录 `assets/` 文件在页面中只能写相对 URL,例如 `assets/images/logo.svg`。
71
72
  - 禁止写 `/assets/images/logo.svg`,它会绕过 `/p/{projectId}/` base path。
72
73
  - 禁止写 `../assets/images/logo.svg`,不同页面层级下容易解析错误。
74
+ - 禁止写 `Network.request({ url: '/assets/...' })` 或 `Network.request({ url: 'assets/...' })`。静态资源不是 API 请求。
73
75
  - 完成前必须自查 `src/`,不能残留 `/assets/`、`../assets/` 或 Tailwind 小数类名。
74
76
 
75
77
  **强制规则**:图片、视频等静态资源必须通过 TOS 对象存储管理,代码中使用 TOS 返回的 URL 引用。
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156 130" role="img" aria-label="LICOS Logo">
2
+ <defs>
3
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
4
+ <stop offset="0" stop-color="#0ea5e9" />
5
+ <stop offset="0.5" stop-color="#14b8a6" />
6
+ <stop offset="1" stop-color="#84cc16" />
7
+ </linearGradient>
8
+ </defs>
9
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
10
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
11
+ <circle cx="58" cy="55" r="8" fill="#fff" />
12
+ <circle cx="98" cy="55" r="8" fill="#fff" />
13
+ </svg>
@@ -84,6 +84,12 @@ const baseRestrictedSyntaxRules = [
84
84
  message:
85
85
  '部署路径兼容性:根目录 assets 资源必须使用相对 URL(如 assets/logo.svg),禁止 /assets/... 或 ../assets/...,否则部署到 /p/{projectId}/ 子路径后资源会 404。',
86
86
  },
87
+ {
88
+ selector:
89
+ "CallExpression[callee.object.name='Network'][callee.property.name='request'] Property[key.name='url'] > Literal[value=/^(?:\\/|\\.\\.\\/)?assets\\//]",
90
+ message:
91
+ '工程规范:静态资源不能通过 Network.request 访问。根目录 assets 资源应直接作为相对 URL 用于 Image src 或页面展示;Network.request 只用于 /api/... 业务接口。',
92
+ },
87
93
  {
88
94
  selector:
89
95
  ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\:has\\(/], TemplateElement[value.raw=/\\:has\\(/])",
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156 130" role="img" aria-label="LICOS Logo">
2
+ <defs>
3
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
4
+ <stop offset="0" stop-color="#0ea5e9" />
5
+ <stop offset="0.5" stop-color="#14b8a6" />
6
+ <stop offset="1" stop-color="#84cc16" />
7
+ </linearGradient>
8
+ </defs>
9
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
10
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
11
+ <circle cx="58" cy="55" r="8" fill="#fff" />
12
+ <circle cx="98" cy="55" r="8" fill="#fff" />
13
+ </svg>
@@ -1,4 +1,4 @@
1
- import { View, Text, Image } from '@tarojs/components';
1
+ import { View, Text } from '@tarojs/components';
2
2
  import { useLoad } from '@tarojs/taro';
3
3
  import { Network } from '@/network';
4
4
  import './index.css';
@@ -14,10 +14,9 @@ const IndexPage = () => {
14
14
 
15
15
  return (
16
16
  <View className="w-full h-full flex flex-col justify-center items-center gap-1">
17
- <Image
18
- className="w-32 h-28"
19
- src="https://placeholder.local/static/icon/licos.gif"
20
- />
17
+ <View className="w-32 h-28 rounded-3xl bg-gradient-to-br from-sky-500 via-teal-500 to-lime-500 flex items-center justify-center">
18
+ <Text className="text-white text-3xl font-bold">AI</Text>
19
+ </View>
21
20
  <View className="self-stretch flex flex-col justify-start items-start gap-2">
22
21
  <Text className="self-stretch text-center justify-start text-base-accent-foreground text-base font-bold">
23
22
  应用开发中
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156 130" role="img" aria-label="LICOS Logo">
2
+ <defs>
3
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
4
+ <stop offset="0" stop-color="#0ea5e9" />
5
+ <stop offset="0.5" stop-color="#14b8a6" />
6
+ <stop offset="1" stop-color="#84cc16" />
7
+ </linearGradient>
8
+ </defs>
9
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
10
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
11
+ <circle cx="58" cy="55" r="8" fill="#fff" />
12
+ <circle cx="98" cy="55" r="8" fill="#fff" />
13
+ </svg>
@@ -10,13 +10,24 @@ export function initApp(): void {
10
10
  <div class="flex h-full items-center justify-center bg-background text-foreground transition-colors duration-300 dark:bg-background dark:text-foreground overflow-hidden min-h-screen">
11
11
  <main class="flex w-full h-full max-w-3xl flex-col items-center justify-center px-16 py-32 sm:items-center">
12
12
  <div class="flex flex-col items-center justify-between gap-4">
13
- <img
14
- src="https://placeholder.local/static/icon/licos.gif"
15
- alt="LICOS AI Logo"
16
- width={156}
17
- height={130}
18
- style="width: 156px; height: 130px; object-fit: contain;"
19
- />
13
+ <svg
14
+ role="img"
15
+ aria-label="LICOS AI Logo"
16
+ viewBox="0 0 156 130"
17
+ style="width: 156px; height: 130px; display: block;"
18
+ >
19
+ <defs>
20
+ <linearGradient id="licosLogoGradient" x1="16" y1="12" x2="140" y2="118">
21
+ <stop offset="0" stop-color="#0ea5e9" />
22
+ <stop offset="0.5" stop-color="#14b8a6" />
23
+ <stop offset="1" stop-color="#84cc16" />
24
+ </linearGradient>
25
+ </defs>
26
+ <rect x="18" y="12" width="120" height="106" rx="30" fill="url(#licosLogoGradient)" />
27
+ <path d="M53 80c10 12 39 12 50 0" fill="none" stroke="#fff" stroke-width="10" stroke-linecap="round" />
28
+ <circle cx="58" cy="55" r="8" fill="#fff" />
29
+ <circle cx="98" cy="55" r="8" fill="#fff" />
30
+ </svg>
20
31
  <div>
21
32
  <div class="flex flex-col items-center gap-2 text-center sm:items-center sm:text-center">
22
33
  <h1 class="max-w-xl text-base font-semibold leading-tight tracking-tight text-foreground dark:text-foreground">
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.42";
2112
+ var version = "0.0.44";
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kmlckj/licos-ai-cli",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "description": "LICOS AI coding workspace CLI - project template engine and dev tools",
5
5
  "license": "MIT",
6
6
  "author": "kmlckj",