@lark-apaas/coding-steering 0.1.47 → 0.1.48-alpha.20260907062150

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/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@lark-apaas/coding-steering",
3
- "version": "0.1.47",
3
+ "version": "0.1.48-alpha.20260907062150",
4
4
  "description": "Stack-specific steering content for miaoda-coding templates",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "steering"
8
8
  ],
9
+ "scripts": {
10
+ "lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
11
+ },
9
12
  "devDependencies": {
10
13
  "markdownlint-cli": "^0.47.0"
11
14
  },
@@ -17,8 +20,5 @@
17
20
  "miaoda",
18
21
  "coding-steering"
19
22
  ],
20
- "license": "MIT",
21
- "scripts": {
22
- "lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
23
- }
24
- }
23
+ "license": "MIT"
24
+ }
@@ -83,7 +83,6 @@ available-agents:
83
83
  | 无持久化状态、纯展示或前端工具 | 纯前端 |
84
84
  | 需要数据存储、用户隔离、后端逻辑 | 全栈 |
85
85
  | 涉及文件上传与管理 | 全栈 + 文件服务 |
86
- | 服务端图像、音视频处理(易引入 native addon) | 先确认能否改用 client 处理、平台服务或纯 JS/WASM |
87
86
  | 以飞书多维表格为数据源 | 插件优先;复杂查询场景评估是否同步至本地库 |
88
87
  | 需要飞书通知、群组、AI 能力 | 插件集成,标记插件实例需求 |
89
88
  | 需要定时或事件驱动的后台处理 | 全栈 + 自动化任务 |
@@ -114,7 +113,6 @@ available-agents:
114
113
  - 集成点:飞书、多维表格、AI、内网接口、OpenAPI、自动化触发。
115
114
  - 边界与限制:不支持的能力、外部依赖、数据权限边界。
116
115
  - 交给 Code agent 时标明需要加载的专项 skill(表格、表单、图表、插件、权限、文件、自动化)。
117
- - 需要 native addon 时:确认它提供覆盖 linux-x64 / glibc 的预编译二进制并记录包名与版本;没有预编译二进制、装的时候要现场编译的不能用。
118
116
 
119
117
  ## Common Mistakes
120
118
 
@@ -155,9 +155,8 @@ shared/ # 前后端共享的目录
155
155
 
156
156
  ## 依赖使用规范
157
157
 
158
- 1. **子包完整性检查**:部分库有多个子包(如 `@dnd-kit/core` + `@dnd-kit/sortable` + `@dnd-kit/utilities`),添加 import 后必须确认 package.json 中包含所有需要的子包
159
- 2. **禁止安装时需现场编译的 native addon**(`node-gyp rebuild`、`binding.gyp`、需要系统头文件或编译器)。依赖按平台内置能力 / 浏览器能力 → 纯 JS 或 WASM → 有预编译二进制的 native addon 的顺序选型
160
- 3. 用法不清时查看 readme,可进一步搜索或网页访问获取信息
158
+ 1. **子包完整性检查**:部分库有多个子包(如 `@radix-ui/react-*` 系列每个组件都是独立子包),添加 import 后必须确认 package.json 中包含所有需要的子包
159
+ 2. 用法不清时查看 readme,可进一步搜索或网页访问获取信息
161
160
 
162
161
  ## 文件命名约定
163
162
 
@@ -234,7 +233,6 @@ shared/ # 前后端共享的目录
234
233
  - **能力边界**:服务端不支持文件上传(FaaS 限制),前端用 dataloom SDK 上传,服务端仅保存元信息
235
234
  - **环境判断**:`process.env.NODE_ENV === "production"` 表示生产环境
236
235
  - **文件系统**:临时文件、下载内容和处理中间产物统一写入 `/tmp` 下的独立目录,用完后清理
237
- - **启动关键路径**:`bootstrap`、`onModuleInit` 和 `OnApplicationBootstrap` 只做必须的同步装配,不得执行 DDL、全量数据同步、长轮询或无界外部请求。应用应尽早 `listen()`;非关键预热放到后台任务,外部调用必须有超时、错误日志和降级路径
238
236
  - **服务端运行时资源文件**(字体 / 证书 / 模板 / wasm 等需在运行时读取的非代码文件,CRITICAL — 发布后静默失效根因):① 必须在 `nest-cli.json` 的 `assets` 中声明(如 `{"include": "assets/<dir>/**/*", "outDir": "dist/server"}`),否则不会进 `dist/` 构建产物;② 路径用 `__dirname` 相对**编译产物**定位(如 `path.join(__dirname, "../assets/...")`),**禁止 `process.cwd()` 相对源码路径**——dev 跑源码能命中、发布跑 `dist/` 会落空;③ 资源缺失或加载失败必须 **fail-loud**(抛错或明确错误日志),禁止 `catch` 后静默返回残缺产物
239
237
  - **启动生命周期**:`constructor`、`onModuleInit` 和 `onApplicationBootstrap` 应快速完成,避免在其中下载大文件、全量同步或批量迁移;仅将钩子声明为 `async` 仍会被等待,无法缩短启动时间
240
238
 
@@ -477,13 +475,10 @@ await db.select().from(users).where(eq(users.adminUser, userId));
477
475
 
478
476
  - **必须从 `req.userContext` 获取**,禁止从前端传递,禁止硬编码(`const { userId } = req.userContext`)
479
477
  - 依赖用户信息的接口不要用 API 测试工具测试,用 `think` 工具思考
480
- - 后端按 `user-identity` 和 `@lark-apaas/fullstack-nestjs-core` 的 Express `Request` 增强读取 `req.userContext`;`tenantId` 为可选 number,不能套用前端 `window.tenantId` / `viewContext` 字符串语义。
481
- - Controller 直接用 `@Req() req: Request`;测试、mock 或业务窄类型用独立接口,只声明实际读取字段。不要继承 Express `Request` 或重声明 `userContext`;未读 `tenantId` 就省略,必须保留时用 `unknown` 或 SDK 兼容类型。
482
478
 
483
479
  ```typescript
484
- // req.userContext 字段(由身份认证中间件挂载,完整合同见 user-identity):
485
- // - userId/appId: string
486
- // - tenantId: SDK Request.userContext 的可选 number
480
+ // req.userContext 字段(由身份认证中间件挂载):
481
+ // - userId/tenantId/appId: string
487
482
  // - env: 'preview' | 'runtime' (preview=预览态, runtime=发布运行态)
488
483
  // - userName/userNameEn: string
489
484
  // - userNameI18n: string (多语名字, 如 {zh_cn: '用户', en_us: 'user'})
@@ -581,6 +576,8 @@ async createArticle(@Req() req: Request, @Body() dto: CreateArticleDto) {
581
576
  {% if projectMeta['flags']['supportTiptapAndStreamdown'] %}
582
577
  - **富文本**: `business-ui/tiptap-editor`(阅读 README.md)
583
578
  - **Markdown 渲染**: `components/ui/streamdown`(内置 prose 排版)
579
+ {% else %}
580
+ - **Markdown 渲染**: `components/ui/markdown`(react-markdown + remark-gfm,内置 prose 排版)
584
581
  {% endif %}
585
582
 
586
583
  ## API 请求
@@ -618,6 +615,8 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
618
615
  {% if projectMeta['flags']['supportTiptapAndStreamdown'] %}
619
616
  | TiptapEditorComplete | `business-ui/tiptap-editor` | 富文本编辑器 |
620
617
  | Streamdown | `components/ui/streamdown` | Markdown/流式渲染 |
618
+ {% else %}
619
+ | Markdown | `components/ui/markdown` | Markdown 渲染(react-markdown + remark-gfm) |
621
620
  {% endif %}
622
621
 
623
622
  ### 组件 Skill 召回规则(强制执行)
@@ -781,15 +780,12 @@ return <h1>{data?.title || '未知标题'}</h1>;
781
780
  | 验证 | zod |
782
781
  | 工具函数 | lodash |
783
782
  | 样式 | clsx |
784
- | Excel | xlsx(**仅前端实现,禁止服务端实现**。解析后将结构化数据传到服务端保存) |
785
- | PDF 导出 | jspdf + html2canvas(**仅前端实现,禁止服务端实现**) |
786
- | 文件上传 | react-dropzone |
787
- | 二维码 | qrcode.react |
783
+ | 文件上传 | 原生 `<input type="file">`,用 shadcn 组件封装样式 |
788
784
  | 用户反馈 | sonner |
789
- | 拖拽 | @dnd-kit/core |
790
- | 数字动画 | react-countup |
791
- | Base64 | js-base64 — `import { encode, decode } from 'js-base64'` |
792
- | 3D 场景 | cobe |
785
+ | 数字动画 | `requestAnimationFrame` 手写,或 framer-motion 的 `animate` |
786
+ | Base64 | 原生 `atob`/`btoa`(Unicode 内容先经 `TextEncoder`/`TextDecoder`);服务端用 `Buffer` |
787
+
788
+ > Excel 解析、PDF 导出、二维码、拖拽、3D 场景等能力已随依赖瘦身不再预装(xlsx、jspdf、html2canvas、qrcode.react、@dnd-kit、react-dropzone、react-countup、js-base64、cobe 已从模板移除)。确有此类需求时,先在 package.json 显式添加所需依赖并安装,再编写代码。
793
789
 
794
790
  ## 滚动分页最佳实践
795
791
 
@@ -93,14 +93,12 @@ match-template-name: nestjs-react-fullstack
93
93
 
94
94
  > 完整的解析→守卫流程见 `authn-guide` skill 第二节"认证流程"。
95
95
 
96
- 类型使用规则:Controller 直接用 `@Req() req: Request` 读取 SDK 增强的 `req.userContext`。测试、mock 或局部业务需要窄类型时,定义独立接口,只声明实际读取字段;不要继承 Express `Request`,也不要重声明平台增强的 `userContext`。未读取的 `tenantId` 省略;必须保留时用 `unknown` 或 SDK 兼容类型。
97
-
98
96
  ### 字段表
99
97
 
100
98
  | 字段 | 类型 | 说明 |
101
99
  |------|------|------|
102
100
  | `userId` | `string` | 妙搭用户 ID |
103
- | `tenantId` | `number \| undefined` | 租户 ID;按 SDK Express `Request.userContext` 增强:可选 number |
101
+ | `tenantId` | `number` | 租户 ID |
104
102
  | `appId` | `string` | 应用 ID |
105
103
  | `loginUrl` | `string` | 登录跳转 URL |
106
104
  | `userType` | `string` | 用户类型(如 `_employee`) |
@@ -129,7 +129,7 @@ shared/ # 前后端共享的目录
129
129
 
130
130
  1. 优先使用项目已有依赖,仅在无法实现时安装新依赖
131
131
  2. 使用前先查看 `package.json` 确保依赖已存在
132
- 3. **子包完整性检查**:部分库有多个子包(如 `@dnd-kit/core` + `@dnd-kit/sortable` + `@dnd-kit/utilities`),添加 import 后必须确认 package.json 中包含所有需要的子包
132
+ 3. **子包完整性检查**:部分库有多个子包(如 `@radix-ui/react-*` 系列每个组件都是独立子包),添加 import 后必须确认 package.json 中包含所有需要的子包
133
133
  4. 用法不清时查看 readme,可进一步搜索或网页访问获取信息
134
134
 
135
135
  ## 文件命名约定
@@ -335,13 +335,10 @@ await db.select().from(users).where(eq(users.adminUser, userId));
335
335
 
336
336
  - **必须从 `req.userContext` 获取**,禁止从前端传递,禁止硬编码
337
337
  - 依赖用户信息的接口不要用 API 测试工具测试,用 `think` 工具思考
338
- - 后端按 `user-identity` 和 `@lark-apaas/fullstack-nestjs-core` 的 Express `Request` 增强读取 `req.userContext`;`tenantId` 为可选 number,不能套用前端 `window.tenantId` / `viewContext` 字符串语义。
339
- - Controller 直接用 `@Req() req: Request`;测试、mock 或业务窄类型用独立接口,只声明实际读取字段。不要继承 Express `Request` 或重声明 `userContext`;未读 `tenantId` 就省略,必须保留时用 `unknown` 或 SDK 兼容类型。
340
338
 
341
339
  ```typescript
342
- // req.userContext 字段(由身份认证中间件挂载,完整合同见 user-identity):
343
- // - userId/appId: string
344
- // - tenantId: SDK Request.userContext 的可选 number
340
+ // req.userContext 字段(由身份认证中间件挂载):
341
+ // - userId/tenantId/appId: string
345
342
  // - env: 'preview' | 'runtime' (preview=预览态, runtime=发布运行态)
346
343
  // - userName/userNameEn: string
347
344
  // - userNameI18n: string (多语名字, 如 {zh_cn: '用户', en_us: 'user'})
@@ -452,14 +449,13 @@ NestJS 自己不读 env。直连 NestJS 端口 → header 缺失 → `req.userCo
452
449
 
453
450
  - **框架**: React 19 + TypeScript
454
451
  - **路由**: React Router DOM v6
455
- - **样式**: styled-jsx + tailwindcss(语义化 token)。styled-jsx 使用前提见下方"样式开发"
452
+ - **样式**: tailwindcss(语义化 token)为主,复杂 CSS 用 CSS Modules(`*.module.css`),动态计算值用行内 `style`
456
453
  - **UI 组件库**: shadcn/ui — Use components for functionality, heavily style them
457
454
  - **图表**: ReactECharts,**开发前必须调用 `/charts-skill`**
458
455
  - **图标**: Lucide React(唯一图标库,禁止 Emoji 和其他图标库)
459
456
  - **表格/表单/图表**: 见下方"组件 Skill 召回规则",开发前必须先调用对应 Skill
460
457
  - **用户**: 用户信息展示/选择必须用 `business-ui` 组件(阅读 README.md),禁止直接展示 userId
461
- - **富文本**: `business-ui/tiptap-editor`(阅读 README.md)
462
- - **Markdown 渲染**: `components/ui/streamdown`(内置 prose 排版)
458
+ - **Markdown 渲染**: `components/ui/markdown`(react-markdown + remark-gfm,内置 prose 排版)
463
459
 
464
460
  ## API 请求
465
461
 
@@ -492,8 +488,7 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
492
488
  | --------------------------------------------------- | --------------------------------------- | --------------------------------- |
493
489
  | Table | `@lark-apaas/client-toolkit/antd-table` | 数据表格,**先调 `/table-skill`** |
494
490
  | UserSelect/UserDisplay/UserProfile/DepartmentSelect | `business-ui/*` | 用户/部门选择展示 |
495
- | TiptapEditorComplete | `business-ui/tiptap-editor` | 富文本编辑器 |
496
- | Streamdown | `components/ui/streamdown` | Markdown/流式渲染 |
491
+ | Markdown | `components/ui/markdown` | Markdown 渲染(react-markdown + remark-gfm) |
497
492
 
498
493
  ### 组件 Skill 召回规则(强制执行)
499
494
 
@@ -544,7 +539,7 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
544
539
  ```
545
540
  需要写样式?
546
541
  ├─ 基础布局/间距/颜色 → Tailwind ✅
547
- ├─ 复杂动画/伪元素/高级CSS → styled-jsx ✅
542
+ ├─ 复杂动画/伪元素/高级CSS → CSS Modules(`*.module.css`)✅
548
543
  └─ JS动态计算值 → 行内 style ✅
549
544
  ```
550
545
 
@@ -557,10 +552,6 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
557
552
  - **arbitrary values 中空格用下划线**:`from-[hsl(215_60%_18%)]` 非 `from-[hsl(215 60% 18%)]`
558
553
  - `tailwind-theme.css` 自定义属性用 `hsl(H, S%, L%)` 格式(非 `23 10% 23%`)
559
554
 
560
- ### styled-jsx 规范
561
-
562
- - **技术栈一致性**:仅在已配置 styled-jsx 插件的项目中使用。`package.json` 无 `styled-jsx` 依赖则**禁用**,否则运行时 SyntaxError
563
- - **禁止动态插值**:`<style jsx>` 内禁止 `${...}` 等表达式(会卡死)。动态值放 CSS 变量,用 `var(--xxx)` 引用
564
555
 
565
556
  ### 布局/排版
566
557
 
@@ -644,15 +635,12 @@ return <h1>{data?.title || '未知标题'}</h1>;
644
635
  | 验证 | zod |
645
636
  | 工具函数 | lodash |
646
637
  | 样式 | clsx |
647
- | Excel | xlsx(**仅前端实现,禁止服务端实现**。解析后将结构化数据传到服务端保存) |
648
- | PDF 导出 | jspdf + html2canvas(**仅前端实现,禁止服务端实现**) |
649
- | 文件上传 | react-dropzone |
650
- | 二维码 | qrcode.react |
638
+ | 文件上传 | 原生 `<input type="file">`,用 shadcn 组件封装样式 |
651
639
  | 用户反馈 | sonner |
652
- | 拖拽 | @dnd-kit/core |
653
- | 数字动画 | react-countup |
654
- | Base64 | js-base64 — `import { encode, decode } from 'js-base64'` |
655
- | 3D 场景 | cobe |
640
+ | 数字动画 | `requestAnimationFrame` 手写,或 framer-motion 的 `animate` |
641
+ | Base64 | 原生 `atob`/`btoa`(Unicode 内容先经 `TextEncoder`/`TextDecoder`);服务端用 `Buffer` |
642
+
643
+ > Excel 解析、PDF 导出、二维码、拖拽、3D 场景等能力已随依赖瘦身不再预装(xlsx、jspdf、html2canvas、qrcode.react、@dnd-kit、react-dropzone、react-countup、js-base64、cobe 已从模板移除)。确有此类需求时,先在 package.json 显式添加所需依赖并安装,再编写代码。
656
644
 
657
645
  ## 滚动分页最佳实践
658
646