draftgo-cli 3.0.1 → 3.0.33
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/LICENSE +21 -0
- package/README.md +73 -124
- package/package.json +21 -8
- package/resources/skill/SKILL.md +62 -89
- package/resources/skill/init/SKILL.md +18 -67
- package/resources/skill/manifest.json +27 -0
- package/resources/skill/pull/SKILL.md +18 -44
- package/resources/skill/push/SKILL.md +30 -247
- package/resources/skill/references/aihub.md +86 -0
- package/resources/skill/references/api-endpoints.md +178 -0
- package/resources/skill/references/api.json +20248 -0
- package/resources/skill/{quickref → references}/app-api.md +44 -14
- package/resources/skill/{core → references}/architecture.md +6 -26
- package/resources/skill/references/chat-sdk.md +201 -0
- package/resources/skill/references/custom-services.md +308 -0
- package/resources/skill/references/data.md +298 -0
- package/resources/skill/references/db-relations.md +227 -0
- package/resources/skill/references/frontend.md +788 -0
- package/resources/skill/references/modules.md +66 -0
- package/resources/skill/references/parallel.md +48 -0
- package/resources/skill/{specs → references}/runtime.md +31 -1
- package/resources/skill/{specs → references}/security.md +3 -3
- package/resources/skill/references/ui-protocol.md +99 -0
- package/resources/skill/scripts/draftgo_delete.py +0 -2
- package/resources/skill/scripts/draftgo_init.py +15 -3
- package/resources/skill/scripts/draftgo_pull.py +154 -87
- package/resources/skill/scripts/draftgo_push.py +440 -183
- package/resources/skill/story/SKILL.md +13 -23
- package/src/cli.js +22 -7
- package/src/commandRegistry.js +34 -0
- package/src/commands/api.js +204 -0
- package/src/commands/autoPush.js +41 -0
- package/src/commands/check.js +27 -17
- package/src/commands/delete.js +6 -4
- package/src/commands/deploy.js +31 -0
- package/src/commands/help.js +41 -28
- package/src/commands/init.js +34 -20
- package/src/commands/local.js +9 -3
- package/src/commands/map.js +18 -7
- package/src/commands/sync.js +11 -4
- package/src/commands/update.js +39 -52
- package/src/commands/verifyUi.js +199 -0
- package/src/index.js +13 -46
- package/src/localdev/compose.js +48 -197
- package/src/localdev/index.js +116 -216
- package/src/localdev/mysqlClient.js +12 -9
- package/src/localdev/services.js +163 -0
- package/src/platforms.js +3 -3
- package/src/projectConfig.js +12 -2
- package/src/projectMap.js +240 -68
- package/src/skill.js +113 -29
- package/src/updateCheck.js +37 -15
- package/resources/skill/core/modules.md +0 -54
- package/resources/skill/practices/anti-patterns.md +0 -70
- package/resources/skill/practices/best-practices.md +0 -41
- package/resources/skill/practices/dev-declaration.md +0 -94
- package/resources/skill/quickref/api-endpoints.md +0 -130
- package/resources/skill/quickref/api.json +0 -17675
- package/resources/skill/quickref/dg-components.md +0 -198
- package/resources/skill/rules/dev-workflow.md +0 -652
- package/resources/skill/rules/frontend.md +0 -210
- package/resources/skill/rules/parallel.md +0 -263
- package/resources/skill/specs/data.md +0 -108
- package/resources/skill/specs/ui-protocol.md +0 -68
- package/src/commands/doctor.js +0 -54
- package/src/commands/new.js +0 -183
- package/src/commands/projectScript.js +0 -37
- /package/resources/skill/{rules → references}/debugging-syntax.md +0 -0
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: draftgo-frontend-rules
|
|
3
|
-
description: DraftGo frontend page development rules.
|
|
4
|
-
version: 2.0.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# DraftGo 前端开发规范
|
|
8
|
-
|
|
9
|
-
> 本文件只规定前端**操作性规则**,已剥离的内容见:
|
|
10
|
-
> 架构原理 → `{{SKILL_DIR}}/core/architecture.md`
|
|
11
|
-
> App API / Token / 路由 / 运行时 → `{{SKILL_DIR}}/specs/runtime.md` · `{{SKILL_DIR}}/quickref/app-api.md`
|
|
12
|
-
> dg-* 映射 → `{{SKILL_DIR}}/specs/ui-protocol.md` · `{{SKILL_DIR}}/quickref/dg-components.md`
|
|
13
|
-
> 动态 DB / filters → `{{SKILL_DIR}}/specs/data.md`
|
|
14
|
-
> 开发禁区 → `{{SKILL_DIR}}/specs/security.md`
|
|
15
|
-
|
|
16
|
-
若本地 Agent 存在前端 UI Skills,前端界面开发时优先调用。
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 页面开发强制规则
|
|
21
|
-
|
|
22
|
-
### 真实闭环(强制)
|
|
23
|
-
|
|
24
|
-
- 页面必须有可访问 route,从真实入口可达(导航/首页/后台菜单/相关按钮至少一处)
|
|
25
|
-
- 按钮、表单、搜索、筛选、分页、提交、删除等交互默认真实有效
|
|
26
|
-
- 必须有加载态/空态/错误态/成功态,不能只堆静态卡片
|
|
27
|
-
- 展示可维护内容时主动判断是否需要后台管理页 + 同一份真实数据
|
|
28
|
-
- 无法实现真实闭环时停止开发,向用户说明阻塞点,写入 `.draftgo/lessons/`
|
|
29
|
-
|
|
30
|
-
### 操作型页面布局(强制)
|
|
31
|
-
|
|
32
|
-
后台管理、表格、列表等操作型页面用**工作台布局**,不用文档流堆叠:
|
|
33
|
-
|
|
34
|
-
```css
|
|
35
|
-
.workbench-page { min-height:100vh; display:flex; flex-direction:column; overflow:hidden; }
|
|
36
|
-
.workbench-toolbar { flex-shrink:0; }
|
|
37
|
-
.workbench-body { flex:1; min-height:0; display:flex; flex-direction:column; }
|
|
38
|
-
.workbench-data { flex:1; min-height:0; overflow:auto; }
|
|
39
|
-
.workbench-footer { flex-shrink:0; }
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
- 分页/操作栏/保存栏固定在工作区底部,不随数据量上浮
|
|
43
|
-
- 滚动发生在数据区,不是整页
|
|
44
|
-
|
|
45
|
-
### 新增页面绑定(强制)
|
|
46
|
-
|
|
47
|
-
- 公开页 → 顶部/侧边导航、首页入口、相关按钮之一
|
|
48
|
-
- 后台页 → 后台导航、管理菜单或现有后台入口
|
|
49
|
-
- 多页面功能:列表/详情/新建/编辑/管理必须互相走通
|
|
50
|
-
- 导航链接必须用 `data-page-route`:`<a href="/orders" data-page-route="/orders">订单</a>`
|
|
51
|
-
- 用户明确要求"隐藏页/草稿页"才可不绑定,但必须在 changelog / Task 说明原因
|
|
52
|
-
|
|
53
|
-
### `page_1_root.html` 首页特例(强制)
|
|
54
|
-
|
|
55
|
-
- 仍是默认内置首页 → 按用户需求和本地 UI Skills 重新实现,不沿用内置文案和结构
|
|
56
|
-
- 已被用户改过 → 只做要求范围内的修改,不强制重做
|
|
57
|
-
- 判断依据:看 HTML 内容是否保留 DraftGo 默认文案/系统介绍/未定制品牌,不要只凭文件名判断
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## 必须 / 禁止
|
|
62
|
-
|
|
63
|
-
### 必须
|
|
64
|
-
- 完整 HTML 文档结构(`<html><head><body>`)
|
|
65
|
-
- 静态资源用本地路径(见下方资源清单)
|
|
66
|
-
- 颜色全用语义 token `var(--dg-*)`
|
|
67
|
-
- 弹窗用 `App.confirm()` / `App.toast()`,禁止 `window.alert/confirm/prompt`
|
|
68
|
-
- 页面初始渲染展示默认状态(骨架屏),不能因请求延迟空白
|
|
69
|
-
- 需要组件能力时用对应 `dg-*` 标签
|
|
70
|
-
|
|
71
|
-
### 禁止
|
|
72
|
-
- ❌ 境外 CDN(googleapis / jsdelivr / cdnjs / unpkg)→ ✅ 国内镜像或本地资源
|
|
73
|
-
- ❌ 外部 CDN 引入图标 → ✅ `/assets/icons/{name}.svg`
|
|
74
|
-
- ❌ `window.alert/confirm/prompt`
|
|
75
|
-
- ❌ `App()` 写法 → ✅ `const App = window.parent?.App`
|
|
76
|
-
- ❌ `window.location.search` 读参数 → ✅ `window.__DG_ROUTE_CONTEXT__.query`
|
|
77
|
-
- ❌ 页面内 `window.location.href=...` 跳转 → ✅ `window.parent.location.href=...`
|
|
78
|
-
- ❌ TSX/React 版 shadcn 组件写进数据库 HTML
|
|
79
|
-
- ❌ `dg-*` 当 daisyUI / Bootstrap / Ant Design
|
|
80
|
-
- ❌ 硬编码颜色值 → ✅ `var(--dg-*)`
|
|
81
|
-
- ❌ 在业务页面实现全局浮窗/客服/统计脚本 → ✅ `frontend_global_*` 固定槽位
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## 本地静态资源清单
|
|
86
|
-
|
|
87
|
-
| 路径 | 说明 |
|
|
88
|
-
|---|---|
|
|
89
|
-
| `/assets/tailwindcss.js` | Tailwind CSS 运行时 |
|
|
90
|
-
| `/assets/fontawesome/css/all.min.css` | FontAwesome 6 |
|
|
91
|
-
| `/assets/icons/{name}.svg` | 内置精选 SVG 图标库(kebab-case 命名) |
|
|
92
|
-
| `/assets/icons/manifest.json` | 图标库映射清单 |
|
|
93
|
-
| `/assets/fonts/inter.css` | Inter 字体 |
|
|
94
|
-
| `/assets/fonts/lexend.css` | Lexend 字体 |
|
|
95
|
-
| `/assets/fonts/plus-jakarta-sans.css` | Plus Jakarta Sans |
|
|
96
|
-
| `/assets/fonts/plus-jakarta-sans-jetbrains-mono.css` | Plus Jakarta Sans + JetBrains Mono |
|
|
97
|
-
| `/assets/vendor/marked/marked.min.js` | Markdown 解析 |
|
|
98
|
-
| `/assets/vendor/prism/prism.min.js` | 代码高亮 |
|
|
99
|
-
| `/assets/vendor/gsap/gsap.min.js` | GSAP 核心 |
|
|
100
|
-
| `/assets/vendor/gsap/ScrollTrigger.min.js` | GSAP ScrollTrigger |
|
|
101
|
-
| `/assets/vendor/gsap/ScrollToPlugin.min.js` | GSAP ScrollTo |
|
|
102
|
-
| `/assets/vendor/gsap/Draggable.min.js` | GSAP Draggable |
|
|
103
|
-
| `/assets/vendor/gsap/Flip.min.js` | GSAP Flip |
|
|
104
|
-
| `/assets/vendor/gsap/SplitText.min.js` | GSAP SplitText |
|
|
105
|
-
| `/assets/vendor/gsap/CustomEase.min.js` | GSAP CustomEase |
|
|
106
|
-
|
|
107
|
-
**图标用法**:
|
|
108
|
-
```html
|
|
109
|
-
<!-- 跟随文字颜色(推荐) -->
|
|
110
|
-
<span aria-hidden="true" style="width:16px;height:16px;display:inline-block;background:currentColor;-webkit-mask:url('/assets/icons/fingerprint.svg') center/contain no-repeat;mask:url('/assets/icons/fingerprint.svg') center/contain no-repeat;"></span>
|
|
111
|
-
<!-- 保留原色 -->
|
|
112
|
-
<img src="/assets/icons/fingerprint.svg" alt="" width="16" height="16">
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
GSAP:禁止引用任何境外 CDN,必须用本地路径,注册插件后才能使用:`gsap.registerPlugin(ScrollTrigger, CustomEase)`
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## 颜色 Token(强制)
|
|
120
|
-
|
|
121
|
-
| Token | 用途 |
|
|
122
|
-
|---|---|
|
|
123
|
-
| `--dg-bg-base` / `--dg-bg-page` / `--dg-bg-surface` | 背景层级 |
|
|
124
|
-
| `--dg-text-primary` / `--dg-text-secondary` / `--dg-text-muted` | 文字层级 |
|
|
125
|
-
| `--dg-accent` / `--dg-accent-hover` / `--dg-accent-subtle` | 主题色 |
|
|
126
|
-
| `--dg-border` / `--dg-success` / `--dg-error` / `--dg-warning` | 功能色 |
|
|
127
|
-
|
|
128
|
-
例外:品牌色、图表色。硬编码时必须同时提供 `[data-theme="dark"]` 覆盖,对比度达 WCAG AA(文字 4.5:1)。
|
|
129
|
-
|
|
130
|
-
主题机制:壳层注入时已把 CSS 变量写入 `<head>`,页面无需初始化,直接用 `var(--dg-*)` 即可。
|
|
131
|
-
|
|
132
|
-
```javascript
|
|
133
|
-
// 读取(仅需 JS 分支时才读)
|
|
134
|
-
const theme = App?.theme; // 'light' | 'dark'
|
|
135
|
-
const scheme = App?.colorScheme; // 'dark-gray-white' | 'deep-blue-white' | ...
|
|
136
|
-
|
|
137
|
-
// 切换
|
|
138
|
-
App.applyTheme('dark');
|
|
139
|
-
App.setColorScheme('deep-blue-white');
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## 导航栏开发
|
|
145
|
-
|
|
146
|
-
| 属性 | 说明 |
|
|
147
|
-
|---|---|
|
|
148
|
-
| `data-nav-position="top\|side"` | 根元素必填 |
|
|
149
|
-
| `data-nav-width="220px"` | 侧边栏展开宽度(可选,默认 260px) |
|
|
150
|
-
| `data-nav-collapsed-width="64px"` | 收起宽度(可选,默认 72px) |
|
|
151
|
-
|
|
152
|
-
```html
|
|
153
|
-
<aside data-nav-position="side" data-nav-width="220px">
|
|
154
|
-
<a href="/dashboard" data-page-route="/dashboard">仪表盘</a>
|
|
155
|
-
</aside>
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
所有导航链接必须用 `data-page-route`,不要硬编 `onclick` 跳转。
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## AIHub 页面 SDK
|
|
163
|
-
|
|
164
|
-
```javascript
|
|
165
|
-
// 聊天
|
|
166
|
-
const text = await DraftGoAI.chat(agentId, '你好', (delta, full) => render(full));
|
|
167
|
-
|
|
168
|
-
// 图片生成(必须用 /images 接口,不要用 /chat)
|
|
169
|
-
const result = await DraftGoAI.images(agentId, '生成主图', { size: '1024x1024', n: 1 });
|
|
170
|
-
|
|
171
|
-
// 用户选模型
|
|
172
|
-
const { user_selectable, models } = await DraftGoAI.getSelectableModels(agentId);
|
|
173
|
-
await DraftGoAI.chat(agentId, '你好', handler, { model: selectedModel });
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 退出登录
|
|
179
|
-
|
|
180
|
-
```javascript
|
|
181
|
-
window.parent.location.href = '/login'; // ✅ 完整刷新,导航栏重新加载
|
|
182
|
-
// App.navigate('/login') ❌ 导航栏不会更新
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## 加载体验
|
|
188
|
-
|
|
189
|
-
- 初始渲染必须先展示骨架屏,再异步填数据
|
|
190
|
-
- 禁止因请求失败导致整页空白
|
|
191
|
-
- 空态必须有明确文案 + 后续操作入口,不能留空或只有 loading
|
|
192
|
-
- 若父级是 flex 工作区,空态容器应 `flex:1` 承接剩余空间,避免高度塌陷
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 平台能力调用快速参考
|
|
197
|
-
|
|
198
|
-
```javascript
|
|
199
|
-
const App = window.parent?.App;
|
|
200
|
-
|
|
201
|
-
// 响应信封:{ code: 200, data: <载荷>, message: "success" }
|
|
202
|
-
const res = await App.get('pages', { page: 1, page_size: 20 });
|
|
203
|
-
if (res.code !== 200) { App.showError(res.message); return; }
|
|
204
|
-
const items = res.data.items;
|
|
205
|
-
|
|
206
|
-
// URL 参数(三阶回落)
|
|
207
|
-
const q = (window.__DG_ROUTE_CONTEXT__ || window.__DG_GET_ROUTE_CONTEXT__?.() || App?.getCurrentRouteContext?.() || { query: {} }).query;
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
完整 API 表 → `{{SKILL_DIR}}/quickref/app-api.md`
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: draftgo-parallel-execution
|
|
3
|
-
description: DraftGo 并行开发协议。当 Task 清单中存在无依赖关系的任务组时,主代理可将其分发给子代理并行执行,显著提升开发效率。
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# DraftGo 并行开发协议
|
|
8
|
-
|
|
9
|
-
> 本协议是 dev-workflow.md 执行门的扩展。启用条件:计划门产出的 Task 清单中存在 **2 个及以上无依赖任务**。
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 核心模型
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
主代理(Orchestrator)
|
|
17
|
-
├── 完成 Story门 → 需求门 → 计划门
|
|
18
|
-
├── 分析任务依赖图
|
|
19
|
-
├── 分发无依赖任务组给子代理
|
|
20
|
-
├── 收集子代理结果
|
|
21
|
-
├── 统一推送(batch push)
|
|
22
|
-
└── 闭环门
|
|
23
|
-
|
|
24
|
-
子代理(Worker)
|
|
25
|
-
├── 接收:单个 Task + 上下文包
|
|
26
|
-
├── 执行:读 → 改 → 验(TDR 的 Tiny + Demo)
|
|
27
|
-
├── 产出:修改后的文件 + changelog 条目 + 验证证据
|
|
28
|
-
└── 不推送、不闭环(交回主代理)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## 依赖分析规则
|
|
34
|
-
|
|
35
|
-
计划门产出 Task 清单时,为每个任务标注 `depends` 字段:
|
|
36
|
-
|
|
37
|
-
```markdown
|
|
38
|
-
- [ ] T1. 用户列表页增加导出按钮 ⬜
|
|
39
|
-
- depends: []
|
|
40
|
-
- resource_lock: pages/admin-users.html
|
|
41
|
-
|
|
42
|
-
- [ ] T2. 用户详情页增加操作日志 ⬜
|
|
43
|
-
- depends: []
|
|
44
|
-
- resource_lock: pages/admin-user-detail.html
|
|
45
|
-
|
|
46
|
-
- [ ] T3. 导出 API 脚本编写 ⬜
|
|
47
|
-
- depends: []
|
|
48
|
-
- resource_lock: custom_scripts/user-export.py
|
|
49
|
-
|
|
50
|
-
- [ ] T4. 导出按钮对接 API ⬜
|
|
51
|
-
- depends: [T1, T3]
|
|
52
|
-
- resource_lock: pages/admin-users.html
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 依赖判定标准
|
|
56
|
-
|
|
57
|
-
| 关系 | 判定为依赖 | 判定为独立 |
|
|
58
|
-
|------|-----------|-----------|
|
|
59
|
-
| 同一文件 | T4 改 admin-users.html,T1 也改 → T4 depends T1 | - |
|
|
60
|
-
| 数据依赖 | T4 需要 T3 产出的 API slug → T4 depends T3 | - |
|
|
61
|
-
| 不同文件 | T1 改页面 A,T2 改页面 B | 无依赖,可并行 |
|
|
62
|
-
| 不同类型 | T1 改 page,T3 写 script | 无依赖,可并行 |
|
|
63
|
-
| 导航引用页面 | 导航加链接 → 目标页面必须先存在 | 页面和不相关导航 |
|
|
64
|
-
|
|
65
|
-
### resource_lock 规则
|
|
66
|
-
|
|
67
|
-
- 每个任务声明它要修改的文件路径(`resource_lock`)
|
|
68
|
-
- **同一 resource_lock 的任务不可并行**,必须串行或合并
|
|
69
|
-
- 一个任务可以锁多个资源:`resource_lock: [pages/a.html, pages/b.html]`
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 并行分发协议
|
|
74
|
-
|
|
75
|
-
### 主代理职责
|
|
76
|
-
|
|
77
|
-
1. **计划门结束后**,按依赖图将任务分为并行批次(waves):
|
|
78
|
-
```
|
|
79
|
-
Wave 1: [T1, T2, T3] — 全部 depends: [],可并行
|
|
80
|
-
Wave 2: [T4] — depends T1+T3,等 Wave 1 结束
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
2. **为每个子代理打包上下文**(Context Pack):
|
|
84
|
-
```
|
|
85
|
-
- task_id: T1
|
|
86
|
-
- task_description: <从 Task 文档摘取该任务的完整定义>
|
|
87
|
-
- resource_files: <该任务涉及的当前文件内容>
|
|
88
|
-
- story_context: <story.yaml 的关键约束摘要>
|
|
89
|
-
- dev_rules: <frontend.md / debugging-syntax.md 的关键禁区摘要>
|
|
90
|
-
- project_config: <.draftgo/config.json 的 server 地址(不含 token)>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
3. **分发时的指令模板**:
|
|
94
|
-
```
|
|
95
|
-
你是 DraftGo 子代理,负责执行单个开发任务。
|
|
96
|
-
|
|
97
|
-
## 你的任务
|
|
98
|
-
{task_description}
|
|
99
|
-
|
|
100
|
-
## 当前文件内容
|
|
101
|
-
{resource_files}
|
|
102
|
-
|
|
103
|
-
## 强制规则
|
|
104
|
-
- 只修改 resource_lock 声明的文件,禁止动其他文件
|
|
105
|
-
- 遵守 DraftGo 前端禁区(见下方摘要)
|
|
106
|
-
- 修改完成后输出:
|
|
107
|
-
1. 修改后的完整文件内容
|
|
108
|
-
2. changelog 条目(格式:- [HH:MM] [操作类型] 描述)
|
|
109
|
-
3. 验证证据(你做了什么验证、结果如何)
|
|
110
|
-
- 不要推送、不要更新 Task 文档、不要写 lessons
|
|
111
|
-
|
|
112
|
-
## 禁区摘要
|
|
113
|
-
{dev_rules_summary}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
4. **收集结果后**:
|
|
117
|
-
- 将子代理产出的文件内容写入对应路径
|
|
118
|
-
- 汇总所有 changelog 条目,按时间排序写入 changelog.md
|
|
119
|
-
- 批量推送:`python draftgo_push.py --batch pages 1,2,3 nav 4`
|
|
120
|
-
- 统一更新 Task 文档标记
|
|
121
|
-
- 进入闭环门
|
|
122
|
-
|
|
123
|
-
### 子代理职责
|
|
124
|
-
|
|
125
|
-
1. 接收上下文包,理解任务边界
|
|
126
|
-
2. 执行 TDR 循环的 Tiny + Demo:
|
|
127
|
-
- 读取当前文件
|
|
128
|
-
- 做最小改动
|
|
129
|
-
- 在能力范围内验证(语法检查、逻辑自审)
|
|
130
|
-
3. **产出三件套**:修改后文件 + changelog 条目 + 验证报告
|
|
131
|
-
4. **不做**:推送、Task 标记、lessons 记录、闭环声明
|
|
132
|
-
|
|
133
|
-
### 子代理边界红线
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
禁止:
|
|
137
|
-
- 修改 resource_lock 之外的任何文件
|
|
138
|
-
- 调用推送 API 或推送脚本
|
|
139
|
-
- 修改 .draftgo/Task/ 文档
|
|
140
|
-
- 安装新依赖或引入新库
|
|
141
|
-
- 修改 .draftgo/config.json
|
|
142
|
-
- 做出超出 task_description 范围的"顺手"改动
|
|
143
|
-
|
|
144
|
-
允许:
|
|
145
|
-
- 读取其他文件以理解上下文(只读)
|
|
146
|
-
- 在验证阶段用 console.log 调试
|
|
147
|
-
- 发现阻塞时报告给主代理(而非自行绕过)
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## 平台适配
|
|
153
|
-
|
|
154
|
-
不同 AI 平台实现并行的方式不同,主代理根据当前平台选择策略:
|
|
155
|
-
|
|
156
|
-
| 平台 | 并行实现方式 | 子代理能力 |
|
|
157
|
-
|------|-------------|-----------|
|
|
158
|
-
| Claude Code | `Agent` tool(subagent) | 完整文件读写 + Bash |
|
|
159
|
-
| Cursor | Background Agent / Composer | 文件读写 |
|
|
160
|
-
| Codex CLI | 多 sandbox 实例 | 完整隔离环境 |
|
|
161
|
-
| Windsurf | Cascade 多步 | 有限并行 |
|
|
162
|
-
| Kiro | Agent tool | 完整文件读写 |
|
|
163
|
-
| 其他 | 退化为串行 | - |
|
|
164
|
-
|
|
165
|
-
### 退化策略
|
|
166
|
-
|
|
167
|
-
当平台不支持子代理或任务数 ≤ 2 时,**静默退化为串行执行**,不需要告知用户。并行协议的 Task 依赖标注仍保留(对执行顺序有指导意义)。
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## 批量推送
|
|
172
|
-
|
|
173
|
-
并行执行完毕后,主代理使用批量推送减少网络开销:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
python {{SKILL_SCRIPTS}}/draftgo_push.py --batch pages 1,2,3 nav 4 custom_scripts 7
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
等价于依次推送 pages 1、2、3 + nav 4 + custom_scripts 7,但一次加载 config、一次建立连接。
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## 错误处理
|
|
184
|
-
|
|
185
|
-
### 子代理失败
|
|
186
|
-
|
|
187
|
-
- 子代理报告阻塞 → 主代理判断:能否由自己接手修复?
|
|
188
|
-
- 能:主代理接手该 Task,其余子代理结果不受影响
|
|
189
|
-
- 不能:暂停该 Task(⏸),其余继续
|
|
190
|
-
- 子代理产出与禁区冲突 → 主代理拒收,自行修复或重新分发
|
|
191
|
-
|
|
192
|
-
### Wave 间传递
|
|
193
|
-
|
|
194
|
-
- Wave 1 中某个 Task 失败 → Wave 2 中依赖该 Task 的任务自动暂停
|
|
195
|
-
- Wave 1 中其他 Task 成功 → Wave 2 中不依赖失败任务的照常执行
|
|
196
|
-
|
|
197
|
-
### 资源冲突检测
|
|
198
|
-
|
|
199
|
-
主代理收集子代理结果时,如果发现两个子代理意外修改了同一文件(违规):
|
|
200
|
-
1. 比对两份输出,取变更不重叠的部分合并
|
|
201
|
-
2. 如果重叠 → 丢弃后执行的那份,由主代理手动合并
|
|
202
|
-
3. 记入 lessons:子代理 resource_lock 定义不够精确
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## Task 文档并行标注格式
|
|
207
|
-
|
|
208
|
-
启用并行后,Task 文档的任务清单增加 `depends` 和 `resource_lock` 字段,进度总览增加 `wave` 列:
|
|
209
|
-
|
|
210
|
-
```markdown
|
|
211
|
-
## 任务清单
|
|
212
|
-
|
|
213
|
-
- [ ] T1. 用户列表页增加导出按钮 ⬜
|
|
214
|
-
- depends: []
|
|
215
|
-
- resource_lock: pages/admin-users.html
|
|
216
|
-
- wave: 1
|
|
217
|
-
|
|
218
|
-
- [ ] T2. 用户详情页增加操作日志 ⬜
|
|
219
|
-
- depends: []
|
|
220
|
-
- resource_lock: pages/admin-user-detail.html
|
|
221
|
-
- wave: 1
|
|
222
|
-
|
|
223
|
-
- [ ] T3. 导出 API 脚本编写 ⬜
|
|
224
|
-
- depends: []
|
|
225
|
-
- resource_lock: custom_scripts/user-export.py
|
|
226
|
-
- wave: 1
|
|
227
|
-
|
|
228
|
-
- [ ] T4. 导出按钮对接 API ⬜
|
|
229
|
-
- depends: [T1, T3]
|
|
230
|
-
- resource_lock: pages/admin-users.html
|
|
231
|
-
- wave: 2
|
|
232
|
-
|
|
233
|
-
## 进度总览
|
|
234
|
-
|
|
235
|
-
| 任务 | Wave | 状态 | 执行方式 | 完成时间 | 证据摘要 |
|
|
236
|
-
|-----|------|------|---------|---------|---------|
|
|
237
|
-
| T1 | 1 | ⬜ | 子代理 | | |
|
|
238
|
-
| T2 | 1 | ⬜ | 子代理 | | |
|
|
239
|
-
| T3 | 1 | ⬜ | 子代理 | | |
|
|
240
|
-
| T4 | 2 | ⬜ | 主代理 | | |
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
---
|
|
244
|
-
|
|
245
|
-
## 启用条件与判断
|
|
246
|
-
|
|
247
|
-
主代理在计划门结束时自动判断:
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
IF 无依赖任务数 >= 2
|
|
251
|
-
AND 平台支持子代理
|
|
252
|
-
AND 任务间无 resource_lock 冲突
|
|
253
|
-
THEN 启用并行分发
|
|
254
|
-
ELSE 串行执行(静默,不告知用户)
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
不需要用户显式启用。用户也可以在需求门显式说"串行做"来关闭并行。
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## 一句话总结
|
|
262
|
-
|
|
263
|
-
> **主代理管脑子(计划 + 闭环),子代理管手脚(单 Task 执行),resource_lock 防冲突,batch push 收全场。**
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
read_when: 操作动态 DB 之前 · 设计数据结构时 · 使用 filters 检索时
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# 动态 DB & 数据层
|
|
6
|
-
|
|
7
|
-
## DB Meta 结构
|
|
8
|
-
|
|
9
|
-
```json
|
|
10
|
-
{
|
|
11
|
-
"type": "order",
|
|
12
|
-
"label": "订单",
|
|
13
|
-
"schema": {
|
|
14
|
-
"type": "object",
|
|
15
|
-
"properties": {
|
|
16
|
-
"name": { "type": "string", "title": "姓名", "required": true, "searchable": "fuzzy" },
|
|
17
|
-
"status": { "type": "string", "title": "状态", "required": false, "searchable": "exact" },
|
|
18
|
-
"amount": { "type": "number", "title": "金额", "required": false, "searchable": "range" },
|
|
19
|
-
"tags": { "type": "array", "title": "标签", "required": false, "searchable": "contains" },
|
|
20
|
-
"note": { "type": "string", "title": "备注", "required": false, "searchable": false }
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"permission": {
|
|
24
|
-
"public": { "read": "none", "create": "none", "update": "none", "delete": "none" },
|
|
25
|
-
"login": { "read": "all", "create": "all", "update": "owner", "delete": "owner" },
|
|
26
|
-
"admin": { "read": "all", "create": "all", "update": "all", "delete": "all" }
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**searchable 模式**:`false`(不可检索)/ `"exact"`(精确)/ `"fuzzy"`(模糊)/ `"range"`(数值范围)/ `"contains"`(数组包含)
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## CRUD 操作范式
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
// 查询(分页 + 结构化检索)
|
|
39
|
-
const res = await App.get(`db/order`, {
|
|
40
|
-
page: 1, page_size: 20,
|
|
41
|
-
filters: ['name:like:张', 'status:eq:paid', 'amount:gte:100'],
|
|
42
|
-
order_by: 'amount', order: 'desc',
|
|
43
|
-
});
|
|
44
|
-
const { items, total } = res.data;
|
|
45
|
-
|
|
46
|
-
// 创建(业务字段必须放在 data 包裹里)
|
|
47
|
-
await App.post(`db/order`, { data: { name: '张三', amount: 200 }, status: 1 });
|
|
48
|
-
|
|
49
|
-
// 更新
|
|
50
|
-
await App.put(`db/order/${id}`, { data: { amount: 250 } });
|
|
51
|
-
|
|
52
|
-
// 删除
|
|
53
|
-
await App.delete(`db/order/${id}`);
|
|
54
|
-
|
|
55
|
-
// 批量更新(原子事务,任一失败全批回滚)
|
|
56
|
-
await App.patch(`db/order/batch`, [
|
|
57
|
-
{ id: 1, data: { status: 'paid' } },
|
|
58
|
-
{ id: 2, data: { status: 'paid' } },
|
|
59
|
-
]);
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## filters 操作符
|
|
65
|
-
|
|
66
|
-
| 操作符 | 含义 | 适用 searchable 模式 |
|
|
67
|
-
|---|---|---|
|
|
68
|
-
| `eq` | 精确等于 | exact / fuzzy / range |
|
|
69
|
-
| `like` | 模糊包含 | fuzzy |
|
|
70
|
-
| `gte` / `lte` / `gt` / `lt` | 数值范围 | range |
|
|
71
|
-
| `in` | 枚举命中(值逗号分隔:`status:in:paid,pending`) | exact / fuzzy |
|
|
72
|
-
| `contains` | 数组字段包含某值 | contains |
|
|
73
|
-
|
|
74
|
-
- 省略操作符(`filters: ['name:张三']`)默认 `like`
|
|
75
|
-
- 多个 filters 为 AND
|
|
76
|
-
- 字段未标 searchable 或操作符不匹配 → 后端返回 400
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## db_meta 本地文件
|
|
81
|
-
|
|
82
|
-
开发前先读 `.draftgo/db_meta/index.json` 了解可用 type 和字段:
|
|
83
|
-
|
|
84
|
-
```json
|
|
85
|
-
[
|
|
86
|
-
{
|
|
87
|
-
"id": 1,
|
|
88
|
-
"type": "order",
|
|
89
|
-
"label": "订单",
|
|
90
|
-
"schema": { ... }
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
⚠️ **GET `/api/db-meta/{type}` 用 type(如 `order`),不是 id。PUT/DELETE 才用 id。**
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## 通用筛选参数(非动态 DB)
|
|
100
|
-
|
|
101
|
-
用于 users / roles / pages / navigations / feedback 等标准资源:
|
|
102
|
-
|
|
103
|
-
| 参数 | 说明 |
|
|
104
|
-
|---|---|
|
|
105
|
-
| `page` / `page_size` | 分页(不传返回全量,超 10000 条后端拒绝) |
|
|
106
|
-
| `search` | 全文搜索(动态 DB 不用此参数) |
|
|
107
|
-
| `status` | 状态过滤 |
|
|
108
|
-
| `type` / `tag` | 类型/标签过滤 |
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
read_when: 开发数据库页面时需要 dg-* 组件 · 了解 shadcn 映射关系时
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# dg-* 完整映射表
|
|
6
|
-
|
|
7
|
-
## 核心认知
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
dg-* ≠ 自研组件库
|
|
11
|
-
dg-* = shadcn/ui 在数据库 HTML 页面里的协议化表达
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
数据库页面不进入 Vite/React 编译链,不能写 TSX;改用 `dg-*` 标签,runtime 解析并渲染对应 shadcn 语义。
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## shadcn → dg-* 完整映射
|
|
19
|
-
|
|
20
|
-
| shadcn 组件 | dg-* 标签 | 说明 |
|
|
21
|
-
|---|---|---|
|
|
22
|
-
| Button | `dg-button` | variant/size/disabled 属性对齐 |
|
|
23
|
-
| Card | `dg-card` + `dg-card-header/title/description/content/footer` | |
|
|
24
|
-
| Badge | `dg-badge` | variant: default/secondary/destructive/outline |
|
|
25
|
-
| Skeleton | `dg-skeleton` | 骨架屏 |
|
|
26
|
-
| Input | `dg-input` | type/placeholder/value/disabled |
|
|
27
|
-
| Textarea | `dg-textarea` | |
|
|
28
|
-
| Select | `dg-select` + `dg-select-item` | |
|
|
29
|
-
| Checkbox | `dg-checkbox` | |
|
|
30
|
-
| Switch | `dg-switch` | |
|
|
31
|
-
| RadioGroup | `dg-radio-group` + `dg-radio-item` | |
|
|
32
|
-
| Form | `dg-form` + `dg-form-item` + `dg-form-message` | |
|
|
33
|
-
| Table | `dg-table` | source 属性拉取数据,columns via data-dg-props |
|
|
34
|
-
| Tabs | `dg-tabs` + `dg-tabs-list/trigger/content` | default-value 属性 |
|
|
35
|
-
| Dialog | `dg-dialog` + `dg-dialog-trigger/content/header/title/footer` | |
|
|
36
|
-
| Sheet | `dg-sheet` + `dg-sheet-trigger/content/header/title` | side: right/left/top/bottom |
|
|
37
|
-
| DropdownMenu | `dg-dropdown-menu` + `dg-dropdown-menu-trigger/content/item/separator` | |
|
|
38
|
-
| Tooltip | `dg-tooltip` | content 属性 |
|
|
39
|
-
| Popover | `dg-popover` + `dg-popover-trigger/content` | |
|
|
40
|
-
| Alert | `dg-alert` + `dg-alert-title/description` | variant: default/destructive |
|
|
41
|
-
| Progress | `dg-progress` | value/max 属性 |
|
|
42
|
-
| Separator | `dg-separator` | orientation: horizontal/vertical |
|
|
43
|
-
| ScrollArea | `dg-scroll-area` | |
|
|
44
|
-
| Avatar | `dg-avatar` + `dg-avatar-image/fallback` | |
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 属性约定
|
|
49
|
-
|
|
50
|
-
`dg-*` 属性命名跟随 shadcn 语义:
|
|
51
|
-
- `variant`、`size`、`disabled`、`default-value`、`data-state`、`aria-*` 保持原意
|
|
52
|
-
- 复杂组件使用 `data-dg-props='{"key":"value"}'` 传递结构化配置
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## 禁止混淆
|
|
57
|
-
|
|
58
|
-
- ❌ `dg-*` 不是 daisyUI
|
|
59
|
-
- ❌ `dg-*` 不是 Bootstrap
|
|
60
|
-
- ❌ `dg-*` 不是 Ant Design / Element Plus
|
|
61
|
-
- ❌ `dg-*` 不是任意相似样式的泛称
|
|
62
|
-
- ✅ `dg-*` 只能是 shadcn 的 DraftGo HTML 协议形态
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## 使用示例速查
|
|
67
|
-
|
|
68
|
-
完整带代码的示例见 `{{SKILL_DIR}}/quickref/dg-components.md`
|