@loom-framework/core 0.1.0-alpha.8 → 0.1.0-alpha.80
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/dist/adapter-base.d.ts +29 -0
- package/dist/adapter-base.d.ts.map +1 -0
- package/dist/adapter-base.js +62 -0
- package/dist/adapter-base.js.map +1 -0
- package/dist/adapter-factory.d.ts +8 -0
- package/dist/adapter-factory.d.ts.map +1 -0
- package/dist/adapter-factory.js +25 -0
- package/dist/adapter-factory.js.map +1 -0
- package/dist/adapter-filesystem.d.ts +6 -11
- package/dist/adapter-filesystem.d.ts.map +1 -1
- package/dist/adapter-filesystem.js +56 -41
- package/dist/adapter-filesystem.js.map +1 -1
- package/dist/adapter-sqlite.d.ts +6 -23
- package/dist/adapter-sqlite.d.ts.map +1 -1
- package/dist/adapter-sqlite.js +65 -50
- package/dist/adapter-sqlite.js.map +1 -1
- package/dist/backend/ai/button-resolver.d.ts +18 -0
- package/dist/backend/ai/button-resolver.d.ts.map +1 -0
- package/dist/backend/ai/button-resolver.js +58 -0
- package/dist/backend/ai/button-resolver.js.map +1 -0
- package/dist/backend/ai/engine.d.ts +52 -0
- package/dist/backend/ai/engine.d.ts.map +1 -0
- package/dist/backend/ai/engine.js +186 -0
- package/dist/backend/ai/engine.js.map +1 -0
- package/dist/backend/ai/index.d.ts +11 -0
- package/dist/backend/ai/index.d.ts.map +1 -0
- package/dist/backend/ai/index.js +8 -0
- package/dist/backend/ai/index.js.map +1 -0
- package/dist/backend/ai/output-parser.d.ts +29 -0
- package/dist/backend/ai/output-parser.d.ts.map +1 -0
- package/dist/backend/ai/output-parser.js +247 -0
- package/dist/backend/ai/output-parser.js.map +1 -0
- package/dist/backend/ai/session-manager.d.ts +103 -0
- package/dist/backend/ai/session-manager.d.ts.map +1 -0
- package/dist/backend/ai/session-manager.js +298 -0
- package/dist/backend/ai/session-manager.js.map +1 -0
- package/dist/backend/index.d.ts +61 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +161 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/observe/index.d.ts +6 -0
- package/dist/backend/observe/index.d.ts.map +1 -0
- package/dist/backend/observe/index.js +5 -0
- package/dist/backend/observe/index.js.map +1 -0
- package/dist/backend/observe/logger.d.ts +28 -0
- package/dist/backend/observe/logger.d.ts.map +1 -0
- package/dist/backend/observe/logger.js +80 -0
- package/dist/backend/observe/logger.js.map +1 -0
- package/dist/backend/observe/types.d.ts +26 -0
- package/dist/backend/observe/types.d.ts.map +1 -0
- package/dist/backend/observe/types.js +7 -0
- package/dist/backend/observe/types.js.map +1 -0
- package/dist/backend/routes/chat.d.ts +31 -0
- package/dist/backend/routes/chat.d.ts.map +1 -0
- package/dist/backend/routes/chat.js +426 -0
- package/dist/backend/routes/chat.js.map +1 -0
- package/dist/backend/routes/data.d.ts +13 -0
- package/dist/backend/routes/data.d.ts.map +1 -0
- package/dist/backend/routes/data.js +134 -0
- package/dist/backend/routes/data.js.map +1 -0
- package/dist/backend/routes/health.d.ts +7 -0
- package/dist/backend/routes/health.d.ts.map +1 -0
- package/dist/backend/routes/health.js +15 -0
- package/dist/backend/routes/health.js.map +1 -0
- package/dist/backend/routes/index.d.ts +11 -0
- package/dist/backend/routes/index.d.ts.map +1 -0
- package/dist/backend/routes/index.js +9 -0
- package/dist/backend/routes/index.js.map +1 -0
- package/dist/backend/routes/skills.d.ts +16 -0
- package/dist/backend/routes/skills.d.ts.map +1 -0
- package/dist/backend/routes/skills.js +590 -0
- package/dist/backend/routes/skills.js.map +1 -0
- package/dist/backend/routes/upload.d.ts +24 -0
- package/dist/backend/routes/upload.d.ts.map +1 -0
- package/dist/backend/routes/upload.js +67 -0
- package/dist/backend/routes/upload.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +12 -0
- package/dist/bin.js.map +1 -0
- package/dist/capability-generator.d.ts +21 -6
- package/dist/capability-generator.d.ts.map +1 -1
- package/dist/capability-generator.js +88 -261
- package/dist/capability-generator.js.map +1 -1
- package/dist/cli/commands/build.d.ts +11 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +170 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/data.d.ts +12 -0
- package/dist/cli/commands/data.d.ts.map +1 -0
- package/dist/cli/commands/data.js +158 -0
- package/dist/cli/commands/data.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +9 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +114 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate-capabilities.d.ts +8 -0
- package/dist/cli/commands/generate-capabilities.d.ts.map +1 -0
- package/dist/cli/commands/generate-capabilities.js +40 -0
- package/dist/cli/commands/generate-capabilities.js.map +1 -0
- package/dist/cli/commands/generate-cli-command.d.ts +8 -0
- package/dist/cli/commands/generate-cli-command.d.ts.map +1 -0
- package/dist/cli/commands/generate-cli-command.js +64 -0
- package/dist/cli/commands/generate-cli-command.js.map +1 -0
- package/dist/cli/commands/generate-page.d.ts +9 -0
- package/dist/cli/commands/generate-page.d.ts.map +1 -0
- package/dist/cli/commands/generate-page.js +641 -0
- package/dist/cli/commands/generate-page.js.map +1 -0
- package/dist/cli/commands/generate-skill.d.ts +8 -0
- package/dist/cli/commands/generate-skill.d.ts.map +1 -0
- package/dist/cli/commands/generate-skill.js +75 -0
- package/dist/cli/commands/generate-skill.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +6 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +17 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +539 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/observe.d.ts +9 -0
- package/dist/cli/commands/observe.d.ts.map +1 -0
- package/dist/cli/commands/observe.js +142 -0
- package/dist/cli/commands/observe.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +9 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +186 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/helpers/duration.d.ts +5 -0
- package/dist/cli/helpers/duration.d.ts.map +1 -0
- package/dist/cli/helpers/duration.js +19 -0
- package/dist/cli/helpers/duration.js.map +1 -0
- package/dist/cli/helpers/field-template.d.ts +10 -0
- package/dist/cli/helpers/field-template.d.ts.map +1 -0
- package/dist/cli/helpers/field-template.js +100 -0
- package/dist/cli/helpers/field-template.js.map +1 -0
- package/dist/cli/helpers/naming.d.ts +12 -0
- package/dist/cli/helpers/naming.d.ts.map +1 -0
- package/dist/cli/helpers/naming.js +25 -0
- package/dist/cli/helpers/naming.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils.d.ts +10 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +31 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/config.d.ts +8 -40
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -8
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/server-bin.d.ts +12 -0
- package/dist/server-bin.d.ts.map +1 -0
- package/dist/server-bin.js +75 -0
- package/dist/server-bin.js.map +1 -0
- package/dist/types.d.ts +33 -20
- package/dist/types.d.ts.map +1 -1
- package/package.json +25 -10
- package/templates/app-skill/SKILL.md +27 -0
- package/templates/app-skill/references/data-semantics.md +44 -0
- package/templates/app-skill/references/models.md +31 -0
- package/templates/loom-skill/SKILL.md +140 -0
- package/templates/loom-skill/references/README.md +128 -0
- package/templates/loom-skill/references/data-model.md +78 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loom-framework/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
4
|
-
"description": "Loom framework
|
|
3
|
+
"version": "0.1.0-alpha.80",
|
|
4
|
+
"description": "Loom framework - DataAdapter, Capability Generator, config system, backend server, CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -11,24 +11,39 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"loom": "dist/bin.js",
|
|
16
|
+
"core": "dist/bin.js",
|
|
17
|
+
"loom-server": "dist/server-bin.js"
|
|
18
|
+
},
|
|
14
19
|
"files": [
|
|
15
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"templates"
|
|
16
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"dev": "tsc --watch",
|
|
26
|
+
"clean": "rm -rf dist",
|
|
27
|
+
"lint": "tsc --noEmit"
|
|
28
|
+
},
|
|
17
29
|
"dependencies": {
|
|
30
|
+
"@fastify/cors": "^10.0.0",
|
|
31
|
+
"@fastify/static": "^8.0.0",
|
|
32
|
+
"adm-zip": "^0.5.17",
|
|
33
|
+
"chalk": "^5.3.0",
|
|
34
|
+
"commander": "^12.1.0",
|
|
35
|
+
"fastify": "^5.2.0",
|
|
36
|
+
"glob": "^11.0.0",
|
|
18
37
|
"jiti": "^2.6.1",
|
|
38
|
+
"ora": "^8.0.0",
|
|
19
39
|
"zod": "^3.23.0"
|
|
20
40
|
},
|
|
21
41
|
"optionalDependencies": {
|
|
22
42
|
"better-sqlite3": "^12.8.0"
|
|
23
43
|
},
|
|
24
44
|
"devDependencies": {
|
|
45
|
+
"@types/adm-zip": "^0.5.8",
|
|
25
46
|
"@types/better-sqlite3": "^7.6.13",
|
|
26
47
|
"typescript": "^5.6.0"
|
|
27
|
-
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsc",
|
|
30
|
-
"dev": "tsc --watch",
|
|
31
|
-
"clean": "rm -rf dist",
|
|
32
|
-
"lint": "tsc --noEmit"
|
|
33
48
|
}
|
|
34
|
-
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{projectName}}-data
|
|
3
|
+
description: |
|
|
4
|
+
[阅读 references/models.md 中的数据模型和 AI 按钮定义,编写触发短语。
|
|
5
|
+
包含:用户语言中的常见增删改查动词、各数据模型相关的操作、AI 按钮的标签。
|
|
6
|
+
格式:"This skill should be used when the user asks to '短语1', '短语2',
|
|
7
|
+
or any request about <此项目管理的内容> in the {{projectName}} project."]
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# {{projectName}} — App Skill
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
[阅读 references/models.md,用2-3句话描述:项目做什么、管理哪些数据模型、用户如何通过 AI 对话与数据交互。]
|
|
16
|
+
|
|
17
|
+
## Usage Scenarios
|
|
18
|
+
|
|
19
|
+
[**必须加载 references/models.md 和 references/data-semantics.md**,这两个文件包含从 loom.config.ts 动态注入的项目特定信息,不加载则无法生成正确内容。
|
|
20
|
+
- models.md — 当前项目的数据模型字段表(字段名、类型、enum 取值、默认值)、AI 按钮定义(id、label、prompt、placement)、CLI 命令语法(read/write/update/delete,不要使用 create/list 等不存在的命令)。
|
|
21
|
+
- data-semantics.md — 当前项目的数据模型名称列表、write 的 --data JSON 构造规则(字段类型格式、enum 取值约束、贴合业务的真实示例值)、read 的 --filter JSON 构造规则(优先用 enum/boolean 字段筛选、跨模型关联查询)。
|
|
22
|
+
再生成8-10个典型用户请求,每个格式:用户说的话 → 对应的 `loom data` CLI 命令。每个数据模型至少包含一个场景。]
|
|
23
|
+
|
|
24
|
+
## Technical Reference
|
|
25
|
+
|
|
26
|
+
- 数据模型结构、CLI 语法和操作规范:**references/models.md**
|
|
27
|
+
- 语义引导(示例数据生成、筛选选择、关系推断):**references/data-semantics.md**
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 数据语义引导
|
|
2
|
+
|
|
3
|
+
> 本文件由 `loom generate capabilities` 自动生成。请勿手动编辑 — 重新生成时将被覆盖。
|
|
4
|
+
|
|
5
|
+
生成 `loom data` CLI 命令时,阅读 `loom.config.ts` 获取数据模型定义,并遵循以下规则生成贴合业务的输出。
|
|
6
|
+
|
|
7
|
+
注:本文中的"数据模型"指 loom.config.ts 中定义的数据结构(如 wrong_questions、review_plans),而非大语言模型。
|
|
8
|
+
|
|
9
|
+
## 示例数据生成
|
|
10
|
+
|
|
11
|
+
构造 write 命令的 `--data` JSON 时:
|
|
12
|
+
|
|
13
|
+
- 根据字段名、类型、描述和枚举值生成**贴合业务的真实值**。
|
|
14
|
+
例如名为 `questionContent`、描述为"题目内容"的字段,应填真实题目如 `"3+5=?"`,而非 `"value"`。
|
|
15
|
+
- 遵守 **FieldType**:`number` → 不加引号的数字(`1`),`boolean` → 不加引号的布尔值(`false`),
|
|
16
|
+
`date` → ISO 日期字符串(`"2026-01-15"`),`string[]` → JSON 数组(`["标签1"]`),`json` → JSON 对象(`{}`)。
|
|
17
|
+
- 有 **enum** 时必须使用枚举值 — 这是该字段唯一切合法的取值。
|
|
18
|
+
- write 命令只需包含**必填字段**,可选字段可省略。
|
|
19
|
+
- update 命令只需传入**要变更的字段**。
|
|
20
|
+
|
|
21
|
+
## 筛选条件选择
|
|
22
|
+
|
|
23
|
+
构造 read 命令的 `--filter` JSON 时:
|
|
24
|
+
|
|
25
|
+
- **优先使用 enum 和 boolean 字段**做筛选 — 它们能产生最有意义的分区
|
|
26
|
+
(如 `{"subject": "数学"}`、`{"mastered": false}`)。
|
|
27
|
+
- 选择**业务含义最丰富的筛选条件**,而非按字母序取第一个字段。
|
|
28
|
+
- 可组合多个筛选:`{"subject": "数学", "mastered": false}`。
|
|
29
|
+
- 数据量大时使用 `--limit` 避免输出过多。
|
|
30
|
+
|
|
31
|
+
## 跨数据模型关联
|
|
32
|
+
|
|
33
|
+
当字段名以 `Id` 结尾(如 `wrongQuestionId`)时,通常引用的是另一个数据模型的记录。
|
|
34
|
+
|
|
35
|
+
- 查询关联记录:`loom data read <目标数据模型> --id <值>`。
|
|
36
|
+
- 查询指向某条记录的所有关联:`loom data read <数据模型> --filter '{"<外键字段>": "<id>"}'`。
|
|
37
|
+
- 常见命名模式:`parentId` → 自引用,`<数据模型名>Id` → 引用该数据模型。
|
|
38
|
+
|
|
39
|
+
<!-- MODEL_NAMES -->
|
|
40
|
+
|
|
41
|
+
## AI 按钮校验
|
|
42
|
+
|
|
43
|
+
执行 AI 按钮操作前,验证 prompt 中所有 `{{var}}` 占位符是否对应目标数据模型上的实际字段。
|
|
44
|
+
如果变量引用了不存在的字段,告知用户并建议添加该字段或更新 prompt。
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 数据模型与 CLI 参考
|
|
2
|
+
|
|
3
|
+
> 本文件由 `loom generate capabilities` 自动生成。请勿手动编辑 — 重新生成时将被覆盖。
|
|
4
|
+
|
|
5
|
+
## 数据模型
|
|
6
|
+
|
|
7
|
+
<!-- DATA_MODELS -->
|
|
8
|
+
|
|
9
|
+
## CLI 命令
|
|
10
|
+
|
|
11
|
+
所有数据操作使用 `loom data` CLI 命令,需在项目根目录下执行。
|
|
12
|
+
|
|
13
|
+
| 命令 | 说明 |
|
|
14
|
+
|------|------|
|
|
15
|
+
| `loom data read <model> [--id <id>] [--filter <json>] [--limit <n>]` | 读取记录 |
|
|
16
|
+
| `loom data write <model> --data '<json>'` | 创建记录 |
|
|
17
|
+
| `loom data update <model> --id <id> --data '<json>'` | 更新记录 |
|
|
18
|
+
| `loom data delete <model> --id <id>` | 删除记录 |
|
|
19
|
+
| `loom data schema [model]` | 查看数据模型结构 |
|
|
20
|
+
|
|
21
|
+
<!-- AI_BUTTONS -->
|
|
22
|
+
|
|
23
|
+
## 操作规范
|
|
24
|
+
|
|
25
|
+
1. 所有数据操作必须使用 `loom data` CLI 命令,不要直接访问文件或数据库。
|
|
26
|
+
2. 命令在项目根目录下执行。
|
|
27
|
+
3. 执行删除等不可逆操作前,需与用户确认。
|
|
28
|
+
4. 创建/更新时确保必填字段齐全。不确定时用 `loom data schema <model>` 查看。
|
|
29
|
+
5. `update` 只需传入要修改的字段,未指定的字段保持不变。
|
|
30
|
+
6. CLI 输出格式为 JSON — 解析输出以理解数据结构。
|
|
31
|
+
7. 数据变更后,告知用户页面会自动刷新。
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Loom
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill when the user asks to "create a new loom project", "用loom开发一个系统",
|
|
5
|
+
"开发一个AI平台应用", "为系统添加页面", "为项目配置 AI 按钮功能", or any Loom framework task.
|
|
6
|
+
Loom is an AI-Native full-stack framework.
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Loom - AI 原生全栈框架技能
|
|
11
|
+
|
|
12
|
+
## 框架工作方式
|
|
13
|
+
|
|
14
|
+
Loom 是**配置驱动、自动生成**的框架。工作流程为:
|
|
15
|
+
|
|
16
|
+
1. **写配置** — 编辑 `loom.config.ts`,定义数据模型和 AI 按钮
|
|
17
|
+
2. **跑命令** — CLI 读取配置,自动生成页面、API 和路由接线
|
|
18
|
+
|
|
19
|
+
`loom generate page` 会自动生成:CRUD 页面(含 AI 按钮)、App.tsx 路由接线、后端 API + 应用 Skill。
|
|
20
|
+
生成的页面自带 AI 助手浮动按钮,支持流式对话、多会话和数据自动刷新。
|
|
21
|
+
|
|
22
|
+
技术架构细节见 `references/README.md`。
|
|
23
|
+
|
|
24
|
+
## 开发流程
|
|
25
|
+
|
|
26
|
+
**重要:** 始终在项目目录下运行命令(不是 loom monorepo 根目录)。
|
|
27
|
+
|
|
28
|
+
### 1. 创建项目
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx -p @loom-framework/core loom init <name> --description <desc> --adapter <filesystem|sqlite>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. 编辑配置
|
|
35
|
+
|
|
36
|
+
编辑 `loom.config.ts`,定义数据模型(`data.models`)和 AI 按钮(`aiButtons`),Schema 见下方。高级选项见 `references/data-model.md`。
|
|
37
|
+
|
|
38
|
+
### 3. 生成页面 + 应用 Skill
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
loom generate page <Name> --model <model-name>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
此命令自动生成:CRUD 页面(含 AI 按钮)、App.tsx 路由接线、后端 API、应用 Skill。数据实体立即可通过 `loom data` CLI 和 AI 对话使用。
|
|
45
|
+
|
|
46
|
+
### 4. 补充应用 Skill 描述(必须)
|
|
47
|
+
|
|
48
|
+
首次生成后,必须补充 `.claude/skills/<项目名>/SKILL.md` 中以下三处 TODO,AI 对话才能正确理解项目业务语义:
|
|
49
|
+
|
|
50
|
+
1. **frontmatter `description`**:写入用户在 AI 对话中会说的触发短语。格式参考:
|
|
51
|
+
```
|
|
52
|
+
This skill should be used when the user asks to "创建XXX", "查看XXX", "删除XXX",
|
|
53
|
+
or any request about managing XXX in the <项目名> project.
|
|
54
|
+
```
|
|
55
|
+
2. **Overview 部分**:用 2-3 句话描述项目做什么、有哪些数据、用户如何与数据交互
|
|
56
|
+
3. **Usage Scenarios 部分**:列出 5-10 个典型用户请求,格式为 `- "用户说的话" → 对应的 CLI 命令`
|
|
57
|
+
|
|
58
|
+
### 5. 启动开发
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
loom dev
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- 前端:http://localhost:5173
|
|
65
|
+
- 后端:http://localhost:3000
|
|
66
|
+
|
|
67
|
+
### 迭代:修改配置 → 重新生成
|
|
68
|
+
|
|
69
|
+
编辑 `loom.config.ts`(添加/修改数据实体或 AI 按钮)→ 重新执行步骤 3。
|
|
70
|
+
|
|
71
|
+
### 可选:添加更多 Skill
|
|
72
|
+
|
|
73
|
+
`.claude/skills/` 下的所有 Skill 都会被 AI 自动发现。除了自动生成的应用 Skill,还可以添加新的:
|
|
74
|
+
|
|
75
|
+
- `loom generate skill <name>` — 创建脚手架,然后编辑 `.claude/skills/<name>/SKILL.md`
|
|
76
|
+
- 或直接复制一个已有的 Skill 目录到 `.claude/skills/` 下
|
|
77
|
+
|
|
78
|
+
### CLI 命令速查
|
|
79
|
+
|
|
80
|
+
| 命令 | 说明 |
|
|
81
|
+
|------|------|
|
|
82
|
+
| `loom dev` | 启动开发环境(`--skip-generate` `--backend-only` `--frontend-only`) |
|
|
83
|
+
| `loom build` | 生产构建 |
|
|
84
|
+
| `loom generate page <name> --model <model>` | 生成 CRUD 页面 + 应用 Skill(含 aiButtons 则自动集成) |
|
|
85
|
+
| `loom generate capabilities` | 仅重新生成应用 Skill 的 `references/models.md` |
|
|
86
|
+
| `loom generate skill <name>` | 生成自定义 Skill 脚手架 |
|
|
87
|
+
|
|
88
|
+
## loom.config.ts Schema(核心)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { defineConfig } from '@loom-framework/core';
|
|
92
|
+
|
|
93
|
+
export default defineConfig({
|
|
94
|
+
project: {
|
|
95
|
+
name: 'my-app', // 必填
|
|
96
|
+
description: '...',', // 可选
|
|
97
|
+
},
|
|
98
|
+
data: {
|
|
99
|
+
defaultAdapter: 'filesystem', // 'filesystem' | 'sqlite'
|
|
100
|
+
models: [{
|
|
101
|
+
name: 'items', // 将作为 React 组件名生成页面,字母开头,字母/数字/下划线
|
|
102
|
+
description: '...',', // 可选:显示在生成页面中
|
|
103
|
+
fields: [{
|
|
104
|
+
name: 'status', // 字母/下划线开头,字母数字下划线
|
|
105
|
+
type: 'string', // 'string' | 'number' | 'boolean' | 'date' | 'string[]' | 'number[]' | 'json'
|
|
106
|
+
required: true, // 可选,默认 false
|
|
107
|
+
description: '...,', // 可选:显示在表单中
|
|
108
|
+
default: 'active', // 可选:写入时自动填充
|
|
109
|
+
enum: ['active', 'inactive'], // 可选:限制可选值
|
|
110
|
+
}],
|
|
111
|
+
}],
|
|
112
|
+
},
|
|
113
|
+
aiButtons: [{ // 可选
|
|
114
|
+
id: 'summarize', // 必填:唯一标识
|
|
115
|
+
label: '总结', // 必填:按钮文本
|
|
116
|
+
prompt: '请总结以下内容', // 必填:支持 {{var}} 引用当前行字段值
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'analyze', // 带变量的示例
|
|
120
|
+
label: '分析',
|
|
121
|
+
prompt: '分析{{questionContent}},错误答案:{{wrongAnswer}}',
|
|
122
|
+
placement: 'wrong_questions', // 可选:限制按钮只出现在指定数据实体的页面,逗号分隔多个实体名;省略则出现在所有页面
|
|
123
|
+
}],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
高级配置(`ai.claudeCode`、`server`、各数据实体的 `adapters`、`indexes`)见 `references/data-model.md`。
|
|
128
|
+
|
|
129
|
+
## API 路由格式
|
|
130
|
+
|
|
131
|
+
后端 REST API 路径为 `/api/v1/data/<model-name>`,支持:`GET`(列表)、`GET /:id`(单条)、`POST`(创建)、`PUT /:id`(更新)、`DELETE /:id`(删除)。
|
|
132
|
+
AI 相关:`POST /api/v1/chat`(SSE 流式对话)、`GET /api/v1/sessions`(会话列表)。
|
|
133
|
+
前端通过 `useData('<model-name>')` 自动访问,无需手动拼接。
|
|
134
|
+
|
|
135
|
+
**注意:** `sqlite` 适配器在 Node.js ≥ 25 时可能因 `better-sqlite3` 原生模块未编译而报错,改用 `filesystem` 即可。
|
|
136
|
+
|
|
137
|
+
## 常见问题
|
|
138
|
+
|
|
139
|
+
- **better-sqlite3 加载失败**:Node.js 版本缺少预编译包。修复:(1) `cd node_modules/better-sqlite3 && npx node-gyp rebuild`,或 (2) 将 `defaultAdapter` 改为 `'filesystem'`
|
|
140
|
+
- **`loom` 命令报错 "No loom.config.ts found"**:在项目目录下运行命令
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Loom - AI-Native Full-Stack Framework
|
|
2
|
+
|
|
3
|
+
编织 AI 能力为应用织物
|
|
4
|
+
|
|
5
|
+
## 快速上手
|
|
6
|
+
|
|
7
|
+
### 1. 安装 npm 包
|
|
8
|
+
|
|
9
|
+
Loom 包含两个包:
|
|
10
|
+
|
|
11
|
+
- `@loom-framework/core` — CLI + 后端(全局安装以使用 `loom` 命令)
|
|
12
|
+
- `@loom-framework/frontend-antd` — 前端组件库(项目运行时依赖,`loom init` 自动添加)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @loom-framework/core
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 2. 配置 Skill 到 Claude Code
|
|
19
|
+
|
|
20
|
+
Loom Skill 随 npm 包发布,位于 `templates/loom-skill/` 目录。复制到 Claude Code 的 skill 目录:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 从全局安装复制
|
|
24
|
+
cp -r $(npm root -g)/@loom-framework/core/templates/loom-skill ~/.claude/skills/loom
|
|
25
|
+
|
|
26
|
+
# 或从项目内复制
|
|
27
|
+
cp -r node_modules/@loom-framework/core/templates/loom-skill ~/.claude/skills/loom
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. 打开 Claude Code
|
|
31
|
+
|
|
32
|
+
启动 Claude Code,Skill 会被自动加载。
|
|
33
|
+
|
|
34
|
+
### 4. 开始使用
|
|
35
|
+
|
|
36
|
+
在 Claude Code 中输入以下内容触发 Loom Skill:
|
|
37
|
+
|
|
38
|
+
### 开始开发
|
|
39
|
+
|
|
40
|
+
在 Claude Code 中输入以下内容即可触发 Loom Skill:
|
|
41
|
+
|
|
42
|
+
- "用 loom 开发一个 AI 平台"
|
|
43
|
+
- "创建一个 loom 项目"
|
|
44
|
+
- "为系统添加页面"
|
|
45
|
+
- "配置 AI 按钮"
|
|
46
|
+
|
|
47
|
+
示例对话:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
用户: 用 loom 开发一个笔记管理系统,用 sqlite 存储,
|
|
51
|
+
需要 AI 总结和翻译功能
|
|
52
|
+
Claude: [读取 SKILL.md] → 运行 loom init → 编辑 config →
|
|
53
|
+
loom generate page → loom dev
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 开发流程
|
|
57
|
+
|
|
58
|
+
1. **创建项目**:`npx -p @loom-framework/core loom init <name> --description <desc> --adapter <adapter>`
|
|
59
|
+
2. **编辑配置**:在 `loom.config.ts` 中定义数据模型和 AI 按钮
|
|
60
|
+
3. **生成页面**:`loom generate page <Name> --model <model>`
|
|
61
|
+
4. **启动开发**:`loom dev` → http://localhost:5173
|
|
62
|
+
|
|
63
|
+
## 核心理念
|
|
64
|
+
|
|
65
|
+
- **Prompt as Code**: 业务逻辑写在 Skill 的 Markdown 中,而非后端代码
|
|
66
|
+
- **Schema-driven**: 一个数据实体定义 → Skill + CLI 命令 + REST API(自动同步)
|
|
67
|
+
- **Zero Backend Logic**: 后端是透明代理,所有智能在 Skill 中
|
|
68
|
+
|
|
69
|
+
## 三种交互类型
|
|
70
|
+
|
|
71
|
+
| 类型 | 说明 | 用户入口 | 自动化程度 |
|
|
72
|
+
|------|------|---------|-----------|
|
|
73
|
+
| AI Chat | 自然语言对话 | AppShell 右下角浮动按钮 | 开箱即用,无需配置 |
|
|
74
|
+
| AI Buttons | 一键 AI 动作 | CRUD 页面操作列的 AI 下拉菜单 | 配置 aiButtons + generate page,自动集成 |
|
|
75
|
+
| CRUD | 结构化数据管理 | 导航菜单页面 | 配置 model + generate page,自动生成 |
|
|
76
|
+
|
|
77
|
+
## 组件架构
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
AppShell
|
|
81
|
+
├── Layout (Sider + Content)
|
|
82
|
+
└── AIBubble → ChatDrawer → ChatPanel
|
|
83
|
+
├── LoomChatProvider + useXChat
|
|
84
|
+
├── MessageContent (thinking / content / tool_call)
|
|
85
|
+
└── Sender (输入框 + 文件上传)
|
|
86
|
+
|
|
87
|
+
AIActionButton → AIContext.triggerAI() → ChatDrawer 自动提交
|
|
88
|
+
useData → 监听 loom:data-changed 事件自动刷新
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### AI 按钮工作流
|
|
92
|
+
|
|
93
|
+
1. 点击 AI 按钮 → `AIContext.triggerAI({ query, buttonId, context })`
|
|
94
|
+
2. ChatDrawer 打开并自动提交 prompt
|
|
95
|
+
3. AI 可能通过工具调用进行 CRUD 操作
|
|
96
|
+
4. done 事件触发 `loom:data-changed` → useData 自动 refresh
|
|
97
|
+
|
|
98
|
+
### 前端组件导出
|
|
99
|
+
|
|
100
|
+
| 组件/Hook | 说明 |
|
|
101
|
+
|-----------|------|
|
|
102
|
+
| `AppShell` | 应用布局框架,内含 AIBubble |
|
|
103
|
+
| `ChatDrawer` | AI 对话抽屉(多会话、流式、thinking/tool_call) |
|
|
104
|
+
| `AIBubble` | AI 浮动按钮(imperativeHandle: openWithQuery) |
|
|
105
|
+
| `AIActionButton` | AI 动作按钮(通过 AIContext 触发 ChatDrawer) |
|
|
106
|
+
| `AIContext` | AI 上下文(AppShell 提供 triggerAI) |
|
|
107
|
+
| `useData` | 数据 CRUD hook(自动响应 loom:data-changed 事件) |
|
|
108
|
+
|
|
109
|
+
## 项目结构
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
my-loom-app/
|
|
113
|
+
├── loom.config.ts # 配置源
|
|
114
|
+
├── frontend/src/components/pages/ # 业务页面
|
|
115
|
+
├── backend/src/ # Fastify + AI 通信
|
|
116
|
+
├── .claude/skills/ # Skills
|
|
117
|
+
├── cli/src/commands/ # CLI 命令扩展
|
|
118
|
+
├── data/ # 数据存储
|
|
119
|
+
└── .loom/ # 自动生成(gitignore)
|
|
120
|
+
└── sessions/ # AI 会话持久化
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 两个包
|
|
124
|
+
|
|
125
|
+
| 包 | 说明 |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `@loom-framework/core` | DataAdapter、LoomServer、CLI(loom / loom-server) |
|
|
128
|
+
| `@loom-framework/frontend-antd` | 前端组件库:AppShell、ChatDrawer、AIActionButton、useData、AIContext |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Data Model Reference
|
|
2
|
+
|
|
3
|
+
Advanced configuration for `loom.config.ts`. Full type definitions from `packages/core/src/types.ts`.
|
|
4
|
+
|
|
5
|
+
## FieldDefinition
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
{
|
|
9
|
+
name: 'status', // ^[a-zA-Z_][a-zA-Z0-9_]*$
|
|
10
|
+
type: 'string', // 'string' | 'number' | 'boolean' | 'date' | 'string[]' | 'number[]' | 'json'
|
|
11
|
+
required: true, // optional, default false
|
|
12
|
+
description: '...', // optional: shown in generated forms
|
|
13
|
+
default: 'active', // optional: auto-filled on write if not provided
|
|
14
|
+
enum: ['active', 'inactive', 'archived'], // optional: restrict string field to allowed values
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## ModelSchema
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
{
|
|
22
|
+
name: 'orders', // ^[a-zA-Z][a-zA-Z0-9_]*$, will be used as React component name
|
|
23
|
+
description: 'Order records', // optional: shown in generated page heading
|
|
24
|
+
fields: [...],
|
|
25
|
+
indexes?: [{ fields: ['userId', 'status'], unique: false }],
|
|
26
|
+
adapters?: { // optional: per-model adapter override
|
|
27
|
+
filesystem: { dir: 'orders', format: 'json' | 'yaml', datePattern: 'YYYY-MM' },
|
|
28
|
+
sqlite: { table: 'orders' },
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## AIButtonConfig
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
aiButtons: [{
|
|
37
|
+
id: 'summarize', // required: unique identifier
|
|
38
|
+
label: '总结', // required: button text
|
|
39
|
+
icon: 'FileTextOutlined', // optional: Ant Design icon component name
|
|
40
|
+
prompt: '请总结以下内容', // required: supports {{var}} placeholders, replaced with current row field values
|
|
41
|
+
placement: 'wrong_questions', // optional: limit to specific model pages, comma-separated; omit for all pages
|
|
42
|
+
}]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## AIConfig
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
ai: {
|
|
49
|
+
engine: 'claude-code', // default 'claude-code'
|
|
50
|
+
claudeCode: {
|
|
51
|
+
path: '/usr/local/bin/claude', // optional: custom claude binary path
|
|
52
|
+
pluginRoot: '.claude', // optional: plugin root directory
|
|
53
|
+
timeout: 120000, // optional: command timeout in ms
|
|
54
|
+
skipPermissions: false, // optional: skip permission prompts
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## ServerConfig
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
server: {
|
|
63
|
+
port: 3000, // default 3000
|
|
64
|
+
host: '0.0.0.0',
|
|
65
|
+
cors: true, // default true
|
|
66
|
+
staticDir: './dist/frontend',
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## DataConfig
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
data: {
|
|
74
|
+
defaultAdapter: 'filesystem' | 'sqlite',
|
|
75
|
+
models: [...],
|
|
76
|
+
sqlite: { filename: 'data.db' }, // optional, default 'loom.db'
|
|
77
|
+
}
|
|
78
|
+
```
|