Merge remote-tracking branch 'origin/main'
# Conflicts: # flutter_monisuo/build/web/assets/fonts/MaterialIcons-Regular.otf # flutter_monisuo/build/web/flutter_bootstrap.js # flutter_monisuo/build/web/main.dart.js # flutter_monisuo/build/web/main.dart.js_1.part.js # flutter_monisuo/build/web/main.dart.js_100.part.js # flutter_monisuo/build/web/main.dart.js_102.part.js # flutter_monisuo/build/web/main.dart.js_103.part.js # flutter_monisuo/build/web/main.dart.js_104.part.js # flutter_monisuo/build/web/main.dart.js_105.part.js # flutter_monisuo/build/web/main.dart.js_106.part.js # flutter_monisuo/build/web/main.dart.js_107.part.js # flutter_monisuo/build/web/main.dart.js_108.part.js # flutter_monisuo/build/web/main.dart.js_109.part.js # flutter_monisuo/build/web/main.dart.js_11.part.js # flutter_monisuo/build/web/main.dart.js_110.part.js # flutter_monisuo/build/web/main.dart.js_111.part.js # flutter_monisuo/build/web/main.dart.js_112.part.js # flutter_monisuo/build/web/main.dart.js_113.part.js # flutter_monisuo/build/web/main.dart.js_13.part.js # flutter_monisuo/build/web/main.dart.js_18.part.js # flutter_monisuo/build/web/main.dart.js_19.part.js # flutter_monisuo/build/web/main.dart.js_20.part.js # flutter_monisuo/build/web/main.dart.js_24.part.js # flutter_monisuo/build/web/main.dart.js_25.part.js # flutter_monisuo/build/web/main.dart.js_29.part.js # flutter_monisuo/build/web/main.dart.js_30.part.js # flutter_monisuo/build/web/main.dart.js_33.part.js # flutter_monisuo/build/web/main.dart.js_36.part.js # flutter_monisuo/build/web/main.dart.js_37.part.js # flutter_monisuo/build/web/main.dart.js_39.part.js # flutter_monisuo/build/web/main.dart.js_41.part.js # flutter_monisuo/build/web/main.dart.js_42.part.js # flutter_monisuo/build/web/main.dart.js_43.part.js # flutter_monisuo/build/web/main.dart.js_44.part.js # flutter_monisuo/build/web/main.dart.js_46.part.js # flutter_monisuo/build/web/main.dart.js_47.part.js # flutter_monisuo/build/web/main.dart.js_48.part.js # flutter_monisuo/build/web/main.dart.js_49.part.js # flutter_monisuo/build/web/main.dart.js_5.part.js # flutter_monisuo/build/web/main.dart.js_50.part.js # flutter_monisuo/build/web/main.dart.js_51.part.js # flutter_monisuo/build/web/main.dart.js_52.part.js # flutter_monisuo/build/web/main.dart.js_54.part.js # flutter_monisuo/build/web/main.dart.js_55.part.js # flutter_monisuo/build/web/main.dart.js_56.part.js # flutter_monisuo/build/web/main.dart.js_57.part.js # flutter_monisuo/build/web/main.dart.js_59.part.js # flutter_monisuo/build/web/main.dart.js_6.part.js # flutter_monisuo/build/web/main.dart.js_60.part.js # flutter_monisuo/build/web/main.dart.js_63.part.js # flutter_monisuo/build/web/main.dart.js_65.part.js # flutter_monisuo/build/web/main.dart.js_66.part.js # flutter_monisuo/build/web/main.dart.js_69.part.js # flutter_monisuo/build/web/main.dart.js_7.part.js # flutter_monisuo/build/web/main.dart.js_70.part.js # flutter_monisuo/build/web/main.dart.js_71.part.js # flutter_monisuo/build/web/main.dart.js_72.part.js # flutter_monisuo/build/web/main.dart.js_73.part.js # flutter_monisuo/build/web/main.dart.js_74.part.js # flutter_monisuo/build/web/main.dart.js_75.part.js # flutter_monisuo/build/web/main.dart.js_76.part.js # flutter_monisuo/build/web/main.dart.js_77.part.js # flutter_monisuo/build/web/main.dart.js_78.part.js # flutter_monisuo/build/web/main.dart.js_79.part.js # flutter_monisuo/build/web/main.dart.js_80.part.js # flutter_monisuo/build/web/main.dart.js_81.part.js # flutter_monisuo/build/web/main.dart.js_82.part.js # flutter_monisuo/build/web/main.dart.js_84.part.js # flutter_monisuo/build/web/main.dart.js_85.part.js # flutter_monisuo/build/web/main.dart.js_86.part.js # flutter_monisuo/build/web/main.dart.js_87.part.js # flutter_monisuo/build/web/main.dart.js_88.part.js # flutter_monisuo/build/web/main.dart.js_89.part.js # flutter_monisuo/build/web/main.dart.js_9.part.js # flutter_monisuo/build/web/main.dart.js_90.part.js # flutter_monisuo/build/web/main.dart.js_91.part.js # flutter_monisuo/build/web/main.dart.js_92.part.js # flutter_monisuo/build/web/main.dart.js_93.part.js # flutter_monisuo/build/web/main.dart.js_94.part.js # flutter_monisuo/build/web/main.dart.js_95.part.js # flutter_monisuo/build/web/main.dart.js_96.part.js # flutter_monisuo/build/web/main.dart.js_97.part.js # flutter_monisuo/build/web/main.dart.js_98.part.js # flutter_monisuo/build/web/main.dart.js_99.part.js
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
# NovelWeave Agent Skills
|
||||
|
||||
这个目录包含您的项目 Agent Skills。
|
||||
|
||||
## 说明
|
||||
|
||||
- ✅ 您可以自由修改、删除或添加 Skills
|
||||
- ✅ Skills 文件会被 Git 跟踪,团队共享
|
||||
- ✅ 每个 Skill 是一个目录,包含 SKILL.md 文件
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
.agent/skills/
|
||||
├── genre-knowledge/ # 类型知识
|
||||
│ ├── romance/
|
||||
│ ├── mystery/
|
||||
│ └── fantasy/
|
||||
├── quality-assurance/ # 质量保证
|
||||
│ ├── consistency-checker/
|
||||
│ └── novelweave-workflow/
|
||||
└── writing-techniques/ # 写作技巧
|
||||
├── dialogue-techniques/
|
||||
└── scene-structure/
|
||||
```
|
||||
|
||||
## 如何使用
|
||||
|
||||
1. **查看 Skill**:打开任意 Skill 目录中的 SKILL.md 文件
|
||||
2. **修改 Skill**:直接编辑 SKILL.md 或添加支持文件
|
||||
3. **删除 Skill**:删除整个 Skill 目录
|
||||
4. **添加新 Skill**:创建新目录,添加 SKILL.md 文件
|
||||
|
||||
## 团队协作
|
||||
|
||||
1. 修改 Skills 后提交到 Git
|
||||
2. 团队成员 pull 后自动获得更新
|
||||
3. 冲突时手动解决(像普通代码一样)
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [Skills 编写指南](https://docs.novelweave.com/skills-guide)
|
||||
- [SKILL.md 格式规范](https://docs.novelweave.com/skill-format)
|
||||
|
||||
---
|
||||
|
||||
_初始化时间:2026-03-28T09:36:05.257Z_
|
||||
_NovelWeave 版本:0.16.0_
|
||||
@@ -1,390 +0,0 @@
|
||||
---
|
||||
name: fantasy-world-building
|
||||
description: "当用户提到奇幻、魔法系统或世界构建时使用 - 提供奇幻类型规范、魔法系统设计模式和世界构建框架"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 奇幻小说世界构建规范
|
||||
|
||||
## 快速参考
|
||||
|
||||
| 元素 | 指导原则 | 关键点 |
|
||||
| ------------- | -------------- | ------------------ |
|
||||
| **魔法系统** | 必须有清晰规则 | 限制比力量更重要 |
|
||||
| **世界设定** | 内在自洽 | 每个规则都有原因 |
|
||||
| **种族/生物** | 独特且有逻辑 | 避免单纯的人类翻版 |
|
||||
| **历史深度** | 至少三代历史 | 过去影响现在 |
|
||||
| **政治结构** | 权力分布清晰 | 冲突有根源 |
|
||||
|
||||
## 核心原则
|
||||
|
||||
### Sanderson 魔法法则
|
||||
|
||||
**第一法则**:读者从魔法中获得的满足感,与其理解魔法的程度成正比
|
||||
|
||||
- 如果魔法要解决问题,读者必须理解它的规则
|
||||
- 软魔法系统(神秘)用于氛围和奇观
|
||||
- 硬魔法系统(规则明确)用于解决问题
|
||||
|
||||
**第二法则**:限制比力量更有趣
|
||||
|
||||
- 强大的魔法需要强大的代价
|
||||
- 限制创造冲突和策略
|
||||
- 完美的系统无法创造戏剧
|
||||
|
||||
**第三法则**:在添加新东西之前,先扩展已有的
|
||||
|
||||
- 深化现有元素胜过添加新元素
|
||||
- 相互关联的系统比孤立的更强
|
||||
- 复杂度应该有机生长
|
||||
|
||||
## 魔法系统设计
|
||||
|
||||
### 硬魔法系统(规则明确)
|
||||
|
||||
**必要元素**:
|
||||
|
||||
1. **能量来源**
|
||||
- 魔法从哪里来?
|
||||
- 是有限的还是无限的?
|
||||
- 可以耗尽吗?
|
||||
|
||||
2. **使用规则**
|
||||
- 谁能使用?如何获得?
|
||||
- 需要什么条件?
|
||||
- 有什么限制?
|
||||
|
||||
3. **代价/后果**
|
||||
- 使用魔法的成本是什么?
|
||||
- 过度使用会怎样?
|
||||
- 是否有长期影响?
|
||||
|
||||
4. **可能与不可能**
|
||||
- 魔法能做什么?
|
||||
- 明确不能做什么
|
||||
- 边界在哪里?
|
||||
|
||||
**示例框架**:
|
||||
|
||||
```
|
||||
魔法系统:元素操控
|
||||
来源:每个人出生时拥有一种元素亲和
|
||||
规则:只能操控自己的元素,需要该元素存在于周围
|
||||
限制:精神疲劳,过度使用导致元素反噬
|
||||
代价:使用魔法时消耗生命力,需要休息恢复
|
||||
禁忌:不能创造元素,只能操控;不能操控生物体内的元素
|
||||
```
|
||||
|
||||
### 软魔法系统(神秘感)
|
||||
|
||||
**特征**:
|
||||
|
||||
- 规则不完全为读者所知
|
||||
- 更多用于氛围和奇观
|
||||
- 不应该方便地解决主要冲突
|
||||
- 保持神秘感和敬畏
|
||||
|
||||
**使用场景**:
|
||||
|
||||
- 古老的魔法,已部分遗失
|
||||
- 神祇力量,超越凡人理解
|
||||
- 背景奇观和世界建设
|
||||
- 不影响主线解决的辅助情节
|
||||
|
||||
## 世界构建框架
|
||||
|
||||
### 地理与环境
|
||||
|
||||
**必须考虑**:
|
||||
|
||||
1. **地形**
|
||||
- 山脉、河流、海洋如何影响文明?
|
||||
- 气候如何塑造文化?
|
||||
- 资源分布如何影响经济?
|
||||
|
||||
2. **生态系统**
|
||||
- 食物链是什么样的?
|
||||
- 魔法生物如何适应环境?
|
||||
- 人类/其他智慧种族如何生存?
|
||||
|
||||
3. **魔法对地理的影响**
|
||||
- 魔法如何改变自然?
|
||||
- 有魔法造成的地标吗?
|
||||
- 魔法灾难留下了什么痕迹?
|
||||
|
||||
### 社会与文化
|
||||
|
||||
**层次架构**:
|
||||
|
||||
**政治层面**:
|
||||
|
||||
- 政府形式(君主制、民主、神权等)
|
||||
- 权力如何传递?
|
||||
- 魔法如何影响政治?
|
||||
- 不同派系的冲突
|
||||
|
||||
**经济层面**:
|
||||
|
||||
- 贸易什么?为什么?
|
||||
- 货币系统
|
||||
- 魔法如何影响经济?
|
||||
- 资源稀缺性
|
||||
|
||||
**社会层面**:
|
||||
|
||||
- 阶级结构
|
||||
- 种族关系
|
||||
- 魔法使用者的地位
|
||||
- 教育和知识传播
|
||||
|
||||
**文化层面**:
|
||||
|
||||
- 宗教和信仰
|
||||
- 艺术和娱乐
|
||||
- 节日和传统
|
||||
- 价值观和禁忌
|
||||
|
||||
### 历史深度
|
||||
|
||||
**最少三代历史**:
|
||||
|
||||
**当代**(故事发生时):
|
||||
|
||||
- 现状是什么?
|
||||
- 主要冲突和问题
|
||||
- 主要势力和人物
|
||||
|
||||
**父辈代**(30-50年前):
|
||||
|
||||
- 什么事件塑造了当代?
|
||||
- 老一辈记得什么?
|
||||
- 遗留的问题
|
||||
|
||||
**祖辈代**(60-100年前):
|
||||
|
||||
- 传说和故事
|
||||
- 失落的知识
|
||||
- 历史创伤
|
||||
|
||||
**古代**(更久远):
|
||||
|
||||
- 神话和传说
|
||||
- 文明的兴衰
|
||||
- 为当代设定埋下种子
|
||||
|
||||
## 种族与生物设计
|
||||
|
||||
### 智慧种族
|
||||
|
||||
**避免单一特征**:
|
||||
❌ 所有精灵都优雅高贵
|
||||
❌ 所有矮人都贪婪暴躁
|
||||
❌ 所有兽人都野蛮好战
|
||||
|
||||
**创造深度**:
|
||||
✅ 内部多样性(不同文化、价值观)
|
||||
✅ 个体差异(性格各异)
|
||||
✅ 历史复杂性(好的和坏的历史)
|
||||
|
||||
**种族特征应该有原因**:
|
||||
|
||||
- 生理特征如何帮助生存?
|
||||
- 文化特征从何而来?
|
||||
- 与其他种族的关系历史
|
||||
|
||||
### 魔法生物
|
||||
|
||||
**设计原则**:
|
||||
|
||||
1. **生态位**
|
||||
- 它在生态系统中的角色?
|
||||
- 吃什么?被什么吃?
|
||||
- 如何繁殖?
|
||||
|
||||
2. **魔法来源**
|
||||
- 为什么有魔法?
|
||||
- 魔法如何帮助它生存?
|
||||
- 有什么代价或限制?
|
||||
|
||||
3. **与人类的关系**
|
||||
- 危险还是有用?
|
||||
- 能驯养吗?
|
||||
- 人类如何应对?
|
||||
|
||||
## 常见陷阱
|
||||
|
||||
### ❌ 过度解释
|
||||
|
||||
**问题**:花费章节解释世界设定,停止故事推进
|
||||
|
||||
**解决**:
|
||||
|
||||
- 在行动中展示设定
|
||||
- 只解释角色需要知道的
|
||||
- 让读者自己拼凑一些东西
|
||||
- 信息应该服务于情节或角色
|
||||
|
||||
### ❌ 不一致的规则
|
||||
|
||||
**问题**:魔法/世界规则为了情节便利而改变
|
||||
|
||||
**解决**:
|
||||
|
||||
- 提前建立所有主要规则
|
||||
- 跟踪已建立的规则
|
||||
- 例外需要早期暗示
|
||||
- 让角色在限制内创造性地解决问题
|
||||
|
||||
### ❌ 欧洲中世纪默认设置
|
||||
|
||||
**问题**:所有奇幻都是欧洲中世纪的翻版
|
||||
|
||||
**解决**:
|
||||
|
||||
- 探索其他文化和时期
|
||||
- 混合多个文化元素
|
||||
- 创造独特的社会结构
|
||||
- 考虑魔法如何改变社会发展
|
||||
|
||||
### ❌ 选中之人陷阱
|
||||
|
||||
**问题**:主角因为预言/血统特殊,而非行动
|
||||
|
||||
**解决**:
|
||||
|
||||
- 让主角通过选择变得特殊
|
||||
- 即使有预言,也让他们努力实现
|
||||
- 颠覆或解构陷阱
|
||||
- 专注于角色成长,而非天赋
|
||||
|
||||
## 奇幻子类型
|
||||
|
||||
### 高奇幻(史诗奇幻)
|
||||
|
||||
- 完全虚构的世界
|
||||
- 善恶对抗
|
||||
- 史诗般的规模和风险
|
||||
- 魔法是世界的一部分
|
||||
|
||||
### 低奇幻
|
||||
|
||||
- 现实世界+魔法元素
|
||||
- 较小的个人风险
|
||||
- 魔法稀有且神秘
|
||||
- 更接地气的基调
|
||||
|
||||
### 城市奇幻
|
||||
|
||||
- 现代城市设定
|
||||
- 隐藏的魔法世界
|
||||
- 通常有侦探/神秘元素
|
||||
- 两个世界的碰撞
|
||||
|
||||
### 黑暗奇幻
|
||||
|
||||
- 道德灰色
|
||||
- 恐怖和暴力元素
|
||||
- 反英雄主角
|
||||
- 更严酷的后果
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
### 当 `/specify` 执行时
|
||||
|
||||
- 定义核心世界元素(魔法、种族、地理)
|
||||
- 识别奇幻子类型
|
||||
- 列出必须建立的主要规则
|
||||
- 计划信息揭示的节奏
|
||||
|
||||
### 在 `/plan` 期间
|
||||
|
||||
- 绘制世界元素如何影响情节
|
||||
- 计划魔法系统的展示
|
||||
- 设计不同文化的碰撞
|
||||
- 确保世界规则的一致性
|
||||
|
||||
### 在 `/write` 时
|
||||
|
||||
- 在行动中展示世界,而非倾倒
|
||||
- 让角色对世界元素做出反应
|
||||
- 使用感官细节使世界生动
|
||||
- 保持已建立规则的一致性
|
||||
|
||||
### 在 `/analyze` 期间
|
||||
|
||||
- 检查世界规则的一致性
|
||||
- 验证魔法系统的逻辑
|
||||
- 确认所有世界元素都有目的
|
||||
- 确保设定服务于故事
|
||||
|
||||
## 世界构建检查清单
|
||||
|
||||
- [ ] 魔法系统有清晰的规则和限制
|
||||
- [ ] 地理和气候影响文化和情节
|
||||
- [ ] 至少三代历史深度
|
||||
- [ ] 多个政治势力有清晰动机
|
||||
- [ ] 经济和贸易有逻辑基础
|
||||
- [ ] 种族/文化有内部多样性
|
||||
- [ ] 魔法生物有生态位和目的
|
||||
- [ ] 宗教/信仰系统有影响
|
||||
- [ ] 社会结构有明确阶级和流动性
|
||||
- [ ] 所有规则在整个故事中保持一致
|
||||
|
||||
## 信息揭示策略
|
||||
|
||||
### 冰山原则
|
||||
|
||||
**创造的 vs 展示的**:
|
||||
|
||||
- 创造 100%,但只展示 10-20%
|
||||
- 读者不需要知道所有东西
|
||||
- 深度创造自信和一致性
|
||||
- 作者知道的比展示的多
|
||||
|
||||
### 展示时机
|
||||
|
||||
**第一章**:
|
||||
|
||||
- 基本世界观(不是详尽说明)
|
||||
- 一个引人注目的魔法/奇幻元素
|
||||
- 主角在世界中的位置
|
||||
|
||||
**前 25%**:
|
||||
|
||||
- 核心魔法系统规则
|
||||
- 主要种族/文化
|
||||
- 中心冲突及其世界根源
|
||||
|
||||
**中段**:
|
||||
|
||||
- 深化已建立元素
|
||||
- 复杂化世界政治
|
||||
- 揭示历史影响
|
||||
|
||||
**后段**:
|
||||
|
||||
- 连接所有世界线索
|
||||
- 揭示深层历史
|
||||
- 展示世界元素如何解决冲突
|
||||
|
||||
## 读者期望
|
||||
|
||||
**奇幻读者想要什么**:
|
||||
|
||||
- 沉浸式、可信的世界
|
||||
- 一致且有趣的魔法系统
|
||||
- 复杂的文化和政治
|
||||
- 对经典陷阱的新鲜视角
|
||||
- 世界感觉比故事更大
|
||||
|
||||
**让奇幻读者沮丧的是什么**:
|
||||
|
||||
- 不一致的世界规则
|
||||
- 方便情节的魔法
|
||||
- 单薄的欧洲中世纪抄袭
|
||||
- 缺乏深度的世界
|
||||
- 信息倾倒而非有机揭示
|
||||
|
||||
---
|
||||
|
||||
**记住**:伟大的世界构建是故事的基础,而非目的。世界应该服务于角色和情节,而角色的行动应该受到世界规则的塑造和限制。平衡深度与叙事流畅性是关键。
|
||||
@@ -1,374 +0,0 @@
|
||||
---
|
||||
name: mystery-novel-conventions
|
||||
description: "当用户提到悬疑、侦探、犯罪或悬念叙事时使用 - 提供类型规范、线索布置和推理小说的公平游戏原则"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 悬疑推理小说创作规范
|
||||
|
||||
## 快速参考
|
||||
|
||||
| 元素 | 指导原则 | 位置 |
|
||||
| ------------ | -------------- | ---------------- |
|
||||
| **触发事件** | 案件/谜团发生 | 前 10% |
|
||||
| **误导线索** | 错误的引导 | 贯穿全文,3-5 个 |
|
||||
| **真实线索** | 公平游戏的证据 | 75% 之前 |
|
||||
| **真相揭露** | 真相揭示 | 85-95% |
|
||||
| **收尾** | 结束所有线索 | 最后 5% |
|
||||
|
||||
## 核心原则
|
||||
|
||||
### 公平游戏原则
|
||||
|
||||
**黄金法则**:读者必须在侦探之前获得所有解决谜团所需的线索。
|
||||
|
||||
1. **没有隐藏信息**
|
||||
- 所有关键线索都必须呈现给读者
|
||||
- 侦探不能基于读者不知道的信息破案
|
||||
- 只在结尾揭示的秘密证据违反公平游戏
|
||||
|
||||
2. **逻辑推理**
|
||||
- 解决方案必须能从呈现的事实中逻辑推导
|
||||
- 巧合可以使情况复杂化,但永远不能解决
|
||||
- 直觉可以,但必须基于已展示的证据
|
||||
|
||||
3. **不使用机械降神**
|
||||
- 不能突然出现新角色作为罪犯
|
||||
- 不能有之前未提及的能力或工具
|
||||
- 不能有神的干预或纯粹的运气
|
||||
|
||||
## 悬疑小说结构
|
||||
|
||||
### 第一幕:铺垫(0-25%)
|
||||
|
||||
**建立常态世界**:
|
||||
|
||||
- 介绍主角和他们的世界
|
||||
- 展示角色能力
|
||||
- 埋下性格怪癖的种子
|
||||
|
||||
**案件发生**:
|
||||
|
||||
- 在前 10% 发生
|
||||
- 必须足够有趣/不寻常以证明调查的必要性
|
||||
- 风险应该清晰
|
||||
|
||||
**初步调查**:
|
||||
|
||||
- 主角接受案件
|
||||
- 首次访谈和证据收集
|
||||
- 建立关键嫌疑人
|
||||
|
||||
### 第二幕:调查(25-75%)
|
||||
|
||||
**收集线索**:
|
||||
|
||||
- 呈现所有公平游戏的证据
|
||||
- 混合真实线索与误导线索
|
||||
- 每条线索都应该感觉重要
|
||||
|
||||
**误导线索**:
|
||||
|
||||
- 3-5 条看似有希望的虚假线索
|
||||
- 必须足够可信以误导
|
||||
- 最终通过逻辑调查证伪
|
||||
|
||||
**复杂化升级**:
|
||||
|
||||
- 新证据与旧理论矛盾
|
||||
- 嫌疑人有不在场证明或秘密
|
||||
- 风险升级(更多案件、主角面临危险)
|
||||
|
||||
**中点转折**(约 50%):
|
||||
|
||||
- 重新框架谜团的重大揭示
|
||||
- 主角的理论被证明错误
|
||||
- 新角度出现
|
||||
|
||||
### 第三幕:解决(75-100%)
|
||||
|
||||
**黑暗之夜**(75-85%):
|
||||
|
||||
- 主角似乎被难住
|
||||
- 所有理论都失败了
|
||||
- 绝望或怀疑的时刻
|
||||
|
||||
**真相揭露**(85-95%):
|
||||
|
||||
- 关键洞察连接所有点
|
||||
- 主角重构真相
|
||||
- 与罪犯对峙
|
||||
|
||||
**收尾**(95-100%):
|
||||
|
||||
- 解释如何/为什么
|
||||
- 所有松散的线索被收紧
|
||||
- 正义得到伸张(或有意颠覆)
|
||||
|
||||
## 线索布置策略
|
||||
|
||||
### 线索类型
|
||||
|
||||
**物理证据**:
|
||||
|
||||
- 物品、指纹、DNA
|
||||
- 必须在需要之前埋下
|
||||
- 重要性最初可能不清楚
|
||||
|
||||
**证言证据**:
|
||||
|
||||
- 证人陈述
|
||||
- 不在场证明及其矛盾
|
||||
- 谎言(有意或无意)
|
||||
|
||||
**行为证据**:
|
||||
|
||||
- 角色对事件的反应
|
||||
- 不寻常的行为模式
|
||||
- 通过行动揭示的动机
|
||||
|
||||
**circumstantial证据**:
|
||||
|
||||
- 机会、手段、动机
|
||||
- 模式和联系
|
||||
- 时间线不一致
|
||||
|
||||
### 线索布置时机
|
||||
|
||||
**早期线索**(0-25%):
|
||||
|
||||
- 建立基准事实
|
||||
- 埋下看似无辜的种子
|
||||
- 介绍所有关键嫌疑人
|
||||
|
||||
**中期线索**(25-75%):
|
||||
|
||||
- 混合真实线索与误导线索
|
||||
- 使情况复杂化
|
||||
- 揭示角色动机
|
||||
|
||||
**后期线索**(75-85%):
|
||||
|
||||
- 使其可解的最后一块拼图
|
||||
- 可以是一直存在的东西
|
||||
- 主角的顿悟时刻
|
||||
|
||||
## 误导线索最佳实践
|
||||
|
||||
### 有效的误导线索
|
||||
|
||||
**特征**:
|
||||
|
||||
- 足够可信以显得真实
|
||||
- 有一些证据支持
|
||||
- 最终通过逻辑被证伪
|
||||
- 揭示为虚假时不显得廉价
|
||||
|
||||
**示例**:
|
||||
|
||||
- 有强烈动机但坚实不在场证明的嫌疑人
|
||||
- 被栽赃的有罪证据
|
||||
- 巧合出现在犯罪现场
|
||||
- 看起来有罪但实际无辜的秘密活动
|
||||
|
||||
### 常见错误
|
||||
|
||||
❌ **太明显**:读者立即看穿
|
||||
❌ **太勉强**:感觉强迫和人为
|
||||
❌ **从不解释**:悬而未决没有解决
|
||||
❌ **太多**:读者失去追踪并感到沮丧
|
||||
|
||||
## 嫌疑人管理
|
||||
|
||||
### 经典设置
|
||||
|
||||
**至少 3 个嫌疑人**:
|
||||
|
||||
- 每个都需要动机、手段和机会
|
||||
- 每个在某个时刻都应该显得有罪
|
||||
- 至少一个应该是同情的
|
||||
|
||||
**罪犯**:
|
||||
|
||||
- 应该在介绍的角色中(公平游戏)
|
||||
- 必须有最终揭示的逻辑动机
|
||||
- 他们有罪的线索必须从早期就存在
|
||||
|
||||
**误导嫌疑人**:
|
||||
|
||||
- 最明显的选择
|
||||
- 强烈的动机和间接证据
|
||||
- 最终通过调查被排除
|
||||
|
||||
**同情嫌疑人**:
|
||||
|
||||
- 读者希望不是有罪的
|
||||
- 有值得保护的秘密
|
||||
- 通常帮助解决真正的谜团
|
||||
|
||||
### 角色秘密
|
||||
|
||||
**每个嫌疑人都应该有秘密**:
|
||||
|
||||
- 不是所有秘密都与案件相关
|
||||
- 秘密创造误导
|
||||
- 揭示秘密推进调查
|
||||
- 有些秘密比案件更具破坏性
|
||||
|
||||
## 常见陷阱
|
||||
|
||||
### ❌ 不可知的解决方案
|
||||
|
||||
**问题**:罪犯或方法依赖读者没有的信息
|
||||
|
||||
**解决**:在 75% 标记之前埋下所有必要线索;读者应该能够解决
|
||||
|
||||
### ❌ 无能的侦探
|
||||
|
||||
**问题**:主角错过明显线索或行为不合逻辑
|
||||
|
||||
**解决**:让侦探有能力但人性化;他们可以犯错,但不是愚蠢
|
||||
|
||||
### ❌ 太多巧合
|
||||
|
||||
**问题**:情节通过方便的运气而非调查推进
|
||||
|
||||
**解决**:巧合可以使情况复杂化,永远不能解决;侦探必须努力寻找答案
|
||||
|
||||
### ❌ 无聊的中段
|
||||
|
||||
**问题**:调查变成重复的访谈接访谈
|
||||
|
||||
**解决**:变化调查方法;添加动作、危险、个人风险
|
||||
|
||||
### ❌ 仓促的解释
|
||||
|
||||
**问题**:复杂的解决方案在最后一章的对话中倾倒
|
||||
|
||||
**解决**:分散揭示;让读者拼凑;保持解释清晰但不冗长
|
||||
|
||||
## 子类型变化
|
||||
|
||||
### 温馨推理
|
||||
|
||||
- 业余侦探
|
||||
- 有限的暴力描写
|
||||
- 小社区背景
|
||||
- 角色驱动
|
||||
- 通常幽默的基调
|
||||
|
||||
### 硬派侦探
|
||||
|
||||
- 专业调查员
|
||||
- 粗糙、现实的暴力
|
||||
- 道德复杂的世界
|
||||
- 愤世嫉俗的基调
|
||||
- 动作导向
|
||||
|
||||
### 警察程序
|
||||
|
||||
- 专注于调查过程
|
||||
- 多个侦探/团队
|
||||
- 现实的程序
|
||||
- 技术细节重要
|
||||
- 官僚主义作为障碍
|
||||
|
||||
### 密室推理
|
||||
|
||||
- 不可能的犯罪场景
|
||||
- 有限的嫌疑人(谁有机会)
|
||||
- 巧妙的方法是关键
|
||||
- 解决方案必须合乎逻辑
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
### 当 `/specify` 执行时
|
||||
|
||||
- 清晰定义中心谜团
|
||||
- 列出所有主要嫌疑人及其动机
|
||||
- 识别关键线索及其出现位置
|
||||
- 决定公平游戏规则
|
||||
|
||||
### 在 `/plan` 期间
|
||||
|
||||
- 绘制线索布置时间线
|
||||
- 设计误导线索模式
|
||||
- 计划调查序列
|
||||
- 结构揭示和反转
|
||||
|
||||
### 在 `/write` 时
|
||||
|
||||
- 确保线索可见但不明显
|
||||
- 平衡调查与角色发展
|
||||
- 保持节奏(动作、揭示、复杂化)
|
||||
- 跟踪读者知道什么vs侦探知道什么
|
||||
|
||||
### 在 `/analyze` 期间
|
||||
|
||||
- 验证公平游戏 - 读者能解决吗?
|
||||
- 检查所有线索是否已埋下
|
||||
- 确保没有机械降神
|
||||
- 确认令人满意的解决
|
||||
|
||||
## 悬疑写作检查清单
|
||||
|
||||
- [ ] 中心谜团引人入胜且清晰
|
||||
- [ ] 3-5 个有动机的可行嫌疑人
|
||||
- [ ] 揭示前呈现所有关键线索
|
||||
- [ ] 误导线索可信且最终得到解释
|
||||
- [ ] 侦探有能力且合乎逻辑
|
||||
- [ ] 解决方案可从给定信息推导
|
||||
- [ ] 没有巧合解决谜团
|
||||
- [ ] 时间线一致且可追踪
|
||||
- [ ] 所有松散的线索都被收紧
|
||||
- [ ] 揭示令人满意,而非令人失望
|
||||
|
||||
## 线索可见性框架
|
||||
|
||||
### 三个层次
|
||||
|
||||
**层次 1 - 明显**(25% 的线索):
|
||||
|
||||
- 引入时明确重要
|
||||
- 主角和读者一起注意到
|
||||
- 建立基准事实
|
||||
|
||||
**层次 2 - 微妙**(50% 的线索):
|
||||
|
||||
- 提及但不强调
|
||||
- 重要性后来变得清晰
|
||||
- 奖励细心的读者
|
||||
|
||||
**层次 3 - 藏在显眼处**(25% 的线索):
|
||||
|
||||
- 引入时看似无关紧要
|
||||
- 只有在回顾时才有意义
|
||||
- "啊哈!"时刻
|
||||
|
||||
### 示例
|
||||
|
||||
**层次 1**:"窗户从里面解锁"
|
||||
**层次 2**:角色在闲聊中提到自己是左撇子
|
||||
**层次 3**:房间描述包括烟灰缸中的特定品牌香烟
|
||||
|
||||
## 读者期望
|
||||
|
||||
**悬疑读者想要什么**:
|
||||
|
||||
- 与侦探一起解决的公平机会
|
||||
- 事后有意义的聪明转折
|
||||
- 有能力但会犯错的主角
|
||||
- 令人满意的"啊哈!"时刻
|
||||
- 正义(或有目的的有意颠覆)
|
||||
|
||||
**让悬疑读者沮丧的是什么**:
|
||||
|
||||
- 只在结尾揭示的隐藏信息
|
||||
- 通过未展示的推理解决的主角
|
||||
- 勉强的巧合
|
||||
- 没有误导的明显罪犯
|
||||
- 松散的线索悬而未决
|
||||
|
||||
---
|
||||
|
||||
**记住**:一个伟大的谜团让读者因解决它而感到聪明,或因没有看到它而印象深刻 - 但总是满意线索一直都在那里。
|
||||
@@ -1,244 +0,0 @@
|
||||
---
|
||||
name: romance-novel-conventions
|
||||
description: "当用户提到言情、爱情故事或关系导向叙事时使用 - 提供类型规范、节奏指南和言情小说的情感节点"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 言情小说创作规范
|
||||
|
||||
## 快速参考
|
||||
|
||||
| 元素 | 指导原则 | 示例 |
|
||||
| ------------ | ------------------------------- | ------------------------ |
|
||||
| **初遇** | 故事的 0-10% | 意外的首次相遇,产生火花 |
|
||||
| **初吻** | 50-60%(慢热)或 20-30%(快热) | 需要充分的情感铺垫 |
|
||||
| **黑暗时刻** | 75-85% | 关系看似不可能继续 |
|
||||
| **大结局** | 85-100% | 表白、承诺、HEA/HFN |
|
||||
|
||||
## 核心要素
|
||||
|
||||
### 必备组成部分
|
||||
|
||||
1. **情感连接**:主角之间必须有化学反应
|
||||
- 通过行动而非单纯描述来展现吸引力
|
||||
- 通过亲近和距离建立张力
|
||||
- 创造可信的相互吸引的理由
|
||||
|
||||
2. **内在冲突**:恐惧、过往创伤、自我怀疑
|
||||
- 每个角色都应该有情感包袱
|
||||
- 内在冲突必须与外在障碍同样强烈
|
||||
- 成长来自面对这些内在问题
|
||||
|
||||
3. **外在障碍**:家庭、事业、误会
|
||||
- 障碍应该是合理的,而非人为的
|
||||
- "只要好好沟通"不应该能解决所有问题
|
||||
- 风险应该逐步升级
|
||||
|
||||
4. **令人满意的结局**:HEA(永远幸福)或 HFN(暂时幸福)
|
||||
- 两个角色都必须成长才配得上结局
|
||||
- 结局应该解决内在和外在冲突
|
||||
- 读者应该感到满足,而非被欺骗
|
||||
|
||||
### 可选元素
|
||||
|
||||
- 三角恋(谨慎使用 - 可能让读者沮丧)
|
||||
- 被迫亲密设定(被困在一起的场景)
|
||||
- 欢喜冤家(需要精心处理)
|
||||
- 第二次机会言情(重燃旧情)
|
||||
|
||||
## 节奏指南
|
||||
|
||||
| 故事阶段 | 百分比 | 关键事件 | 情感焦点 |
|
||||
| ------------ | ------- | ------------------------ | ---------- |
|
||||
| **初遇** | 0-10% | 初次相遇,产生兴趣的火花 | 好奇、吸引 |
|
||||
| **张力建立** | 10-60% | 吸引力增长,障碍出现 | 渴望、挫折 |
|
||||
| **冲突升级** | 60-75% | 重大误会或真相揭露 | 怀疑、痛苦 |
|
||||
| **黑暗时刻** | 75-85% | 关系看似不可能 | 绝望、失落 |
|
||||
| **大结局** | 85-100% | 盛大表白、承诺 | 喜悦、圆满 |
|
||||
|
||||
## 情感节奏点
|
||||
|
||||
### 初吻时机
|
||||
|
||||
**慢热言情**(约 50-60%):
|
||||
|
||||
- 初吻前有多次差点亲上的时刻
|
||||
- 大量的情感铺垫
|
||||
- 亲吻发生在建立重要信任之后
|
||||
- 读者的期待值很高
|
||||
|
||||
**快热言情**(约 20-30%):
|
||||
|
||||
- 立即的化学反应导致快速的身体接触
|
||||
- 之后重点转移到情感亲密
|
||||
- 仍必须展现合理的吸引力建立
|
||||
- 避免"一见钟情" - 展示他们为何吸引
|
||||
|
||||
**黄金法则**:在没有足够铺垫的情况下,绝不要仓促。没有情感基础的身体亲密会显得空洞。
|
||||
|
||||
### 亲密关系进展
|
||||
|
||||
1. **情感亲密先于身体亲密**
|
||||
- 分享脆弱性
|
||||
- 揭露过去的伤痛
|
||||
- 信任必须赢得
|
||||
|
||||
2. **逐步展现脆弱**
|
||||
- 从小的袒露开始
|
||||
- 建立到更深层的情感分享
|
||||
- 身体亲密跟随情感信任
|
||||
|
||||
3. **尊重角色界限**
|
||||
- 角色可以说不
|
||||
- 同意是必不可少的
|
||||
- 尊重符合角色性格的节奏
|
||||
|
||||
## 常见陷阱
|
||||
|
||||
### ❌ 一见钟情
|
||||
|
||||
**问题**:角色在没有发展的情况下爱得太快
|
||||
|
||||
**为什么不好**:读者不相信这种连接;感觉勉强和不真实
|
||||
|
||||
**解决方法**:
|
||||
|
||||
- 在表白之前展示 3-5 次有意义的互动
|
||||
- 通过行动而非想法建立吸引力
|
||||
- 给出他们相互吸引的具体原因
|
||||
- 允许时间让信任发展
|
||||
|
||||
### ❌ 误会是唯一冲突
|
||||
|
||||
**问题**:"只要好好谈谈,一切都会好起来"
|
||||
|
||||
**为什么不好**:让读者沮丧;感觉像人为的戏剧
|
||||
|
||||
**解决方法**:
|
||||
|
||||
- 添加合理的外部障碍(工作、家庭、地点)
|
||||
- 创造必须发生的内在成长(恐惧、创伤、身份认同)
|
||||
- 让沟通因真实原因而困难(权力失衡、过去的背叛)
|
||||
- 确保冲突需要角色成长才能解决
|
||||
|
||||
### ❌ 被动的主角
|
||||
|
||||
**问题**:等待被拯救或被选择;没有主动权
|
||||
|
||||
**为什么不好**:削弱角色,让言情感觉不平等
|
||||
|
||||
**解决方法**:
|
||||
|
||||
- 给他们关系之外的目标
|
||||
- 展示他们主动追求
|
||||
- 让他们为爱情积极做出牺牲
|
||||
- 确保两个角色在关系中拥有平等的主动权
|
||||
|
||||
### ❌ 陈词滥调没有创新
|
||||
|
||||
**问题**:读者已经看过一千次的可预测情节
|
||||
|
||||
**为什么不好**:无聊;读者能预测每一个转折
|
||||
|
||||
**解决方法**:
|
||||
|
||||
- 添加独特的角色背景或情境
|
||||
- 在熟悉的框架内扭转期望
|
||||
- 以意想不到的方式结合套路
|
||||
- 让角色性格驱动情节,而非反过来
|
||||
|
||||
## 子类型考虑
|
||||
|
||||
### 现代言情
|
||||
|
||||
- 现代关系动态
|
||||
- 现实的障碍(事业、距离、时机)
|
||||
- 短信/科技发挥作用
|
||||
- 关注兼容性和沟通
|
||||
|
||||
### 古代言情
|
||||
|
||||
- 符合时代的限制(阶级、礼仪)
|
||||
- 社会规则创造自然障碍
|
||||
- 需要研究以确保真实性
|
||||
- 平衡历史准确性与现代敏感性
|
||||
|
||||
### 超自然言情
|
||||
|
||||
- 超自然元素增加风险
|
||||
- 不朽创造时间线问题
|
||||
- 必须解决权力动态
|
||||
- 危险可以迫使亲密
|
||||
|
||||
### 悬疑言情
|
||||
|
||||
- 外部危险将他们联系在一起
|
||||
- 秘密使信任复杂化
|
||||
- 悬疑情节必须同样强大
|
||||
- 结局需要解决两个谜团
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
### 当用户执行 `/specify` 时
|
||||
|
||||
- 提醒在故事结构中包含关系弧
|
||||
- 建议定义:初遇、主要障碍、黑暗时刻、大结局
|
||||
- 识别言情子类型以适应相应惯例
|
||||
|
||||
### 在 `/plan` 期间
|
||||
|
||||
- 将情感节奏映射到章节结构
|
||||
- 计划被迫亲密或分离的时刻
|
||||
- 设计内外冲突升级
|
||||
- 确保身体/情感亲密的适当节奏
|
||||
|
||||
### 在 `/write` 时
|
||||
|
||||
- 为浪漫张力应用对话技巧
|
||||
- 通过行动而非想法展现化学反应
|
||||
- 通过潜台词建立性张力
|
||||
- 确保两个角色都有主动权
|
||||
|
||||
### 当 `/analyze` 运行时
|
||||
|
||||
- 根据言情惯例检查节奏
|
||||
- 验证两个角色都有完整的弧线
|
||||
- 确保障碍感觉合理,而非人为
|
||||
- 确认令人满意的 HEA/HFN 结局
|
||||
|
||||
## 实用检查清单
|
||||
|
||||
写言情时,确保你有:
|
||||
|
||||
- [ ] 早期建立强烈的化学反应(10% 前)
|
||||
- [ ] 两位主角都有清晰的内在冲突
|
||||
- [ ] 不能通过一次对话解决的外部障碍
|
||||
- [ ] 整个故事中跟踪的情感亲密发展
|
||||
- [ ] 适合子类型的身体亲密节奏
|
||||
- [ ] 感觉毁灭性且真实的黑暗时刻
|
||||
- [ ] 解决两个角色成长的结局
|
||||
- [ ] 满足读者期望的 HEA 或 HFN
|
||||
|
||||
## 常见读者期望
|
||||
|
||||
**言情读者想要什么**:
|
||||
|
||||
- 情感满足胜过惊喜
|
||||
- 两个角色都赢得他们的幸福
|
||||
- 通过成长克服可信的障碍
|
||||
- 页面上闪耀的化学反应
|
||||
- 他们想要给自己的关系
|
||||
- 所有关系线索的结尾
|
||||
|
||||
**让言情读者沮丧的是什么**:
|
||||
|
||||
- 可以轻易解决的人为冲突
|
||||
- 一个角色做所有情感工作
|
||||
- 没有适当解决的仓促结局
|
||||
- 未解决的不平等权力动态
|
||||
- 没有后果的出轨或背叛
|
||||
- 为了情节便利而牺牲角色成长
|
||||
|
||||
---
|
||||
|
||||
**记住**:言情是关于两个人在一起变得比分开时更好的旅程。障碍应该迫使成长,化学反应应该感觉不可避免,结局应该感觉是赢得的。
|
||||
@@ -1,185 +0,0 @@
|
||||
---
|
||||
name: novelweave-workflow
|
||||
description: 使用 NovelWeave 进行小说创作的完整工作流程,包括命令使用、最佳实践和高效创作技巧。适用于规划小说项目、组织创作过程或学习 NovelWeave 功能。
|
||||
version: 1.0.0
|
||||
keywords: [NovelWeave, 工作流, 小说命令, 创作流程, 最佳实践]
|
||||
when_to_use: 开始新小说项目、优化创作流程、学习 NovelWeave 功能或需要创作指导时使用
|
||||
allowed_tool_groups: [read]
|
||||
---
|
||||
|
||||
# NovelWeave 小说创作工作流
|
||||
|
||||
## NovelWeave 核心理念
|
||||
|
||||
NovelWeave 是一个 AI 驱动的小说创作助手,设计用于支持从构思到完稿的整个创作过程。
|
||||
|
||||
### 三大支柱
|
||||
|
||||
1. **结构化创作** - 通过专用命令引导创作流程
|
||||
2. **知识管理** - 使用 Knowledge Base 追踪世界观和角色
|
||||
3. **AI 协作** - 与 AI 共同创作,而非让 AI 独立创作
|
||||
|
||||
## 完整创作工作流
|
||||
|
||||
### 阶段 1:构思和规划
|
||||
|
||||
#### 1.1 定义创作核心(Constitution)
|
||||
|
||||
使用 `/constitution` 命令建立小说的核心价值观和主题。
|
||||
|
||||
**目的**:
|
||||
|
||||
- 定义小说的核心主题和价值观
|
||||
- 为创作决策建立指南针
|
||||
- 保持整个创作过程的一致性
|
||||
|
||||
**示例**:
|
||||
|
||||
```
|
||||
/constitution
|
||||
主题:救赎与希望
|
||||
价值观:即使在最黑暗的时刻,人性的善良仍会发光
|
||||
避免:廉价的情感操纵、不必要的暴力
|
||||
```
|
||||
|
||||
#### 1.2 制定创作计划
|
||||
|
||||
使用 `/plan` 命令构建小说大纲和结构。
|
||||
|
||||
**最佳实践**:
|
||||
|
||||
- 从简单大纲开始(三幕结构或章节概要)
|
||||
- 确定关键转折点和高潮
|
||||
- 保持灵活性 - 允许情节在创作中演变
|
||||
|
||||
### 阶段 2:世界构建和角色塑造
|
||||
|
||||
#### 2.1 建立角色档案
|
||||
|
||||
使用 Agent Rules 和 Knowledge Base 创建详细的角色档案。
|
||||
|
||||
**关键要素**:
|
||||
|
||||
- 外貌、性格、动机
|
||||
- 背景故事和创伤
|
||||
- 角色弧线和成长轨迹
|
||||
- 语言风格和习惯用语
|
||||
|
||||
#### 2.2 构建世界设定
|
||||
|
||||
为奇幻、科幻或复杂背景建立世界观。
|
||||
|
||||
**记录内容**:
|
||||
|
||||
- 地理和地点
|
||||
- 历史和文化
|
||||
- 魔法系统或科技规则
|
||||
- 社会结构和政治
|
||||
|
||||
### 阶段 3:场景创作
|
||||
|
||||
#### 3.1 使用 `/write` 命令
|
||||
|
||||
这是核心创作命令,用于生成场景内容。
|
||||
|
||||
**有效的 `/write` 请求**:
|
||||
|
||||
```
|
||||
/write
|
||||
场景:艾米在废弃工厂与追踪者对峙
|
||||
情感:紧张、恐惧但决心坚定
|
||||
重点:展示艾米的机智和勇气
|
||||
长度:800-1000 字
|
||||
```
|
||||
|
||||
**避免**:
|
||||
|
||||
- 过于宽泛的请求("写第一章")
|
||||
- 缺乏情感方向
|
||||
- 没有明确的场景目标
|
||||
|
||||
#### 3.2 追踪场景连续性
|
||||
|
||||
使用 `/track` 系统维护情节、角色和时间线的一致性。
|
||||
|
||||
**功能**:
|
||||
|
||||
- 追踪角色状态和情感弧线
|
||||
- 记录重要事件和时间戳
|
||||
- 识别潜在的情节漏洞
|
||||
|
||||
### 阶段 4:审稿和修订
|
||||
|
||||
#### 4.1 质量保证
|
||||
|
||||
使用一致性检查工具审查稿件。
|
||||
|
||||
**检查领域**:
|
||||
|
||||
- 角色一致性(外貌、性格、声音)
|
||||
- 情节连续性
|
||||
- 时间线准确性
|
||||
- 主题一致性
|
||||
|
||||
#### 4.2 风格润色
|
||||
|
||||
审查对话、节奏和描写质量。
|
||||
|
||||
**常见改进点**:
|
||||
|
||||
- 对话真实性
|
||||
- 展示 vs. 告知平衡
|
||||
- 节奏和张力
|
||||
- 感官细节
|
||||
|
||||
## NovelWeave 最佳实践
|
||||
|
||||
### 1. 增量创作
|
||||
|
||||
- 一次专注于一个场景
|
||||
- 先完成粗稿,再精炼
|
||||
- 允许灵感自然涌现
|
||||
|
||||
### 2. 充分利用 Knowledge Base
|
||||
|
||||
- 记录所有重要细节
|
||||
- 定期审查以确保一致性
|
||||
- 在创作时参考现有材料
|
||||
|
||||
### 3. 与 AI 有效协作
|
||||
|
||||
- 提供明确的方向和上下文
|
||||
- 审查并编辑 AI 生成的内容
|
||||
- 保持你独特的创作声音
|
||||
|
||||
### 4. 保持灵活性
|
||||
|
||||
- 允许故事自然演变
|
||||
- 不要过度规划
|
||||
- 相信创作过程
|
||||
|
||||
## 常见陷阱避免
|
||||
|
||||
❌ **过度依赖 AI** - 你是作者,AI 是助手
|
||||
❌ **跳过规划** - 一些结构能防止后期大返工
|
||||
❌ **忽视一致性** - 小错误会累积破坏可信度
|
||||
❌ **一次写太多** - 专注质量而非数量
|
||||
|
||||
## 快速参考:关键命令
|
||||
|
||||
- `/constitution` - 定义核心价值观和主题
|
||||
- `/plan` - 创建和管理小说大纲
|
||||
- `/write` - 生成场景内容
|
||||
- `/track` - 追踪情节和角色一致性
|
||||
- `/clarify` - 解决情节问题和填补漏洞
|
||||
- `/analyze` - 深入分析文本和结构
|
||||
|
||||
## 与其他 Skills 配合
|
||||
|
||||
- **类型知识** Skills(奇幻、言情、悬疑)提供类型特定指导
|
||||
- **写作技巧** Skills(对话、场景结构)提升技艺水平
|
||||
- **质量保证** Skills(一致性检查)确保专业品质
|
||||
|
||||
---
|
||||
|
||||
**记住**:NovelWeave 旨在增强你的创造力,而非替代它。保持你的独特声音,让 AI 帮助你实现愿景。
|
||||
@@ -1,367 +0,0 @@
|
||||
---
|
||||
name: story-consistency-monitor
|
||||
description: "在章节写作过程中自动检查角色行为、世界规则和时间线一致性 - 在潜在矛盾成为重大问题前发出警报"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 故事一致性监控
|
||||
|
||||
## 自动检查系统
|
||||
|
||||
### 本技能监控什么
|
||||
|
||||
#### 角色一致性
|
||||
|
||||
- **物理特征**:眼睛颜色、身高、年龄、疤痕
|
||||
- **性格**:行动符合已建立的角色
|
||||
- **知识**:角色只知道他们应该知道的
|
||||
- **成长**:变化与角色弧线一致
|
||||
|
||||
#### 世界规则
|
||||
|
||||
- **魔法/科技系统**:力量的使用一致
|
||||
- **地理**:距离和地点保持稳定
|
||||
- **社会规则**:文化和习俗不矛盾
|
||||
- **物理法则**:已建立的规则不随机打破
|
||||
|
||||
#### 时间线逻辑
|
||||
|
||||
- **事件顺序**:A 在逻辑上发生在 B 之前
|
||||
- **时间流逝**:角色适当地老化
|
||||
- **同时事件**:多 POV 时间线对齐
|
||||
- **历史一致性**:过去的引用保持一致
|
||||
|
||||
### 如何工作
|
||||
|
||||
**被动监控**:当你写作或讨论故事时,我会自动交叉参考:
|
||||
|
||||
1. `characters/` 目录中的角色档案
|
||||
2. `worldbuilding/` 目录中的世界构建文档
|
||||
3. `spec/tracking/timeline.json` 中的时间线数据
|
||||
4. 之前章节的内容
|
||||
|
||||
**不需要你采取任何行动** - 监控在后台进行。
|
||||
|
||||
## 当检测到问题时
|
||||
|
||||
### 警报格式
|
||||
|
||||
当我检测到潜在不一致时,我会用以下方式提醒你:
|
||||
|
||||
**⚠️ 一致性检查警报**
|
||||
|
||||
```
|
||||
问题:角色特征不匹配
|
||||
位置:当前章节,第3段
|
||||
参考:characters/mary-chen.md,第15行
|
||||
|
||||
当前文本:"玛丽的绿色眼睛眯起..."
|
||||
已建立特征:"眼睛颜色:蓝色"(在第3章中设定)
|
||||
|
||||
可能的解决方案:
|
||||
1. 将当前文本改为"蓝色眼睛"
|
||||
2. 如果你要修改设定,更新角色档案
|
||||
3. 这是一个有相似名字的不同角色?
|
||||
|
||||
你想让我自动修复这个,还是你更愿意自己处理?
|
||||
```
|
||||
|
||||
### 严重程度级别
|
||||
|
||||
| 级别 | 图标 | 行动 | 示例 |
|
||||
| -------- | ---- | -------------- | ------------------------------------ |
|
||||
| **关键** | 🔴 | 立即停止并修复 | 角色突然知道他们不应该知道的秘密信息 |
|
||||
| **警告** | ⚠️ | 尽快修复 | 角色的惯常言语模式改变了 |
|
||||
| **注意** | 📝 | 考虑检查 | 时间线感觉压缩 |
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
### 在 `/write` 期间
|
||||
|
||||
- 在生成内容时进行实时一致性检查
|
||||
- 对关键问题的即时警报
|
||||
- 自动参考规格文档
|
||||
|
||||
### 在 `/analyze` 期间
|
||||
|
||||
- 全面的一致性报告
|
||||
- 所有累积的警告和注意事项
|
||||
- 建议的修复按严重性排序
|
||||
|
||||
### 在 `/track` 期间
|
||||
|
||||
- 使用经过验证的信息更新追踪数据
|
||||
- 标记不一致以供手动审查
|
||||
- 维护一致性历史
|
||||
|
||||
## 配置
|
||||
|
||||
### 严格程度级别
|
||||
|
||||
你可以调整一致性检查的严格程度:
|
||||
|
||||
**严格模式**(非奇幻的默认):
|
||||
|
||||
- 标记所有矛盾
|
||||
- 执行真实世界物理
|
||||
- 时间线必须完全合乎逻辑
|
||||
|
||||
**灵活模式**(推荐用于奇幻/科幻):
|
||||
|
||||
- 允许"酷炫规则"例外
|
||||
- 魔法/科技可以弯曲现实
|
||||
- 允许艺术许可,但会通知
|
||||
|
||||
**最小模式**:
|
||||
|
||||
- 只标记关键矛盾
|
||||
- 专注于角色和主要情节点
|
||||
- 让小的不一致通过
|
||||
|
||||
### 禁用特定检查
|
||||
|
||||
如果某些不一致是有意的:
|
||||
|
||||
```
|
||||
"请为梦境序列禁用时间线检查 -
|
||||
它们有意是非线性的。"
|
||||
```
|
||||
|
||||
## 常见误报
|
||||
|
||||
有时我会标记实际上正确的东西:
|
||||
|
||||
### 有意的矛盾
|
||||
|
||||
**示例**:角色谎报眼睛颜色
|
||||
**修复**:在角色档案中添加评论:"// 眼睛实际上是蓝色的,告诉人们是绿色的"
|
||||
|
||||
### 不可靠的叙述者
|
||||
|
||||
**示例**:第一人称叙述者记错事件
|
||||
**修复**:在宪法中注明:"不可靠的叙述者 - 记忆不一致是有意的"
|
||||
|
||||
### 时间跳跃
|
||||
|
||||
**示例**:角色的年龄突然增加
|
||||
**修复**:在章节中明确说明时间跳跃:"三年后..."
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 保持参考文档更新
|
||||
|
||||
一致性检查器只能和你的文档一样好:
|
||||
|
||||
- 特征变化时更新角色档案
|
||||
- 清楚地记录世界规则
|
||||
- 使用 `/timeline` 命令维护时间线文件
|
||||
|
||||
### 及时处理警报
|
||||
|
||||
不要让一致性问题累积:
|
||||
|
||||
- 立即修复关键警报
|
||||
- 在写作会话结束时审查警告
|
||||
- 在修订阶段批处理注意事项
|
||||
|
||||
### 与 `/track` 一起使用
|
||||
|
||||
一致性检查 + 追踪系统 = 强大组合:
|
||||
|
||||
- `/track --check` 运行深度一致性验证
|
||||
- `/track --fix` 可以自动修复简单问题
|
||||
- 定期使用两者(每 5-10 章)
|
||||
|
||||
## 检查类别详解
|
||||
|
||||
### 角色一致性检查
|
||||
|
||||
**物理描述**:
|
||||
|
||||
```
|
||||
✓ 检查:身高、体重、年龄、发色、眼色
|
||||
✓ 检查:疤痕、纹身、独特标记
|
||||
✓ 检查:服装风格、配饰
|
||||
```
|
||||
|
||||
**行为模式**:
|
||||
|
||||
```
|
||||
✓ 检查:言语模式是否一致
|
||||
✓ 检查:反应是否符合性格
|
||||
✓ 检查:决策是否符合价值观
|
||||
✓ 检查:技能/能力是否一致
|
||||
```
|
||||
|
||||
**知识状态**:
|
||||
|
||||
```
|
||||
✓ 检查:角色知道什么时候知道的
|
||||
✓ 检查:他们不知道不应该知道的秘密
|
||||
✓ 检查:记忆与已建立事实一致
|
||||
```
|
||||
|
||||
### 世界规则检查
|
||||
|
||||
**魔法/科技系统**:
|
||||
|
||||
```
|
||||
✓ 检查:力量在已建立限制内使用
|
||||
✓ 检查:代价/成本一致应用
|
||||
✓ 检查:规则不为了情节便利而改变
|
||||
✓ 检查:例外有前期暗示
|
||||
```
|
||||
|
||||
**地理和距离**:
|
||||
|
||||
```
|
||||
✓ 检查:地点在地图上保持一致
|
||||
✓ 检查:旅行时间合理
|
||||
✓ 检查:气候与地理匹配
|
||||
✓ 检查:地标不移动
|
||||
```
|
||||
|
||||
**社会和文化**:
|
||||
|
||||
```
|
||||
✓ 检查:文化规范一致
|
||||
✓ 检查:语言和方言保持稳定
|
||||
✓ 检查:社会结构不随机改变
|
||||
✓ 检查:宗教/信仰保持一致
|
||||
```
|
||||
|
||||
### 时间线检查
|
||||
|
||||
**事件序列**:
|
||||
|
||||
```
|
||||
✓ 检查:原因发生在结果之前
|
||||
✓ 检查:角色不在他们不能在的地方
|
||||
✓ 检查:事件在合理的时间范围内发生
|
||||
```
|
||||
|
||||
**时间流逝**:
|
||||
|
||||
```
|
||||
✓ 检查:角色适当地老化
|
||||
✓ 检查:季节按顺序改变
|
||||
✓ 检查:怀孕/康复需要适当的时间
|
||||
✓ 检查:技能习得需要练习时间
|
||||
```
|
||||
|
||||
**多POV同步**:
|
||||
|
||||
```
|
||||
✓ 检查:同时事件从不同POV匹配
|
||||
✓ 检查:时间跳跃在POV之间对齐
|
||||
✓ 检查:没有POV知道其他POV的未来
|
||||
```
|
||||
|
||||
## 自动修复功能
|
||||
|
||||
对于某些简单问题,我可以提供自动修复:
|
||||
|
||||
### 自动修复类型
|
||||
|
||||
**拼写变化**:
|
||||
|
||||
```
|
||||
检测:角色名字拼写不一致
|
||||
建议:标准化为最常见的拼写
|
||||
行动:全局查找并替换(经你批准)
|
||||
```
|
||||
|
||||
**数字不一致**:
|
||||
|
||||
```
|
||||
检测:角色年龄在章节间不匹配
|
||||
建议:基于时间线计算正确年龄
|
||||
行动:更新到正确数字
|
||||
```
|
||||
|
||||
**时间线冲突**:
|
||||
|
||||
```
|
||||
检测:事件日期与已建立时间线冲突
|
||||
建议:调整日期以适应已知序列
|
||||
行动:更新时间线参考
|
||||
```
|
||||
|
||||
## 报告和追踪
|
||||
|
||||
### 一致性报告
|
||||
|
||||
定期(或根据要求),我会生成:
|
||||
|
||||
```markdown
|
||||
## 一致性报告 - [日期]
|
||||
|
||||
### 章节范围:章节 1-15
|
||||
|
||||
### 检测到的问题
|
||||
|
||||
#### 关键(必须修复)
|
||||
|
||||
1. 第12章:角色知道只在第14章揭示的信息
|
||||
- 修复:重写第12章场景或移动第14章揭示更早
|
||||
|
||||
#### 警告(应该修复)
|
||||
|
||||
1. 第8章:角色的眼睛颜色从蓝色变为绿色
|
||||
- 修复建议:将第8章更新为蓝色或更新角色档案
|
||||
2. 第10章:从首都到边境的旅行只用了1天(之前建立为3天)
|
||||
- 修复建议:添加时间跳跃或调整天数
|
||||
|
||||
#### 注意事项(考虑检查)
|
||||
|
||||
1. 第5章:角色反应似乎不符合特征
|
||||
- 审查:这是有意的成长还是不一致?
|
||||
|
||||
### 统计
|
||||
|
||||
- 总检查:456
|
||||
- 问题发现:8
|
||||
- 自动修复:3
|
||||
- 需要审查:5
|
||||
|
||||
### 一致性得分:94%
|
||||
```
|
||||
|
||||
### 追踪历史
|
||||
|
||||
我维护发现和修复的一致性问题的历史:
|
||||
|
||||
- 有助于识别模式
|
||||
- 防止重复错误
|
||||
- 显示随时间的改进
|
||||
- 对修订有用
|
||||
|
||||
## 与其他技能协作
|
||||
|
||||
### 配合 Writing Techniques Skills
|
||||
|
||||
**对话一致性**:
|
||||
|
||||
- 检查角色声音是否保持
|
||||
- 验证言语模式
|
||||
- 标记不符合特征的对话
|
||||
|
||||
**场景一致性**:
|
||||
|
||||
- 验证设定细节
|
||||
- 检查物理可能性
|
||||
- 确认时间流逝
|
||||
|
||||
### 配合 Genre Knowledge Skills
|
||||
|
||||
**类型惯例一致性**:
|
||||
|
||||
- 确保类型规则应用一致
|
||||
- 检查陷阱是否一致避免
|
||||
- 验证节奏模式
|
||||
|
||||
---
|
||||
|
||||
**记住**:一致性不是关于完美 - 它是关于读者的信任。当世界规则可靠时,读者沉浸其中。当规则似乎随意改变时,他们被拉出体验。我在这里帮助维持这种信任。
|
||||
|
||||
**你总是有最后的决定权** - 如果不一致是艺术选择,告诉我,我会停止标记它。
|
||||
@@ -1,148 +0,0 @@
|
||||
---
|
||||
name: forgotten-elements-reminder
|
||||
description: "当重要的故事元素(角色、情节线、伏笔)10章以上未出现时自动提醒 - 防止长篇小说中的'角色消失综合症'和遗漏的情节线"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 遗忘元素提醒器
|
||||
|
||||
## 核心功能
|
||||
|
||||
**防止长篇小说常见问题**:
|
||||
|
||||
- 角色突然消失("配角A去哪了?")
|
||||
- 情节线被遗忘("那个伏笔后来呢?")
|
||||
- 伏笔没回收("前文说的宝藏呢?")
|
||||
|
||||
**解决方案**:后台监控,主动提醒已经很久未出现的元素。
|
||||
|
||||
---
|
||||
|
||||
## 监控内容
|
||||
|
||||
### 1. 角色出场频率
|
||||
|
||||
```
|
||||
监控:character-state.json中的所有角色
|
||||
阈值:10章未出现
|
||||
|
||||
提醒示例:
|
||||
⚠️ 角色提醒:
|
||||
"配角李明"已经10章未出现(上次:第5章)
|
||||
- 是否应该安排他再次出场?
|
||||
- 还是这个角色的故事已结束?
|
||||
```
|
||||
|
||||
### 2. 情节线进度
|
||||
|
||||
```
|
||||
监控:plot-tracker.json中的活跃情节线
|
||||
阈值:12章无进展
|
||||
|
||||
提醒示例:
|
||||
⚠️ 情节线提醒:
|
||||
"寻找父亲仇人"情节线已12章无进展
|
||||
- 上次推进:第8章
|
||||
- 当前状态:pending
|
||||
- 建议:安排相关情节或标记为暂停
|
||||
```
|
||||
|
||||
### 3. 伏笔回收
|
||||
|
||||
```
|
||||
监控:在前文埋下的重要伏笔
|
||||
阈值:20章未回收
|
||||
|
||||
提醒示例:
|
||||
⚠️ 伏笔提醒:
|
||||
第3章提到"神秘盒子",至今未揭秘(已过23章)
|
||||
- 读者可能已经忘记
|
||||
- 建议:尽快回收或在对话中提及
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 提醒时机
|
||||
|
||||
### 写作前提醒
|
||||
|
||||
```
|
||||
执行 `/write` 时,如果检测到遗忘元素:
|
||||
|
||||
📋 写作前检查...
|
||||
⚠️ 发现3个被遗忘的元素:
|
||||
|
||||
1. 角色"张婶"已15章未出现
|
||||
2. 情节线"寻宝"已13章无进展
|
||||
3. 伏笔"神秘信件"已20章未揭秘
|
||||
|
||||
💡 本章是否考虑处理?
|
||||
```
|
||||
|
||||
### 分析时汇总
|
||||
|
||||
```
|
||||
执行 `/analyze` 时,生成完整报告:
|
||||
|
||||
## 遗忘元素报告
|
||||
|
||||
### 失踪角色(3个)
|
||||
1. 张婶(15章未出场)
|
||||
2. 李老板(11章未出场)
|
||||
3. 王医生(10章未出场)
|
||||
|
||||
### 停滞情节线(2个)
|
||||
1. 寻宝线(13章无进展)
|
||||
2. 复仇线(12章无进展)
|
||||
|
||||
### 未回收伏笔(1个)
|
||||
1. 神秘信件(20章未揭秘)
|
||||
|
||||
建议:
|
||||
- 优先处理失踪角色(读者可能已忘记)
|
||||
- 推进停滞情节线或标记为"暂停"
|
||||
- 伏笔及时回收(否则成烂尾)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 调整阈值
|
||||
|
||||
```
|
||||
"角色未出场提醒阈值改为15章"
|
||||
"情节线停滞提醒阈值改为20章"
|
||||
```
|
||||
|
||||
### 排除特定元素
|
||||
|
||||
```
|
||||
"张婶角色已完结,不再提醒"
|
||||
"寻宝线有意暂停,30章后才推进,不提醒"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **定期查看**:每10章运行一次 `/analyze` 查看报告
|
||||
2. **及时处理**:不要让太多元素堆积
|
||||
3. **主动标记**:已完结的角色标记为"retired"
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
forgotten-elements-reminder = 你的**记忆助手**
|
||||
|
||||
✓ 自动监控角色/情节/伏笔
|
||||
✓ 超过阈值主动提醒
|
||||
✓ 防止长篇小说烂尾
|
||||
|
||||
**长篇小说必备!** 📝
|
||||
|
||||
---
|
||||
|
||||
**本Skill版本**: v1.0
|
||||
**最后更新**: 2025-10-18
|
||||
@@ -1,225 +0,0 @@
|
||||
---
|
||||
name: getting-started-guide
|
||||
description: "当用户开始新小说项目时激活 - 通过温和的提示和解释引导他们完成七步方法论(constitution → specify → clarify → plan → tasks → write → analyze)"
|
||||
allowed-tools: Read
|
||||
---
|
||||
|
||||
# 新用户入门引导
|
||||
|
||||
## 激活条件
|
||||
|
||||
当用户说出以下内容时自动激活:
|
||||
|
||||
- "我想写小说"
|
||||
- "我要开始一个新项目"
|
||||
- "怎么使用novel-writer"
|
||||
- "从哪里开始"
|
||||
|
||||
---
|
||||
|
||||
## 七步方法论引导
|
||||
|
||||
### 欢迎消息
|
||||
|
||||
```
|
||||
👋 欢迎使用Novel Writer Skills!
|
||||
|
||||
我注意到你要开始一个新的小说项目。
|
||||
Novel Writer使用系统化的七步方法论,帮助你从想法到完稿。
|
||||
|
||||
让我带你快速了解流程:
|
||||
|
||||
第1步:/constitution - 创建创作宪法
|
||||
第2步:/specify - 定义故事规格
|
||||
第3步:/clarify - 澄清模糊点(5个问题)
|
||||
第4步:/plan - 制定创作计划
|
||||
第5步:/tasks - 分解任务清单
|
||||
第6步:/write - 执行章节写作
|
||||
第7步:/analyze - 质量验证分析
|
||||
|
||||
想要详细了解每一步吗?还是直接开始第1步?
|
||||
```
|
||||
|
||||
### 步骤详解(根据需要提供)
|
||||
|
||||
```
|
||||
【第1步:/constitution】
|
||||
创建你的创作宪法 - 这是最高原则。
|
||||
- 核心价值观(你想传达什么?)
|
||||
- 质量标准(什么算好的章节?)
|
||||
- 禁忌红线(不能写什么?)
|
||||
|
||||
为什么重要:后续所有创作都要符合宪法。
|
||||
|
||||
【第2步:/specify】
|
||||
定义故事规格 - 明确你要写什么。
|
||||
- 故事概念、类型、主题
|
||||
- 目标读者、字数、结局
|
||||
- 必须包含的元素(P0)
|
||||
|
||||
为什么重要:规格是技术需求,避免写到一半发现偏题。
|
||||
|
||||
【第3步:/clarify】
|
||||
AI提出5个关键问题,帮你澄清模糊点。
|
||||
- 针对specification中的不明确之处
|
||||
- 逼迫你想清楚细节
|
||||
|
||||
为什么重要:模糊的规格=模糊的故事。
|
||||
|
||||
【第4步:/plan】
|
||||
制定创作计划 - 技术方案。
|
||||
- 章节架构、节奏设计
|
||||
- 关键情节点时间线
|
||||
- 技术难点的解决方案
|
||||
|
||||
为什么重要:计划详细,执行才顺畅。
|
||||
|
||||
【第5步:/tasks】
|
||||
分解任务清单 - 可执行的步骤。
|
||||
- 每个章节一个任务
|
||||
- 标记状态(pending/in_progress/completed)
|
||||
- 追踪进度
|
||||
|
||||
为什么重要:大目标拆解成小任务,不overwhelm。
|
||||
|
||||
【第6步:/write】
|
||||
执行写作 - 基于任务清单。
|
||||
- 自动加载所有context
|
||||
- 遵循宪法、规格、计划
|
||||
- 质量自检后保存
|
||||
|
||||
为什么重要:这是七步方法论的优势集中体现。
|
||||
|
||||
【第7步:/analyze】
|
||||
质量验证 - 确保一致性。
|
||||
- 框架检查(结构、节奏)
|
||||
- 内容检查(一致性、质量)
|
||||
- 发现问题,建议修复
|
||||
|
||||
为什么重要:定期分析,及时调整,避免大返工。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题快速解答
|
||||
|
||||
### Q: 必须按顺序执行吗?
|
||||
|
||||
**A**: 推荐按顺序,但不强制。
|
||||
|
||||
```
|
||||
推荐流程:1→2→3→4→5→6→7(循环6-7)
|
||||
|
||||
允许跳步:
|
||||
- 有经验的作者可以跳过/clarify
|
||||
- 短篇可以简化/plan
|
||||
|
||||
不推荐:
|
||||
- 直接跳到/write(缺少规格和计划,容易写乱)
|
||||
```
|
||||
|
||||
### Q: 七步走完要多久?
|
||||
|
||||
**A**: 取决于故事复杂度。
|
||||
|
||||
```
|
||||
简单故事(5万字短篇):
|
||||
- 步骤1-5:2-3小时
|
||||
- 步骤6-7:执行写作,持续进行
|
||||
|
||||
复杂故事(50万字长篇):
|
||||
- 步骤1-5:1-2天
|
||||
- 步骤6-7:数月
|
||||
|
||||
前期投入换来后期顺畅。
|
||||
```
|
||||
|
||||
### Q: 可以中途修改吗?
|
||||
|
||||
**A**: 当然!
|
||||
|
||||
```
|
||||
发现规格不对:
|
||||
→ 修改specification.md
|
||||
→ 重新运行/plan调整计划
|
||||
|
||||
计划需要调整:
|
||||
→ 修改creative-plan.md
|
||||
→ 更新tasks.md
|
||||
|
||||
这是迭代过程,不是一次定死。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第一次使用建议
|
||||
|
||||
### 从简单项目开始
|
||||
|
||||
```
|
||||
✓ 推荐:
|
||||
- 5-10万字的中短篇
|
||||
- 单一类型(言情/悬疑/历史)
|
||||
- 简单情节(1-2条主线)
|
||||
|
||||
⚠️ 不推荐初次就写:
|
||||
- 50万字+的长篇
|
||||
- 多类型融合(如言情+悬疑+奇幻+历史)
|
||||
- 超复杂世界观
|
||||
|
||||
先熟悉流程,再挑战复杂项目。
|
||||
```
|
||||
|
||||
### 执行第一个命令
|
||||
|
||||
```
|
||||
准备好了?让我们开始第1步:
|
||||
|
||||
执行命令:/constitution
|
||||
|
||||
我会引导你创建创作宪法。
|
||||
准备回答以下问题:
|
||||
1. 这个故事你想传达什么核心理念?
|
||||
2. 你对质量的标准是什么?
|
||||
3. 有哪些内容是绝对不能写的?
|
||||
|
||||
准备好了就输入:/constitution
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与workflow-guide的配合
|
||||
|
||||
```
|
||||
getting-started:
|
||||
- 初次使用时激活
|
||||
- 提供完整流程概览
|
||||
- 回答入门问题
|
||||
|
||||
workflow-guide:
|
||||
- 整个创作过程中持续激活
|
||||
- 偏离流程时温和提醒
|
||||
- 提供最佳实践建议
|
||||
|
||||
两者互补:
|
||||
getting-started = 入门教程
|
||||
workflow-guide = 持续顾问
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
getting-started-guide = 你的**入门向导**
|
||||
|
||||
✓ 自动识别新用户
|
||||
✓ 引导七步方法论
|
||||
✓ 回答常见问题
|
||||
✓ 给出第一步建议
|
||||
|
||||
**让第一次使用不再迷茫!** 🚀
|
||||
|
||||
---
|
||||
|
||||
**本Skill版本**: v1.0
|
||||
**最后更新**: 2025-10-18
|
||||
@@ -1,549 +0,0 @@
|
||||
---
|
||||
name: pre-write-checklist
|
||||
description: "在章节写作前自动激活,强制执行9项必读文件检查清单 - 通过确保每次写作前加载所有上下文来防止AI在长篇小说中的焦点退化"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# 写作前强制检查清单
|
||||
|
||||
## 核心功能
|
||||
|
||||
**解决AI长篇失焦问题** - 这是Novel Writer Skills v1.0的核心创新。
|
||||
|
||||
### 问题根源
|
||||
|
||||
用户反馈:使用novel-writer创作,前30章质量很好,但30章后AI开始:
|
||||
|
||||
- 忘记前文设定
|
||||
- 角色性格不一致
|
||||
- 情节重复或矛盾
|
||||
- 忽略创作宪法的原则
|
||||
|
||||
**根本原因**:长对话导致AI遗忘早期context,即使specification.md写得再详细也会被忘记。
|
||||
|
||||
### 解决方案
|
||||
|
||||
**每次写作前强制重读所有关键文件** → AI重新加载完整context → 保持一致性
|
||||
|
||||
---
|
||||
|
||||
## 9项强制检查清单
|
||||
|
||||
每次执行`/write`命令时,必须先完成此检查清单:
|
||||
|
||||
```markdown
|
||||
📋 写作前检查清单(必须完成):
|
||||
|
||||
✓ 1. memory/constitution.md - 创作宪法
|
||||
✓ 2. memory/style-reference.md - 风格参考(如有)
|
||||
✓ 3. stories/_/specification.md - 故事规格
|
||||
✓ 4. stories/_/creative-plan.md - 创作计划
|
||||
✓ 5. stories/\*/tasks.md - 当前任务
|
||||
✓ 6. spec/tracking/character-state.json - 角色状态
|
||||
✓ 7. spec/tracking/relationships.json - 关系网络
|
||||
✓ 8. spec/tracking/plot-tracker.json - 情节追踪(如有)
|
||||
✓ 9. spec/tracking/validation-rules.json - 验证规则(如有)
|
||||
|
||||
📊 上下文加载状态:✅ 完成
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 工作原理
|
||||
|
||||
### 自动触发时机
|
||||
|
||||
1. **用户执行 `/write` 命令**
|
||||
2. **本Skill自动激活**
|
||||
3. **强制执行检查清单**
|
||||
4. **输出确认报告**
|
||||
5. **然后才开始写作**
|
||||
|
||||
### 执行流程
|
||||
|
||||
```
|
||||
用户: /write 第10章
|
||||
|
||||
↓
|
||||
|
||||
[pre-write-checklist 自动激活]
|
||||
|
||||
↓
|
||||
|
||||
步骤1:读取 memory/constitution.md
|
||||
步骤2:读取 memory/style-reference.md(如有)
|
||||
步骤3:读取 stories/*/specification.md
|
||||
步骤4:读取 stories/*/creative-plan.md
|
||||
步骤5:读取 stories/*/tasks.md
|
||||
步骤6:读取 spec/tracking/character-state.json
|
||||
步骤7:读取 spec/tracking/relationships.json
|
||||
步骤8:读取 spec/tracking/plot-tracker.json(如有)
|
||||
步骤9:读取 spec/tracking/validation-rules.json(如有)
|
||||
|
||||
↓
|
||||
|
||||
输出确认:
|
||||
📋 写作前检查清单(已完成):
|
||||
✓ 1-9 所有文件已读取
|
||||
📊 上下文加载状态:✅ 完成
|
||||
|
||||
关键信息摘要:
|
||||
- 创作原则:[从constitution提取]
|
||||
- 当前任务:[从tasks.md提取]
|
||||
- 主要角色:[从character-state提取]
|
||||
- 情节进度:[从plot-tracker提取]
|
||||
|
||||
↓
|
||||
|
||||
开始写作第10章...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 标准输出(所有文件存在)
|
||||
|
||||
```markdown
|
||||
📋 写作前检查清单(已完成):
|
||||
|
||||
✓ 1. memory/constitution.md - 创作宪法
|
||||
→ 核心原则:[列出2-3条关键原则]
|
||||
|
||||
✓ 2. memory/style-reference.md - 风格参考
|
||||
→ 风格要点:[提取关键风格要求]
|
||||
|
||||
✓ 3. stories/xxx/specification.md - 故事规格
|
||||
→ 故事类型:[言情/悬疑/历史等]
|
||||
→ P0元素:[必须包含的元素]
|
||||
|
||||
✓ 4. stories/xxx/creative-plan.md - 创作计划
|
||||
→ 当前阶段:[第X卷/第X章]
|
||||
→ 本章目标:[情节/情感目标]
|
||||
|
||||
✓ 5. stories/xxx/tasks.md - 当前任务
|
||||
→ 待写章节:[第X章]
|
||||
→ 任务状态:[pending/in_progress]
|
||||
|
||||
✓ 6. spec/tracking/character-state.json - 角色状态
|
||||
→ 主要角色:[列出角色名和当前状态]
|
||||
|
||||
✓ 7. spec/tracking/relationships.json - 关系网络
|
||||
→ 核心关系:[主角与谁的关系变化]
|
||||
|
||||
✓ 8. spec/tracking/plot-tracker.json - 情节追踪
|
||||
→ 活跃线索:[当前进行中的情节线]
|
||||
|
||||
✓ 9. spec/tracking/validation-rules.json - 验证规则
|
||||
→ 自动修复:[启用/禁用]
|
||||
|
||||
📊 上下文加载状态:✅ 完成(加载9个文件,约XXXX tokens)
|
||||
|
||||
🎯 准备写作第X章...
|
||||
```
|
||||
|
||||
### 部分文件缺失时
|
||||
|
||||
```markdown
|
||||
📋 写作前检查清单(部分完成):
|
||||
|
||||
✓ 1. memory/constitution.md - 创作宪法
|
||||
✓ 2. ⚠️ memory/style-reference.md - 不存在(可选文件,跳过)
|
||||
✓ 3. stories/xxx/specification.md - 故事规格
|
||||
✓ 4. stories/xxx/creative-plan.md - 创作计划
|
||||
✓ 5. stories/xxx/tasks.md - 当前任务
|
||||
✓ 6. spec/tracking/character-state.json - 角色状态
|
||||
✓ 7. spec/tracking/relationships.json - 关系网络
|
||||
✓ 8. ⚠️ spec/tracking/plot-tracker.json - 不存在(可选文件,跳过)
|
||||
✓ 9. ⚠️ spec/tracking/validation-rules.json - 不存在(可选文件,跳过)
|
||||
|
||||
📊 上下文加载状态:✅ 完成(加载6个必须文件 + 0个可选文件)
|
||||
|
||||
💡 建议:运行 `/track-init` 初始化完整追踪系统
|
||||
```
|
||||
|
||||
### 关键文件缺失时(阻止写作)
|
||||
|
||||
```markdown
|
||||
📋 写作前检查清单(失败):
|
||||
|
||||
✓ 1. memory/constitution.md - 创作宪法
|
||||
✓ 2. memory/style-reference.md - 风格参考
|
||||
❌ 3. stories/xxx/specification.md - **文件不存在**
|
||||
❌ 4. stories/xxx/creative-plan.md - **文件不存在**
|
||||
❌ 5. stories/xxx/tasks.md - **文件不存在**
|
||||
|
||||
⛔ 错误:缺少必需文件,无法继续写作
|
||||
|
||||
必须先完成:
|
||||
|
||||
1. 运行 `/constitution` 创建创作宪法
|
||||
2. 运行 `/specify` 定义故事规格
|
||||
3. 运行 `/plan` 制定创作计划
|
||||
4. 运行 `/tasks` 分解任务清单
|
||||
|
||||
然后才能执行 `/write`
|
||||
|
||||
这是seven-step methodology的推荐流程。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与Commands集成
|
||||
|
||||
### `/write` 命令
|
||||
|
||||
**必须先执行检查清单,才能写作**:
|
||||
|
||||
```yaml
|
||||
执行顺序:
|
||||
1. pre-write-checklist(本Skill)→ 读取所有文件
|
||||
2. 输出确认报告
|
||||
3. 检查setting-detector → 是否需要激活知识库
|
||||
4. 开始实际写作
|
||||
```
|
||||
|
||||
### `/analyze` 命令
|
||||
|
||||
分析时也建议执行检查清单:
|
||||
|
||||
```yaml
|
||||
分析前先确保context完整:
|
||||
1. pre-write-checklist → 重新加载所有文件
|
||||
2. 基于最新状态执行分析
|
||||
```
|
||||
|
||||
### `/track` 命令
|
||||
|
||||
追踪更新后触发检查清单:
|
||||
|
||||
```yaml
|
||||
更新流程:
|
||||
1. 用户修改tracking文件
|
||||
2. 运行 `/track` 更新
|
||||
3. pre-write-checklist → 重新读取验证
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件重要性分类
|
||||
|
||||
### 必须文件(缺失则阻止写作)
|
||||
|
||||
```
|
||||
1. memory/constitution.md - 创作原则
|
||||
3. stories/*/specification.md - 故事规格
|
||||
4. stories/*/creative-plan.md - 创作计划
|
||||
5. stories/*/tasks.md - 当前任务
|
||||
6. spec/tracking/character-state.json - 角色状态
|
||||
7. spec/tracking/relationships.json - 关系网络
|
||||
```
|
||||
|
||||
**逻辑**:没有这些文件,AI不知道:
|
||||
|
||||
- 要遵循什么原则
|
||||
- 故事是关于什么的
|
||||
- 当前写到哪里了
|
||||
- 角色是谁、什么状态
|
||||
|
||||
### 可选文件(缺失时警告但允许继续)
|
||||
|
||||
```
|
||||
2. memory/style-reference.md - 风格参考
|
||||
8. spec/tracking/plot-tracker.json - 情节追踪
|
||||
9. spec/tracking/validation-rules.json - 验证规则
|
||||
```
|
||||
|
||||
**逻辑**:这些文件增强质量,但不是最低要求:
|
||||
|
||||
- style-reference:某些用户不用/book-internalize
|
||||
- plot-tracker:简单故事可能不需要
|
||||
- validation-rules:非必需的自动化
|
||||
|
||||
---
|
||||
|
||||
## 防失焦机制
|
||||
|
||||
### 问题场景
|
||||
|
||||
```
|
||||
第1章写作:
|
||||
- AI记得所有设定
|
||||
- 质量很好
|
||||
|
||||
第10章写作:
|
||||
- 对话已经很长
|
||||
- AI开始遗忘第1章的设定
|
||||
|
||||
第30章写作:
|
||||
- 完全忘记早期设定
|
||||
- 角色性格走样
|
||||
- 情节自相矛盾
|
||||
```
|
||||
|
||||
### 解决机制
|
||||
|
||||
```
|
||||
每次写作前:
|
||||
- 强制重读所有核心文件
|
||||
- 重新加载完整context
|
||||
- 像写第1章一样对待第30章
|
||||
|
||||
结果:
|
||||
- 第30章质量 ≈ 第1章质量
|
||||
- 一致性保持
|
||||
- 不再失焦
|
||||
```
|
||||
|
||||
### 效果对比
|
||||
|
||||
| 对比维度 | 无检查清单 | 有检查清单 |
|
||||
| --------- | ------------- | ---------- |
|
||||
| 第1-10章 | ✓ 质量好 | ✓ 质量好 |
|
||||
| 第11-30章 | ⚠️ 开始不稳定 | ✓ 保持稳定 |
|
||||
| 第31-50章 | ❌ 明显失焦 | ✓ 依然稳定 |
|
||||
| 第51+章 | ❌ 严重失焦 | ✓ 长期稳定 |
|
||||
|
||||
---
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 调整严格度
|
||||
|
||||
**默认:严格模式**(推荐)
|
||||
|
||||
```
|
||||
"使用严格检查清单模式"
|
||||
→ 缺少必需文件则阻止写作
|
||||
```
|
||||
|
||||
**宽松模式**(不推荐)
|
||||
|
||||
```
|
||||
"使用宽松检查清单模式"
|
||||
→ 允许跳过部分文件(不推荐,可能失焦)
|
||||
```
|
||||
|
||||
### 自定义检查项
|
||||
|
||||
如果你有额外的重要文件:
|
||||
|
||||
```
|
||||
"检查清单请额外包含:
|
||||
- spec/knowledge/worldbuilding/magic-system.md
|
||||
- spec/knowledge/characters/protagonist-profile.md"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 性能优化
|
||||
|
||||
### Token消耗
|
||||
|
||||
```
|
||||
每次写作的额外token成本:
|
||||
|
||||
9个文件读取:
|
||||
- constitution.md:~200 tokens
|
||||
- specification.md:~500 tokens
|
||||
- creative-plan.md:~300 tokens
|
||||
- tasks.md:~150 tokens
|
||||
- character-state.json:~200 tokens
|
||||
- relationships.json:~150 tokens
|
||||
- 其他:~200 tokens
|
||||
|
||||
总计:约1700 tokens/次写作
|
||||
|
||||
收益:
|
||||
- 避免失焦导致的重写(节省数万tokens)
|
||||
- 保持质量一致(用户满意度)
|
||||
- 长篇项目的可持续性
|
||||
```
|
||||
|
||||
**ROI极高**:1700 tokens换来长期稳定质量。
|
||||
|
||||
### 缓存策略
|
||||
|
||||
```
|
||||
同一写作会话中:
|
||||
第1次写作:读取所有文件(1700 tokens)
|
||||
第2次写作(1小时内):检查文件是否修改
|
||||
- 未修改:使用缓存(0 tokens)
|
||||
- 已修改:重新读取(部分tokens)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 每次写作都要读这么多文件,会不会很慢?
|
||||
|
||||
**A**: 不会。
|
||||
|
||||
- 文件读取很快(毫秒级)
|
||||
- token消耗合理(~1700 tokens)
|
||||
- 换来的是长期质量保证
|
||||
|
||||
**对比**:
|
||||
|
||||
- 不用检查清单:第30章质量差 → 用户要求重写10章 → 浪费数万tokens
|
||||
- 用检查清单:每章+1700 tokens → 50章也只+85000 tokens → 但质量稳定
|
||||
|
||||
### Q: 我能跳过检查清单吗?
|
||||
|
||||
**A**: 技术上可以,但**强烈不推荐**。
|
||||
|
||||
```
|
||||
"跳过检查清单,直接写作"
|
||||
→ AI会警告:"不推荐,可能导致失焦"
|
||||
→ 但会尊重你的选择
|
||||
```
|
||||
|
||||
**后果自负**:30章后失焦了别说我没提醒你😊
|
||||
|
||||
### Q: 某些文件我确实没有怎么办?
|
||||
|
||||
**A**: 分两种情况:
|
||||
|
||||
**必需文件缺失**(constitution、specification等):
|
||||
→ 阻止写作,提示先运行对应命令创建
|
||||
|
||||
**可选文件缺失**(style-reference、plot-tracker):
|
||||
→ 警告但允许继续,建议后续创建
|
||||
|
||||
### Q: 检查清单和setting-detector的关系?
|
||||
|
||||
**A**: 互补工作:
|
||||
|
||||
```
|
||||
pre-write-checklist:
|
||||
- 加载项目特定文件(你的故事数据)
|
||||
|
||||
setting-detector:
|
||||
- 加载通用知识库(类型惯例、写作技巧)
|
||||
|
||||
两者结合 = 完整context:
|
||||
你的故事设定 + 类型专业知识
|
||||
```
|
||||
|
||||
### Q: 100章的长篇小说也要每次都读吗?
|
||||
|
||||
**A**: 是的,而且**更需要**。
|
||||
|
||||
```
|
||||
长篇小说的挑战:
|
||||
- 设定更复杂
|
||||
- 角色更多
|
||||
- 情节线更多
|
||||
- AI更容易忘记
|
||||
|
||||
检查清单的作用:
|
||||
- 确保第100章和第1章质量一致
|
||||
- 防止角色性格突变
|
||||
- 防止情节自相矛盾
|
||||
|
||||
这是长篇小说质量保证的基石。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 保持文件更新
|
||||
|
||||
检查清单只能确保AI读取文件,但文件内容要准确:
|
||||
|
||||
```
|
||||
✓ 角色状态变化 → 更新 character-state.json
|
||||
✓ 关系变化 → 更新 relationships.json
|
||||
✓ 新情节线 → 更新 plot-tracker.json
|
||||
```
|
||||
|
||||
### 2. 定期运行 `/track`
|
||||
|
||||
```
|
||||
建议频率:每5-10章运行一次 `/track`
|
||||
作用:
|
||||
- 更新tracking文件
|
||||
- 验证一致性
|
||||
- 发现潜在问题
|
||||
```
|
||||
|
||||
### 3. 重要变更后手动触发
|
||||
|
||||
```
|
||||
如果你手动修改了关键文件:
|
||||
"请重新执行检查清单,重新加载所有文件"
|
||||
|
||||
确保AI看到最新状态。
|
||||
```
|
||||
|
||||
### 4. 与consistency-checker配合
|
||||
|
||||
```
|
||||
pre-write-checklist(写前):
|
||||
- 加载所有context
|
||||
- 准备写作
|
||||
|
||||
consistency-checker(写中/写后):
|
||||
- 监控一致性
|
||||
- 发现矛盾
|
||||
```
|
||||
|
||||
双重保障 = 最高质量。
|
||||
|
||||
---
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 文件读取顺序
|
||||
|
||||
```
|
||||
优先级排序(重要的先读):
|
||||
1. constitution(最高原则)
|
||||
2. specification(故事核心)
|
||||
3. creative-plan(技术方案)
|
||||
4. tasks(当前任务)
|
||||
5. character-state(角色数据)
|
||||
6. relationships(关系数据)
|
||||
7. plot-tracker(情节追踪)
|
||||
8. validation-rules(验证规则)
|
||||
9. style-reference(风格参考)
|
||||
```
|
||||
|
||||
### 错误处理
|
||||
|
||||
```
|
||||
文件不存在:
|
||||
→ 必需文件:阻止写作,提示创建
|
||||
→ 可选文件:警告,允许继续
|
||||
|
||||
文件格式错误:
|
||||
→ JSON解析失败:显示错误,建议修复
|
||||
→ Markdown格式问题:尽力读取,标记问题
|
||||
|
||||
文件过大:
|
||||
→ 超过10000行:警告(可能影响性能)
|
||||
→ 建议拆分文件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
pre-write-checklist是Novel Writer Skills v1.0的**核心创新**:
|
||||
|
||||
✓ 解决AI长篇失焦问题
|
||||
✓ 强制重读关键文件
|
||||
✓ 确保context完整性
|
||||
✓ 保持质量长期稳定
|
||||
✓ 适合专业作者长篇创作
|
||||
|
||||
**30章后不再失焦 = 长期竞争力** 🎯
|
||||
|
||||
---
|
||||
|
||||
**本Skill版本**: v1.0
|
||||
**最后更新**: 2025-10-18
|
||||
**核心问题**: 解决30章后AI失焦
|
||||
**配合**: write.md, setting-detector, consistency-checker
|
||||
@@ -1,131 +0,0 @@
|
||||
# 多规范探测与冲突处理
|
||||
|
||||
当探测到多个规范关键词时,需要进行冲突检测并提供解决方案。
|
||||
|
||||
---
|
||||
|
||||
## 兼容组合示例
|
||||
|
||||
### fast-paced + anti-ai-v4
|
||||
|
||||
**用户说**:
|
||||
|
||||
> "我要写爽文,节奏快,而且要去AI味"
|
||||
|
||||
**处理方式**:
|
||||
|
||||
```markdown
|
||||
🔍 多规范探测结果
|
||||
|
||||
检测到:
|
||||
|
||||
- fast-paced(因为"爽文、节奏快")
|
||||
- anti-ai-v4(因为"去AI味")
|
||||
|
||||
这两个规范可以组合使用!
|
||||
|
||||
推荐配置:
|
||||
writing-requirements:
|
||||
|
||||
- fast-paced
|
||||
- anti-ai-v4
|
||||
|
||||
效果:快节奏爽文 + 强力去AI味 = 自然流畅的商业化网文
|
||||
|
||||
确认应用这个组合吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 冲突组合示例
|
||||
|
||||
### serious-literature + fast-paced
|
||||
|
||||
**用户说**:
|
||||
|
||||
> "我要写严肃文学,但也要每章都有爽点"
|
||||
|
||||
**处理方式**:
|
||||
|
||||
```markdown
|
||||
⚠️ 规范冲突检测
|
||||
|
||||
检测到:
|
||||
|
||||
- serious-literature(严肃文学) - 要求慢节奏、深度
|
||||
- fast-paced(快节奏爽文) - 要求每章2个爽点
|
||||
|
||||
这两个规范有根本冲突:
|
||||
|
||||
- 严肃文学:慢节奏、思想性、开放结局
|
||||
- 快节奏爽文:密集冲突、爽感优先、套路化
|
||||
|
||||
建议:
|
||||
|
||||
1. 选择 serious-literature,放弃"每章爽点"要求
|
||||
2. 选择 fast-paced,调整为"有深度的爽文"
|
||||
3. 考虑使用 strong-emotion(强情绪)作为折中
|
||||
|
||||
你倾向哪个方向?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### romance-sweet + romance-angst
|
||||
|
||||
**用户说**:
|
||||
|
||||
> "我要写甜文,但也要虐一下"
|
||||
|
||||
**处理方式**:
|
||||
|
||||
```markdown
|
||||
⚠️ 甜虐冲突检测
|
||||
|
||||
检测到:
|
||||
|
||||
- romance-sweet(甜文) - 禁止长时间虐
|
||||
- romance-angst(虐文) - 需要虐心情节
|
||||
|
||||
建议处理方式:
|
||||
|
||||
1. **先甜后虐**(虐恋)
|
||||
- 前半部分:romance-sweet
|
||||
- 后半部分:romance-angst
|
||||
|
||||
2. **虐中带甜**(微虐)
|
||||
- 主要:romance-sweet
|
||||
- 允许:短暂小虐(1-2章)
|
||||
- 甜虐比例:80% 甜 / 20% 虐
|
||||
|
||||
3. **BE甜文**(先甜后刀)
|
||||
- 前期:romance-sweet
|
||||
- 结局:romance-angst(BE)
|
||||
|
||||
你想要哪种模式?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 冲突矩阵
|
||||
|
||||
| 组合 | 兼容性 | 说明 |
|
||||
| ---------------------------------- | ------- | ------------------ |
|
||||
| anti-ai-v4 + fast-paced | ✅ 兼容 | 极致自然的爽文 |
|
||||
| anti-ai-v4 + no-poison | ✅ 兼容 | 自然且逻辑合理 |
|
||||
| anti-ai-v4 + romance-sweet | ✅ 兼容 | 自然的甜文 |
|
||||
| fast-paced + no-poison | ✅ 兼容 | 合理的爽文 |
|
||||
| fast-paced + strong-emotion | ✅ 兼容 | 情绪饱满的爽文 |
|
||||
| serious-literature + fast-paced | ❌ 冲突 | 慢节奏 vs 快节奏 |
|
||||
| serious-literature + romance-sweet | ⚠️ 谨慎 | 可以尝试,但需平衡 |
|
||||
| romance-sweet + romance-angst | ❌ 冲突 | 甜 vs 虐 |
|
||||
|
||||
---
|
||||
|
||||
## 处理原则
|
||||
|
||||
1. **优先用户意图**:尊重用户明确表达的偏好
|
||||
2. **提供选项**:遇到冲突时给出解决方案
|
||||
3. **解释原因**:说明为什么冲突
|
||||
4. **支持组合**:对于兼容的组合,鼓励使用
|
||||
5. **允许调整**:支持中途切换规范
|
||||
@@ -1,153 +0,0 @@
|
||||
# 完整对话示例和成功案例
|
||||
|
||||
本文档展示 requirement-detector 在实际使用中的完整对话流程。
|
||||
|
||||
---
|
||||
|
||||
## 示例 1:基础规范探测
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写现代言情,甜文,但不能有AI味"
|
||||
|
||||
**requirement-detector 响应**:
|
||||
|
||||
```
|
||||
📋 规范探测器已激活
|
||||
|
||||
检测到关键词:
|
||||
- "甜文" → romance-sweet
|
||||
- "不能有AI味" → anti-ai-v4
|
||||
|
||||
建议规范组合:
|
||||
1. romance-sweet(甜文规范)
|
||||
2. anti-ai-v4(强力AI去味)
|
||||
|
||||
✅ 已加载规范文档
|
||||
✅ 已写入配置:
|
||||
writing-requirements:
|
||||
- romance-sweet
|
||||
- anti-ai-v4
|
||||
|
||||
配合建议:
|
||||
💡 检测到"现代言情",建议同时激活
|
||||
style-detector 选择 natural-voice 风格。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 2:与 style-detector 协同
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写都市爽文,口语化,去AI味"
|
||||
|
||||
**system(两个detector协同)**:
|
||||
|
||||
```
|
||||
🎨 style-detector 已激活
|
||||
检测到:口语化 → natural-voice
|
||||
|
||||
📋 requirement-detector 已激活
|
||||
检测到:爽文 → fast-paced
|
||||
检测到:去AI味 → anti-ai-v4
|
||||
|
||||
✅ 推荐配置组合:
|
||||
|
||||
风格层:natural-voice
|
||||
规范层:fast-paced + anti-ai-v4
|
||||
|
||||
最终效果:
|
||||
自然口语化的快节奏爽文,强力去AI味
|
||||
|
||||
已写入配置:
|
||||
---
|
||||
writing-style: natural-voice
|
||||
writing-requirements:
|
||||
- fast-paced
|
||||
- anti-ai-v4
|
||||
---
|
||||
|
||||
这个组合特别适合你的需求,确认应用吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 3:冲突处理
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写严肃文学,但也要每章都有爽点"
|
||||
|
||||
**requirement-detector 响应**:
|
||||
|
||||
```
|
||||
⚠️ 规范冲突检测
|
||||
|
||||
检测到:
|
||||
- serious-literature(因为"严肃文学")
|
||||
- fast-paced(因为"每章都有爽点")
|
||||
|
||||
这两个规范有根本冲突:
|
||||
- 严肃文学:慢节奏、思想性
|
||||
- 快节奏爽文:密集冲突、爽感优先
|
||||
|
||||
建议:
|
||||
1. 选择 serious-literature,调整"爽点"为"情感高潮点"
|
||||
→ 可以使用 strong-emotion 代替 fast-paced
|
||||
2. 选择 fast-paced,调整为"有深度的爽文"
|
||||
→ 降低爽点密度,增加思想性
|
||||
|
||||
你倾向哪个方向?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 4:主动建议
|
||||
|
||||
**用户已经选择了 natural-voice 风格**
|
||||
|
||||
**requirement-detector 主动建议**:
|
||||
|
||||
```
|
||||
💡 规范建议
|
||||
|
||||
检测到你选择了 natural-voice(自然人声风格)
|
||||
|
||||
建议配套规范:
|
||||
1. **anti-ai-v4** - 与 natural-voice 完美配合,极致自然
|
||||
2. **no-poison** - 保证逻辑合理,避免降智
|
||||
3. **fast-paced**(可选) - 如果写商业化爽文
|
||||
|
||||
推荐组合:
|
||||
natural-voice + anti-ai-v4 + no-poison
|
||||
= 极致自然、逻辑自洽的现代小说
|
||||
|
||||
需要我加载这些规范吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用技巧
|
||||
|
||||
1. **明确需求**:说清楚你要什么效果(爽文、虐文、去AI味等)
|
||||
2. **信任探测**:探测器会基于经验给出推荐
|
||||
3. **组合使用**:多个兼容的规范可以叠加
|
||||
4. **注意冲突**:遇到冲突时,选择最重要的需求
|
||||
5. **配合风格**:规范(requirement)+ 风格(style)效果更好
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q:可以同时使用多个规范吗?**
|
||||
A:可以,但要注意兼容性。参考 [CONFLICT_RESOLUTION.md](CONFLICT_RESOLUTION.md)。
|
||||
|
||||
**Q:anti-ai-v4 和 anti-ai-v3 有什么区别?**
|
||||
A:v4 是强力版本,限制更严格;v3 是标准版本,更平衡。
|
||||
|
||||
**Q:爽文规范会影响文学性吗?**
|
||||
A:fast-paced 强调节奏和爽点,与 serious-literature 有冲突。但可以和 literary 风格配合。
|
||||
|
||||
**Q:甜文和虐文能混合吗?**
|
||||
A:不推荐,但可以分阶段使用(先甜后虐)。详见 CONFLICT_RESOLUTION.md。
|
||||
@@ -1,178 +0,0 @@
|
||||
# 写作规范关键词详细列表
|
||||
|
||||
本文档包含所有可探测规范的详细关键词列表、触发场景示例和激活后行为模板。
|
||||
|
||||
---
|
||||
|
||||
## 1. anti-ai-v4(强力AI去味)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
AI味重、AI腔太重、太AI了
|
||||
去AI味、去除AI感、不要AI味
|
||||
太机器、太生硬、不自然
|
||||
AI痕迹明显、一看就是AI写的
|
||||
要求极致自然、完全去AI
|
||||
最强去味、强力去AI
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"这个AI味道太重了,能不能去掉?"
|
||||
> 用户:"我要最强的AI去味,完全看不出AI写的那种"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
📋 规范探测器已激活
|
||||
|
||||
检测到:【AI味重、去AI味】
|
||||
|
||||
建议使用:**anti-ai-v4**(强力AI去味规范)
|
||||
|
||||
这个规范的特点:
|
||||
|
||||
- 200+ 禁用词汇表
|
||||
- 6层规则体系(词汇、句式、形容词、成语、对话、段落)
|
||||
- 极致的自然化要求
|
||||
|
||||
⚠️ 警告:这是最激进的去AI规范,可能会牺牲部分文学性
|
||||
|
||||
想要查看详细的规范文档吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. anti-ai-v3(标准AI去味)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
自然一点、不要太生硬
|
||||
少一点AI感、适度去AI
|
||||
正常的去AI就行、标准去味
|
||||
不要太明显、平衡一下
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"去掉AI味就行,不用太极端"
|
||||
> 用户:"适度自然一点,保持可读性"
|
||||
|
||||
---
|
||||
|
||||
## 3. fast-paced(快节奏/爽文规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
节奏快、快节奏、爽文、爽点
|
||||
打脸、装逼、升级、逆袭
|
||||
冲突密集、不拖沓、干脆利落
|
||||
每章都要有爽点、要爽
|
||||
网文节奏、商业化节奏
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我要写爽文,每章都要有爽点"
|
||||
> 用户:"节奏快一点,不要拖沓"
|
||||
|
||||
---
|
||||
|
||||
## 4. no-poison(无毒点规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
无毒点、不要毒点、避免毒
|
||||
不要降智、别让主角傻
|
||||
不要圣母、不要工具人
|
||||
逻辑自洽、合理、不强行
|
||||
不要为了剧情牺牲智商
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"千万不要降智,主角别太傻"
|
||||
> 用户:"要合理,不要强行的剧情"
|
||||
|
||||
---
|
||||
|
||||
## 5. serious-literature(严肃文学规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
严肃文学、纯文学、文学性
|
||||
有深度、思想性、哲思
|
||||
现实主义、人性探讨
|
||||
不要爽文套路、要有内涵
|
||||
社会问题、深刻、有意义
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我要写严肃文学,有思想深度的"
|
||||
> 用户:"不要爽文那套,要探讨人性"
|
||||
|
||||
---
|
||||
|
||||
## 6. strong-emotion(强情绪规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
情绪饱满、情感强烈、有感染力
|
||||
情绪爆发、情绪冲击、催泪
|
||||
让人有共鸣、打动人心
|
||||
有情感张力、情绪起伏大
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我要写得情感饱满,能打动人"
|
||||
> 用户:"需要强烈的情绪冲击"
|
||||
|
||||
---
|
||||
|
||||
## 7. romance-sweet(甜文规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
甜文、甜、撒糖、高糖
|
||||
齁甜、甜到发腻、甜宠
|
||||
HE、圆满、温馨
|
||||
不虐、少虐、轻松
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我要写甜文,多撒糖"
|
||||
> 用户:"全程高糖,不要虐"
|
||||
|
||||
---
|
||||
|
||||
## 8. romance-angst(虐文规范)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
虐文、虐、BE、刀子
|
||||
虐心、虐恋、悲剧
|
||||
误会虐、分离虐、时机虐
|
||||
重虐、极虐、生离死别
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我要写虐文,虐得痛快"
|
||||
> 用户:"BE结局,生离死别那种"
|
||||
|
||||
---
|
||||
|
||||
## 使用说明
|
||||
|
||||
当用户提到任何上述关键词时,按照对应的激活后行为模板与用户交互。
|
||||
@@ -1,157 +0,0 @@
|
||||
---
|
||||
name: requirement-detector
|
||||
description: "探测用户的写作规范需求并加载对应文档。当用户提到AI味重、去AI味、自然、爽文、快节奏、爽点、无毒点、不降智、严肃文学、有深度、强情绪、打动人、甜文、撒糖、虐文、虐心、BE等关键词时自动激活。适用于讨论写作要求、AI去味方法、节奏控制、情感表达时使用。"
|
||||
allowed-tools: Read, Edit
|
||||
---
|
||||
|
||||
# 写作规范探测器
|
||||
|
||||
## 核心功能
|
||||
|
||||
自动探测用户的写作规范需求,并无缝加载对应的规范知识库。
|
||||
|
||||
## 可探测的规范
|
||||
|
||||
### 1. anti-ai-v4(强力AI去味)
|
||||
|
||||
- **适合**:对AI味零容忍的作品、需要极致口语化的小说
|
||||
- **特点**:200+ 禁用词汇表、6层规则体系、极致自然化
|
||||
- **触发词**:AI味重、去AI味、太机器、不自然、最强去味
|
||||
|
||||
### 2. anti-ai-v3(标准AI去味)
|
||||
|
||||
- **适合**:大部分现代小说、需要平衡自然感和文学性
|
||||
- **特点**:平衡的去AI策略、适度的词汇限制
|
||||
- **触发词**:自然一点、少一点AI感、适度去AI、标准去味
|
||||
|
||||
### 3. fast-paced(快节奏/爽文规范)
|
||||
|
||||
- **适合**:都市爽文、玄幻升级流、系统文、重生文
|
||||
- **特点**:每章至少2个爽点、打脸/装逼/升级公式
|
||||
- **触发词**:爽文、快节奏、爽点、打脸、装逼、升级
|
||||
|
||||
### 4. no-poison(无毒点规范)
|
||||
|
||||
- **适合**:所有类型小说(通用)、重视逻辑性的作品
|
||||
- **特点**:避免降智、强行误会、玛丽苏、工具人、逻辑漏洞
|
||||
- **触发词**:无毒点、不降智、逻辑自洽、合理、不强行
|
||||
|
||||
### 5. serious-literature(严肃文学规范)
|
||||
|
||||
- **适合**:现实主义小说、历史小说、社会问题小说
|
||||
- **特点**:现实主义手法、思想性和哲学探讨、语言克制
|
||||
- **触发词**:严肃文学、纯文学、有深度、思想性、人性探讨
|
||||
|
||||
### 6. strong-emotion(强情绪规范)
|
||||
|
||||
- **适合**:情感类小说、虐文、需要感染力的作品
|
||||
- **特点**:每10-15章至少1个情绪爆发点、波浪式情绪节奏
|
||||
- **触发词**:情绪饱满、情感强烈、有感染力、打动人心
|
||||
|
||||
### 7. romance-sweet(甜文规范)
|
||||
|
||||
- **适合**:言情甜文、现代甜宠、轻松向恋爱故事
|
||||
- **特点**:糖分密度配置、冲突控制、禁止BE倾向
|
||||
- **触发词**:甜文、撒糖、高糖、齁甜、甜宠、HE
|
||||
|
||||
### 8. romance-angst(虐文规范)
|
||||
|
||||
- **适合**:虐恋小说、悲剧向爱情、刀子文
|
||||
- **特点**:虐要有理有度、虐点设计、虐度等级控制
|
||||
- **触发词**:虐文、虐心、BE、刀子、分离虐、时机虐
|
||||
|
||||
详细关键词列表和触发场景请参阅 [KEYWORDS.md](KEYWORDS.md)。
|
||||
|
||||
---
|
||||
|
||||
## 激活后的工作流程
|
||||
|
||||
### 步骤 1:确认规范选择
|
||||
|
||||
当探测到关键词后,首先确认用户意图:
|
||||
|
||||
```
|
||||
我注意到你提到了【AI味重、去AI味】,这通常对应 anti-ai-v4 规范。
|
||||
|
||||
我可以:
|
||||
1. 📖 展示这个规范的详细文档
|
||||
2. ✅ 直接应用这个规范到你的项目
|
||||
3. 🔍 看看其他规范选项
|
||||
|
||||
你想要哪一个?
|
||||
```
|
||||
|
||||
### 步骤 2:加载规范知识库
|
||||
|
||||
如果用户确认,使用 Read 工具读取对应的知识库文件:
|
||||
|
||||
```
|
||||
📖 读取:.claude/knowledge-base/requirements/{requirement-name}.md
|
||||
```
|
||||
|
||||
然后展示核心要点,完整规范已加载到上下文中。
|
||||
|
||||
### 步骤 3:写入配置标记
|
||||
|
||||
使用 Edit 工具在用户的 `specification.md` 中添加配置:
|
||||
|
||||
```yaml
|
||||
---
|
||||
writing-requirements:
|
||||
- anti-ai-v4
|
||||
- fast-paced
|
||||
---
|
||||
```
|
||||
|
||||
提示用户配置已保存,在执行 /write 时会自动遵守这些规范。
|
||||
|
||||
---
|
||||
|
||||
## 多规范处理
|
||||
|
||||
当探测到多个规范关键词时,进行兼容性检测:
|
||||
|
||||
- **兼容组合**:自动组合并说明综合效果
|
||||
- **冲突组合**:提示矛盾并给出解决方案
|
||||
|
||||
详细的冲突处理逻辑请参阅 [CONFLICT_RESOLUTION.md](CONFLICT_RESOLUTION.md)。
|
||||
|
||||
---
|
||||
|
||||
## 主动建议
|
||||
|
||||
- **基于风格建议规范**:如果 style-detector 已激活,主动推荐配套规范
|
||||
- **中途调整支持**:持续监控用户反馈,支持规范调整
|
||||
|
||||
---
|
||||
|
||||
## 与 style-detector 的配合
|
||||
|
||||
本 Skill 专注于规范层面,与 style-detector(文风层)协同工作:
|
||||
|
||||
```
|
||||
用户输入:"我要写都市爽文,口语化,去AI味"
|
||||
|
||||
style-detector → 识别:natural-voice
|
||||
requirement-detector → 识别:fast-paced + anti-ai-v4
|
||||
|
||||
最终配置:
|
||||
writing-style: natural-voice
|
||||
writing-requirements:
|
||||
- fast-paced
|
||||
- anti-ai-v4
|
||||
|
||||
效果:自然人声的快节奏爽文,强力去AI味
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
完整的对话示例和成功案例请参阅 [EXAMPLES.md](EXAMPLES.md)。
|
||||
|
||||
---
|
||||
|
||||
**Skill 版本**:v1.1
|
||||
**最后更新**:2025-10-19
|
||||
**兼容版本**:novel-writer-skills v1.0.5+
|
||||
@@ -1,597 +0,0 @@
|
||||
---
|
||||
name: setting-detector
|
||||
description: "基于关键词自动检测故事设定(类型、时代、主题)并激活相应的知识库 - 在后台静默工作,无需用户干预即可提供相关写作指导"
|
||||
allowed-tools: Read
|
||||
---
|
||||
|
||||
# 故事设定自动检测器
|
||||
|
||||
## 核心功能
|
||||
|
||||
**自动激活知识库系统** - 这是Novel Writer Skills的核心竞争力。
|
||||
|
||||
当你提到特定关键词时,我会自动:
|
||||
|
||||
1. 检测故事的类型、时代、主题
|
||||
2. 加载对应的写作知识库
|
||||
3. 在整个创作过程中应用专业知识
|
||||
|
||||
**无需手动调用** - 完全自动化,后台运行。
|
||||
|
||||
---
|
||||
|
||||
## 工作原理
|
||||
|
||||
### 关键词映射表
|
||||
|
||||
我监听以下关键词并自动激活对应知识库:
|
||||
|
||||
#### 类型知识库(Genres)
|
||||
|
||||
**言情小说**(romance):
|
||||
|
||||
```
|
||||
触发词:言情、爱情、恋爱、浪漫、感情线、关系弧、CP、甜文、虐文、
|
||||
HE、BE、双洁、破镜重圆、先婚后爱、契约关系
|
||||
|
||||
激活:templates/knowledge-base/genres/romance.md
|
||||
```
|
||||
|
||||
**悬疑推理**(mystery):
|
||||
|
||||
```
|
||||
触发词:悬疑、推理、侦探、破案、谜团、线索、真相、凶手、犯罪、
|
||||
密室、诡计、不在场证明、推理小说
|
||||
|
||||
激活:templates/knowledge-base/genres/mystery.md
|
||||
```
|
||||
|
||||
**历史小说**(historical):
|
||||
|
||||
```
|
||||
触发词:历史、古代、朝代、考据、时代背景、历史小说、古言、
|
||||
穿越、重生古代、架空历史、宫斗、宅斗
|
||||
|
||||
激活:templates/knowledge-base/genres/historical.md
|
||||
```
|
||||
|
||||
**复仇爽文**(revenge):
|
||||
|
||||
```
|
||||
触发词:复仇、报仇、打脸、爽文、逆袭、反击、重生复仇、
|
||||
穿越复仇、系统、金手指、女主爽文、男主爽文
|
||||
|
||||
激活:templates/knowledge-base/genres/revenge.md
|
||||
```
|
||||
|
||||
**武侠小说**(wuxia):
|
||||
|
||||
```
|
||||
触发词:武侠、江湖、武功、侠客、门派、武学、剑客、
|
||||
轻功、内功、武林、江湖恩仇、侠义
|
||||
|
||||
激活:templates/knowledge-base/genres/wuxia.md
|
||||
```
|
||||
|
||||
#### 参考资料库(References)
|
||||
|
||||
**1920年代中国**(china-1920s):
|
||||
|
||||
```
|
||||
触发词:1920、民国、军阀、北洋、穿越民国、二十年代、
|
||||
民国时期、军阀混战
|
||||
|
||||
激活:templates/knowledge-base/references/china-1920s/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 自动激活流程
|
||||
|
||||
### 示例1:单一类型检测
|
||||
|
||||
```
|
||||
用户:"我要写一部言情小说"
|
||||
↓
|
||||
[检测到关键词:"言情"]
|
||||
↓
|
||||
✓ 自动加载:romance.md
|
||||
↓
|
||||
AI回复:"太好了!让我帮你创作言情小说。
|
||||
根据言情类型惯例,我们需要明确几个核心元素...
|
||||
(自动应用romance.md中的知识)"
|
||||
```
|
||||
|
||||
### 示例2:多类型组合检测
|
||||
|
||||
```
|
||||
用户:"我要写一部1920年代的言情复仇小说"
|
||||
↓
|
||||
[检测到关键词:"1920"、"言情"、"复仇"]
|
||||
↓
|
||||
✓ 自动加载:romance.md
|
||||
✓ 自动加载:revenge.md
|
||||
✓ 自动加载:references/china-1920s/
|
||||
↓
|
||||
📚 已激活知识库:
|
||||
- genres/romance.md(言情小说惯例)
|
||||
- genres/revenge.md(复仇爽文技巧)
|
||||
- references/china-1920s/(1920年代背景)
|
||||
↓
|
||||
AI回复:"很好的组合!这是浪漫悬疑+复仇+民国背景。
|
||||
根据这三个类型的融合,建议...
|
||||
(同时应用三个知识库的内容)"
|
||||
```
|
||||
|
||||
### 示例3:创作过程中的持续应用
|
||||
|
||||
```
|
||||
/constitution 阶段:
|
||||
→ 已激活:romance.md
|
||||
→ 提醒:言情小说需要HEA/HFN结局承诺
|
||||
|
||||
/specify 阶段:
|
||||
→ 已激活:romance.md + revenge.md
|
||||
→ 建议:定义关系弧线+复仇目标
|
||||
|
||||
/plan 阶段:
|
||||
→ 已激活:所有知识库
|
||||
→ 应用:情感节奏点+打脸节奏+1920年代细节
|
||||
|
||||
/write 阶段:
|
||||
→ 已激活:所有知识库
|
||||
→ 实时:对话技巧+场景描写+时代氛围
|
||||
|
||||
/analyze 阶段:
|
||||
→ 已激活:所有知识库
|
||||
→ 检查:言情惯例+复仇合理性+历史准确性
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Token效率优化
|
||||
|
||||
**为什么这个系统高效?**
|
||||
|
||||
传统方案(superpowers-skills模式):
|
||||
|
||||
```
|
||||
50个独立Skills × 每个40行SKILL.md = 2000 tokens
|
||||
每次对话都加载所有Skills
|
||||
```
|
||||
|
||||
我们的方案(分层知识库+检测器):
|
||||
|
||||
```
|
||||
1个detector Skill(本文件):~100 tokens
|
||||
按需加载知识库:
|
||||
- romance.md:~520 tokens
|
||||
- revenge.md:~480 tokens
|
||||
- china-1920s/:~650 tokens
|
||||
|
||||
总计:100 + 520 + 480 + 650 = ~1750 tokens
|
||||
(仅加载相关知识库)
|
||||
```
|
||||
|
||||
**节省75%** vs 加载50个无关Skills
|
||||
|
||||
---
|
||||
|
||||
## 手动控制
|
||||
|
||||
### 查看当前激活的知识库
|
||||
|
||||
随时询问:
|
||||
|
||||
```
|
||||
"当前激活了哪些知识库?"
|
||||
```
|
||||
|
||||
我会回复:
|
||||
|
||||
```
|
||||
📚 当前激活的知识库:
|
||||
✓ genres/romance.md - 言情小说创作惯例
|
||||
✓ genres/revenge.md - 复仇爽文打脸技巧
|
||||
✓ references/china-1920s/ - 1920年代中国参考资料
|
||||
|
||||
Token消耗:约1650 tokens
|
||||
```
|
||||
|
||||
### 手动激活知识库
|
||||
|
||||
如果自动检测失败,可以明确指定:
|
||||
|
||||
```
|
||||
"请加载 romance 和 mystery 知识库"
|
||||
"这个故事需要 1920s 中国参考资料"
|
||||
"激活武侠知识库"
|
||||
```
|
||||
|
||||
### 停用知识库
|
||||
|
||||
如果某个知识库不需要了:
|
||||
|
||||
```
|
||||
"停用 revenge 知识库,这个故事不涉及复仇"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与Commands集成
|
||||
|
||||
### `/constitution` - 类型特定原则
|
||||
|
||||
根据激活的知识库,提供类型特定的创作原则:
|
||||
|
||||
```markdown
|
||||
【自动插入到constitution中】
|
||||
|
||||
## 类型特定原则(由setting-detector自动添加)
|
||||
|
||||
### 言情小说核心原则
|
||||
|
||||
1. 关系弧线是主情节
|
||||
2. HEA/HFN结局是必须的
|
||||
3. 化学反应真实可信
|
||||
|
||||
### 复仇爽文核心原则
|
||||
|
||||
1. 仇恨必须深刻具体
|
||||
2. 打脸节奏渐进式
|
||||
3. 道德平衡:罪有应得
|
||||
```
|
||||
|
||||
### `/specify` - 类型特定规格
|
||||
|
||||
提供对应的规格模板元素:
|
||||
|
||||
```markdown
|
||||
【自动提示】
|
||||
|
||||
💡 根据已激活的知识库,建议在规格中定义:
|
||||
|
||||
【来自romance.md】
|
||||
|
||||
- 关系弧线设定
|
||||
- 情感节奏点规划
|
||||
- HEA/HFN结局类型
|
||||
|
||||
【来自revenge.md】
|
||||
|
||||
- 仇恨来源(具体罪行)
|
||||
- 金手指设定
|
||||
- 打脸节奏规划
|
||||
|
||||
【来自china-1920s】
|
||||
|
||||
- 具体年份(1920-1929)
|
||||
- 地理位置(北京/上海/其他)
|
||||
- 社会阶层设定
|
||||
```
|
||||
|
||||
### `/plan` - 类型知识融合
|
||||
|
||||
将多个知识库的建议融合到计划中:
|
||||
|
||||
```markdown
|
||||
【自动应用】
|
||||
|
||||
## 章节规划(融合3个知识库)
|
||||
|
||||
第1-5章:相遇与仇恨建立
|
||||
|
||||
- [romance] 初次相遇场景(meet-cute)
|
||||
- [revenge] 展示前世/过去的深仇大恨
|
||||
- [1920s] 民国时代氛围营造
|
||||
|
||||
第6-10章:关系升温与小打脸
|
||||
|
||||
- [romance] 暧昧期:肢体接触、情感积累
|
||||
- [revenge] 第一次打脸:仇人惊讶
|
||||
- [1920s] 服饰、礼仪、社会规则展现
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### `/write` - 实时写作指导
|
||||
|
||||
写作时自动应用相关知识:
|
||||
|
||||
```markdown
|
||||
【写作前自动提醒】
|
||||
|
||||
📋 本章应用的知识库:
|
||||
|
||||
✓ romance.md - 对话火花技巧
|
||||
→ 调情对话:挑战而非顺从
|
||||
→ 肢体语言:眼神、触碰、距离
|
||||
|
||||
✓ revenge.md - 打脸场景爽感
|
||||
→ 期待 → 反转 → 惊愕 → 霸气
|
||||
|
||||
✓ 1920s - 时代细节
|
||||
→ 称呼:大人、老爷、小姐
|
||||
→ 场景:茶馆、洋行、租界
|
||||
```
|
||||
|
||||
### `/analyze` - 类型惯例检查
|
||||
|
||||
根据激活的知识库执行对应检查:
|
||||
|
||||
```markdown
|
||||
【自动分析】
|
||||
|
||||
## 类型符合度分析
|
||||
|
||||
### 言情小说检查(基于romance.md)
|
||||
|
||||
- [x] 关系弧线是主情节
|
||||
- [x] 包含必备情感节奏点
|
||||
- [ ] ⚠️ 缺少初吻场景(建议在第15章)
|
||||
- [x] HEA结局承诺明确
|
||||
|
||||
### 复仇爽文检查(基于revenge.md)
|
||||
|
||||
- [x] 仇恨深刻具体
|
||||
- [x] 打脸频率合理(每5章1次)
|
||||
- [x] 主角实力提升合理
|
||||
|
||||
### 历史准确性检查(基于1920s)
|
||||
|
||||
- [x] 时代背景正确
|
||||
- [ ] ⚠️ 第8章出现"手机"(时代不符)
|
||||
- [x] 称呼系统正确
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 知识库扩展
|
||||
|
||||
### 当前支持的知识库
|
||||
|
||||
| 类别 | 已完成 | 计划中 |
|
||||
| -------- | ------ | ------ |
|
||||
| 类型知识 | 5个 | 10+ |
|
||||
| 参考资料 | 1个 | 20+ |
|
||||
|
||||
**已完成**(v1.0):
|
||||
|
||||
- genres/romance.md
|
||||
- genres/mystery.md
|
||||
- genres/historical.md
|
||||
- genres/revenge.md
|
||||
- genres/wuxia.md
|
||||
- references/china-1920s/
|
||||
|
||||
**计划中**(v1.1+):
|
||||
|
||||
- genres/fantasy.md(奇幻)
|
||||
- genres/sci-fi.md(科幻)
|
||||
- genres/horror.md(恐怖)
|
||||
- references/ancient-china/(各朝代)
|
||||
- references/modern-workplace/(现代职场)
|
||||
|
||||
### 添加新知识库
|
||||
|
||||
1. 在`templates/knowledge-base/`对应目录创建文件
|
||||
2. 更新`templates/knowledge-base/README.md`的关键词映射表
|
||||
3. setting-detector会自动识别(无需修改本文件)
|
||||
|
||||
**示例**:添加奇幻知识库
|
||||
|
||||
```bash
|
||||
# 1. 创建文件
|
||||
touch templates/knowledge-base/genres/fantasy.md
|
||||
|
||||
# 2. 更新README.md关键词映射
|
||||
fantasy:
|
||||
keywords: [奇幻, 魔法, 世界构建, 魔法系统]
|
||||
auto_load: genres/fantasy.md
|
||||
|
||||
# 3. 完成!下次用户说"奇幻"就会自动激活
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 智能特性
|
||||
|
||||
### 1. 模糊匹配
|
||||
|
||||
即使不是精确关键词也能识别:
|
||||
|
||||
```
|
||||
"我想写个穿越到民国的复仇故事"
|
||||
↓
|
||||
识别:"民国" → 1920s中国
|
||||
"复仇" → revenge
|
||||
|
||||
"女主重生后要报仇"
|
||||
↓
|
||||
识别:"重生" + "报仇" → revenge(重生复仇)
|
||||
```
|
||||
|
||||
### 2. 上下文理解
|
||||
|
||||
根据对话上下文持续识别:
|
||||
|
||||
```
|
||||
第1条消息:"我要写小说"
|
||||
→ 未激活任何知识库(等待更多信息)
|
||||
|
||||
第2条消息:"主角是侦探"
|
||||
→ 激活mystery.md
|
||||
|
||||
第3条消息:"还有感情线"
|
||||
→ 额外激活romance.md
|
||||
|
||||
→ 当前激活:mystery + romance(浪漫悬疑)
|
||||
```
|
||||
|
||||
### 3. 自动去重
|
||||
|
||||
避免重复激活:
|
||||
|
||||
```
|
||||
用户:"这是武侠小说,江湖背景,有武功"
|
||||
↓
|
||||
识别到3个武侠关键词,但只激活1次wuxia.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 我怎么知道哪个知识库被激活了?
|
||||
|
||||
**A**: 随时问我"当前激活了哪些知识库?",我会列出清单。
|
||||
|
||||
### Q: 自动检测错了怎么办?
|
||||
|
||||
**A**: 直接告诉我:
|
||||
|
||||
```
|
||||
"这不是言情小说,请停用romance知识库"
|
||||
"这是科幻小说,请激活sci-fi知识库"(如果已有)
|
||||
```
|
||||
|
||||
### Q: 能同时激活多少个知识库?
|
||||
|
||||
**A**: 理论上无限,但建议3-5个最优:
|
||||
|
||||
- 太少:指导不够全面
|
||||
- 太多:token消耗大,可能冲突
|
||||
|
||||
实际经验:3个知识库(如romance + revenge + 1920s)已经很丰富。
|
||||
|
||||
### Q: 知识库会冲突吗?
|
||||
|
||||
**A**: 不会!知识库设计为协同工作:
|
||||
|
||||
- romance + mystery = 浪漫悬疑✓
|
||||
- fantasy + romance = 奇幻言情✓
|
||||
- historical + revenge = 古代复仇✓
|
||||
|
||||
### Q: 什么时候应该手动指定知识库?
|
||||
|
||||
**A**: 当:
|
||||
|
||||
- 使用了非常专业的术语(我可能没识别)
|
||||
- 想尝试不同类型的融合
|
||||
- 自动检测和你的意图不符
|
||||
|
||||
### Q: 知识库会一直激活吗?
|
||||
|
||||
**A**: 是的,直到:
|
||||
|
||||
- 你明确说"停用XX知识库"
|
||||
- 或开始新的对话
|
||||
- 或切换到完全不同的故事
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 在创作初期明确类型
|
||||
|
||||
```
|
||||
推荐做法:
|
||||
用户:"我要写一部民国背景的复仇言情小说"
|
||||
|
||||
不推荐:
|
||||
用户:"我要写小说"
|
||||
AI:"好的"
|
||||
用户:"主角姓李"
|
||||
AI:"嗯"
|
||||
(20轮对话后才提到是什么类型)
|
||||
```
|
||||
|
||||
### 2. 定期检查激活状态
|
||||
|
||||
每5-10章问一次:
|
||||
|
||||
```
|
||||
"当前激活的知识库还适合吗?"
|
||||
```
|
||||
|
||||
我会检查并建议是否需要调整。
|
||||
|
||||
### 3. 类型融合要合理
|
||||
|
||||
```
|
||||
✓ 好的组合:
|
||||
- romance + mystery(浪漫悬疑)
|
||||
- historical + romance(古言)
|
||||
- revenge + romance(复仇+感情)
|
||||
|
||||
⚠️ 困难的组合:
|
||||
- horror + romance(恐怖言情?读者可能不适应)
|
||||
- mystery + wuxia(推理武侠,需要特殊设计)
|
||||
|
||||
不是不能做,但需要特别小心融合方式。
|
||||
```
|
||||
|
||||
### 4. 利用参考资料
|
||||
|
||||
如果故事有明确时代背景,一定激活对应参考资料:
|
||||
|
||||
```
|
||||
"1920年代" → china-1920s
|
||||
"古代" → 指定具体朝代(如"唐代"、"明朝")
|
||||
```
|
||||
|
||||
历史细节准确,读者沉浸感强。
|
||||
|
||||
---
|
||||
|
||||
## 技术说明
|
||||
|
||||
### 检测算法
|
||||
|
||||
```
|
||||
1. 用户输入 → 提取关键词
|
||||
2. 关键词 → 映射到知识库(基于README.md)
|
||||
3. 去重 → 避免重复激活
|
||||
4. 加载 → Read相应的.md文件
|
||||
5. 应用 → 在后续对话中持续应用知识
|
||||
```
|
||||
|
||||
### Token管理
|
||||
|
||||
```
|
||||
激活状态检查:每次对话开始时
|
||||
知识库内容:按需加载,缓存在对话上下文中
|
||||
更新策略:只在明确需要时重新读取
|
||||
```
|
||||
|
||||
### 与其他Skills协作
|
||||
|
||||
setting-detector是"知识调度器",其他Skills是"执行者":
|
||||
|
||||
```
|
||||
setting-detector → 决定加载哪些知识
|
||||
consistency-checker → 基于激活的知识库检查一致性
|
||||
workflow-guide → 根据类型提供特定流程指导
|
||||
genre-specific skills → 提供类型特定的深度技巧
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
setting-detector是Novel Writer Skills的**大脑**:
|
||||
|
||||
✓ 自动检测故事设定
|
||||
✓ 智能激活对应知识库
|
||||
✓ Token高效(按需加载)
|
||||
✓ 持续应用专业知识
|
||||
✓ 无需用户干预
|
||||
|
||||
**让AI自动成为你故事类型的专家!** 🧠✨
|
||||
|
||||
---
|
||||
|
||||
**本Skill版本**: v1.0
|
||||
**最后更新**: 2025-10-18
|
||||
**依赖**: templates/knowledge-base/ 系统
|
||||
**协作**: consistency-checker, workflow-guide, genre-specific skills
|
||||
@@ -1,140 +0,0 @@
|
||||
# 多风格探测与冲突处理
|
||||
|
||||
当探测到多个风格关键词时,需要进行冲突检测并提供解决方案。
|
||||
|
||||
---
|
||||
|
||||
## 场景 1:兼容的组合
|
||||
|
||||
### 示例:natural-voice + literary
|
||||
|
||||
**用户说**:
|
||||
|
||||
> "我要写都市小说,口语化一点,但也要有点文学性"
|
||||
|
||||
**探测结果**:
|
||||
|
||||
- natural-voice(口语化)
|
||||
- literary(文学性)
|
||||
|
||||
**处理方式**:
|
||||
|
||||
```markdown
|
||||
🔍 多风格探测结果
|
||||
|
||||
检测到:
|
||||
|
||||
- natural-voice(因为"口语化")
|
||||
- literary(因为"文学性")
|
||||
|
||||
这两个风格可以混合使用!
|
||||
|
||||
建议方案:
|
||||
|
||||
1. 主风格:natural-voice (70%) + 辅助:literary (30%)
|
||||
- 对话和日常用口语化
|
||||
- 关键时刻加入文学化描写
|
||||
|
||||
2. 主风格:literary (60%) + 辅助:natural-voice (40%)
|
||||
- 整体保持文学性
|
||||
- 对话部分口语化
|
||||
|
||||
你倾向哪种比例?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 场景 2:冲突的组合
|
||||
|
||||
### 示例:minimal + literary
|
||||
|
||||
**用户说**:
|
||||
|
||||
> "我要极简风格,但也要华丽的辞藻"
|
||||
|
||||
**探测结果**:
|
||||
|
||||
- minimal(极简)
|
||||
- literary(华丽)- 冲突!
|
||||
|
||||
**处理方式**:
|
||||
|
||||
```markdown
|
||||
⚠️ 风格冲突检测
|
||||
|
||||
检测到:
|
||||
|
||||
- minimal(极简风格) - 要求删除所有修饰
|
||||
- literary(文学风格) - 需要优美的语言
|
||||
|
||||
这两个风格有冲突:
|
||||
|
||||
- 极简要求:删除形容词、极短句、零修饰
|
||||
- 文学要求:精准词汇、美感、适度修饰
|
||||
|
||||
建议:
|
||||
|
||||
1. 选择 minimal,放弃华丽辞藻
|
||||
2. 选择 literary,调整"极简"为"简洁"
|
||||
3. 考虑使用 natural-voice(介于两者之间)
|
||||
|
||||
你倾向哪个方向?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 冲突矩阵
|
||||
|
||||
| 组合 | 兼容性 | 处理方式 |
|
||||
| ----------------------------- | ------- | -------------------------- |
|
||||
| natural-voice + literary | ✅ 兼容 | 提供比例混合方案 |
|
||||
| natural-voice + web-novel | ✅ 兼容 | 口语化网文,推荐 |
|
||||
| natural-voice + ancient-style | ⚠️ 谨慎 | 现代口语 vs 古韵,需要平衡 |
|
||||
| natural-voice + minimal | ⚠️ 谨慎 | 都强调简洁,可以组合 |
|
||||
| literary + web-novel | ⚠️ 谨慎 | 文学性 vs 爽文套路,需取舍 |
|
||||
| literary + ancient-style | ✅ 兼容 | 都重视意境,推荐 |
|
||||
| literary + minimal | ❌ 冲突 | 华丽 vs 极简,矛盾 |
|
||||
| web-novel + ancient-style | ⚠️ 谨慎 | 快节奏 vs 古韵留白,需平衡 |
|
||||
| web-novel + minimal | ❌ 冲突 | 套路化 vs 极简主义,矛盾 |
|
||||
| ancient-style + minimal | ⚠️ 谨慎 | 意象 vs 克制,可以尝试 |
|
||||
|
||||
---
|
||||
|
||||
## 中途调整风格
|
||||
|
||||
即使项目已经开始,仍然持续监控用户反馈。
|
||||
|
||||
### 场景:中途切换风格
|
||||
|
||||
**用户在第10章时说**:
|
||||
|
||||
> "这几章写得太文艺了,我想换成口语化一点"
|
||||
|
||||
**探测器激活**:
|
||||
|
||||
```markdown
|
||||
🎨 风格调整探测
|
||||
|
||||
检测到你想调整风格:
|
||||
当前风格:literary
|
||||
建议新风格:natural-voice
|
||||
|
||||
这会影响后续章节的写作。
|
||||
|
||||
调整建议:
|
||||
|
||||
1. 从下一章开始使用新风格
|
||||
2. 不修改已写章节(保持一致性)
|
||||
|
||||
确认调整吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 处理原则
|
||||
|
||||
1. **优先用户意图**:当用户明确表达偏好时,尊重用户选择
|
||||
2. **提供选项**:遇到冲突时,给出2-3个解决方案
|
||||
3. **解释原因**:说明为什么冲突,帮助用户理解
|
||||
4. **支持混合**:对于兼容的组合,提供比例建议
|
||||
5. **允许调整**:支持中途切换,但提醒影响范围
|
||||
@@ -1,218 +0,0 @@
|
||||
# 完整对话示例和成功案例
|
||||
|
||||
本文档展示 style-detector 在实际使用中的完整对话流程。
|
||||
|
||||
---
|
||||
|
||||
## 示例 1:基础风格探测
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写一个都市爽文,要口语化,真实一点"
|
||||
|
||||
**style-detector 响应**:
|
||||
|
||||
```
|
||||
🎨 风格探测器已激活
|
||||
|
||||
检测到关键词:
|
||||
- "口语化" → natural-voice
|
||||
- "真实" → natural-voice
|
||||
|
||||
建议风格:**natural-voice**(自然人声)
|
||||
|
||||
这个风格的特点:
|
||||
- 以口语化表达为主,像讲故事给朋友听
|
||||
- 生活细节丰富,代入感强
|
||||
- 对话推动情节(占比 40-60%)
|
||||
- 避免文艺腔和书面语
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
**用户**:
|
||||
|
||||
> "好的,应用这个风格"
|
||||
|
||||
**style-detector 执行**:
|
||||
|
||||
```
|
||||
✅ 正在加载风格知识库...
|
||||
|
||||
📖 读取:.claude/knowledge-base/styles/natural-voice.md
|
||||
|
||||
【展示核心要点】
|
||||
|
||||
## 核心原则:
|
||||
1. 口语化优先 - 能用5个字说清楚的,不用10个字
|
||||
2. 对话推动情节 - 对话占比 40-60%
|
||||
3. 行为>心理 - 多写做了什么,少写想了什么
|
||||
4. 具体>抽象 - 用具体的细节,不要抽象的概念
|
||||
|
||||
## AI 去味要点:
|
||||
- 禁用词:然而、殊不知、五味杂陈、极其...
|
||||
- 形容词限制:每100字最多5个
|
||||
- 成语使用:能不用就不用
|
||||
|
||||
✅ 已将风格配置写入 specification.md
|
||||
|
||||
在执行 /write 时,我会自动严格遵守 natural-voice 的所有规范。
|
||||
|
||||
💡 配合建议:
|
||||
检测到你也提到了"爽文",建议同时激活 requirement-detector 加载 fast-paced 规范。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 2:主动建议风格
|
||||
|
||||
**用户在 specification.md 中写道**:
|
||||
|
||||
> "类型:都市现实主义小说,讲述普通人的生活"
|
||||
|
||||
**style-detector 主动建议**:
|
||||
|
||||
```
|
||||
💡 风格建议
|
||||
|
||||
根据你的故事类型(都市现实主义,普通人生活),
|
||||
建议使用:**natural-voice**(自然人声风格)
|
||||
|
||||
理由:
|
||||
✅ 现实题材适合口语化
|
||||
✅ 普通人生活需要真实感
|
||||
✅ 代入感强
|
||||
|
||||
当然,这只是建议,你也可以选择其他风格。
|
||||
要应用 natural-voice 风格吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 3:风格混合
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写历史小说,要有古风的味道,但也要保持一定的文学性"
|
||||
|
||||
**style-detector 响应**:
|
||||
|
||||
```
|
||||
🔍 多风格探测结果
|
||||
|
||||
检测到:
|
||||
- ancient-style(因为"古风的味道")
|
||||
- literary(因为"文学性")
|
||||
|
||||
这两个风格可以很好地组合!
|
||||
|
||||
建议方案:
|
||||
1. 主风格:ancient-style (60%) + 辅助:literary (40%)
|
||||
- 用古韵营造氛围
|
||||
- 用文学性加深意境
|
||||
|
||||
2. 主风格:literary (55%) + 辅助:ancient-style (45%)
|
||||
- 以文学性为基础
|
||||
- 加入古风元素点缀
|
||||
|
||||
推荐:方案1 更适合历史小说
|
||||
|
||||
想应用这个组合吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 4:中途调整
|
||||
|
||||
**项目进行到第10章时,用户说**:
|
||||
|
||||
> "这几章太文艺了,读者反馈说看不懂,能不能换成简单点的"
|
||||
|
||||
**style-detector 响应**:
|
||||
|
||||
```
|
||||
🎨 风格调整探测
|
||||
|
||||
检测到你想调整风格:
|
||||
当前风格:literary
|
||||
建议新风格:natural-voice
|
||||
|
||||
这会影响后续章节的写作风格。
|
||||
|
||||
调整建议:
|
||||
1. 从第11章开始使用 natural-voice
|
||||
2. 不修改第1-10章(保持前文一致性)
|
||||
|
||||
这样做的好处:
|
||||
✅ 后续章节更易读
|
||||
✅ 保持已写内容完整性
|
||||
|
||||
这样做的风险:
|
||||
⚠️ 前后风格会有明显变化
|
||||
⚠️ 读者可能感到文风转变
|
||||
|
||||
确认调整吗?还是想要更平滑的过渡方案?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例 5:与 requirement-detector 协同
|
||||
|
||||
**用户**:
|
||||
|
||||
> "我要写现代言情,甜甜的那种,要口语化,还要去掉AI味"
|
||||
|
||||
**system(两个detector协同)**:
|
||||
|
||||
```
|
||||
🎨 style-detector 已激活
|
||||
检测到:口语化 → natural-voice
|
||||
|
||||
📋 requirement-detector 已激活
|
||||
检测到:甜甜的 → romance-sweet
|
||||
检测到:去掉AI味 → anti-ai-v4
|
||||
|
||||
✅ 推荐配置组合:
|
||||
|
||||
风格层:natural-voice
|
||||
规范层:romance-sweet + anti-ai-v4
|
||||
|
||||
最终效果:
|
||||
自然口语化的甜宠现代言情,强力去AI味
|
||||
|
||||
已写入配置:
|
||||
---
|
||||
writing-style: natural-voice
|
||||
writing-requirements:
|
||||
- romance-sweet
|
||||
- anti-ai-v4
|
||||
---
|
||||
|
||||
这个组合特别适合你的需求,确认应用吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用技巧
|
||||
|
||||
1. **关键词要明确**:直接说"口语化"、"网文"、"古风"等触发词
|
||||
2. **描述具体需求**:说明故事类型、目标读者
|
||||
3. **信任建议**:探测器会基于经验给出推荐
|
||||
4. **勇于调整**:写作过程中随时可以调整风格
|
||||
5. **组合使用**:风格(style)+ 规范(requirement)组合效果更好
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q:可以同时使用多个风格吗?**
|
||||
A:可以,但要注意兼容性。参考 [CONFLICT_RESOLUTION.md](CONFLICT_RESOLUTION.md) 查看兼容矩阵。
|
||||
|
||||
**Q:中途能换风格吗?**
|
||||
A:可以,但建议从新章节开始,保持已写内容的一致性。
|
||||
|
||||
**Q:不确定用哪个风格怎么办?**
|
||||
A:描述你的故事类型和目标读者,探测器会主动建议。
|
||||
|
||||
**Q:风格和规范有什么区别?**
|
||||
A:风格(style)控制文风和语感,规范(requirement)控制写作标准和要求。两者可以组合使用。
|
||||
@@ -1,227 +0,0 @@
|
||||
# 写作风格关键词详细列表
|
||||
|
||||
本文档包含所有可探测风格的详细关键词列表、触发场景示例和激活后行为模板。
|
||||
|
||||
---
|
||||
|
||||
## 1. natural-voice(自然人声风格)
|
||||
|
||||
### 关键词(任意一个即触发)
|
||||
|
||||
```
|
||||
口语化、生活化、真实感、接地气
|
||||
像说话一样、不要文艺腔、去掉书面语
|
||||
自然、不装、白话、日常对话
|
||||
真实、贴近生活、不做作
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"我想要口语化一点的风格,不要太文艺"
|
||||
> 用户:"写得真实一点,像平时说话那样"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
🎨 风格探测器已激活
|
||||
|
||||
我注意到你提到了【口语化、真实感】等关键词。
|
||||
|
||||
建议使用:**natural-voice**(自然人声风格)
|
||||
|
||||
这个风格的特点:
|
||||
|
||||
- 以口语化表达为主,像讲故事给朋友听
|
||||
- 生活细节丰富,代入感强
|
||||
- 对话推动情节(占比 40-60%)
|
||||
- 避免文艺腔和书面语
|
||||
|
||||
这个风格特别适合:
|
||||
✅ 都市现代小说
|
||||
✅ 现实题材
|
||||
✅ 情感类小说
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. literary(文学风格)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
文学性、优美、深刻、有深度
|
||||
严肃文学、纯文学、意境、诗意(现代文)
|
||||
哲思、人性、思想性、文艺
|
||||
有内涵、有深度、不肤浅
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"想写严肃文学,有深度的那种"
|
||||
> 用户:"要有文学性,不是网文那种"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
🎨 风格探测器已激活
|
||||
|
||||
检测到:【严肃文学、有深度】
|
||||
|
||||
建议使用:**literary**(文学风格)
|
||||
|
||||
这个风格的特点:
|
||||
|
||||
- 优美、深刻、有文学性
|
||||
- 注重意境和哲思
|
||||
- 适度的心理描写
|
||||
- 语言克制但有力量
|
||||
|
||||
这个风格特别适合:
|
||||
✅ 严肃文学作品
|
||||
✅ 历史小说(现代背景)
|
||||
✅ 需要思想深度的故事
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. web-novel(网文风格)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
网文、爽文、快节奏、套路
|
||||
打脸、装逼、升级流、废柴流
|
||||
玄幻风格、仙侠风格、系统文
|
||||
爽点、冲突密集
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"就是那种网文的感觉"
|
||||
> 用户:"节奏快一点,爽文那种"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
🎨 风格探测器已激活
|
||||
|
||||
检测到:【网文、爽文、快节奏】
|
||||
|
||||
建议使用:**web-novel**(网文风格)
|
||||
|
||||
这个风格的特点:
|
||||
|
||||
- 节奏快,冲突密集
|
||||
- 爽点频繁(打脸、装逼、升级)
|
||||
- 对话简短有力
|
||||
- 套路清晰但不老套
|
||||
|
||||
这个风格特别适合:
|
||||
✅ 玄幻小说
|
||||
✅ 都市爽文
|
||||
✅ 系统流、重生流
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. ancient-style(古风)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
古风、古韵、文言(不要太重)
|
||||
诗意、意象、留白、武侠风
|
||||
古典美、传统、江湖味
|
||||
有古韵、古代感、古典
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"想要古风的文字"
|
||||
> 用户:"要有武侠小说那种味道"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
🎨 风格探测器已激活
|
||||
|
||||
检测到:【古风、武侠风】
|
||||
|
||||
建议使用:**ancient-style**(古风)
|
||||
|
||||
这个风格的特点:
|
||||
|
||||
- 有古韵,但不是纯文言
|
||||
- 意象丰富,留白艺术
|
||||
- 诗意化的描写
|
||||
- 避免现代化词汇
|
||||
|
||||
这个风格特别适合:
|
||||
✅ 武侠小说
|
||||
✅ 仙侠(文风层面)
|
||||
✅ 古代背景小说
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. minimal(极简风格)
|
||||
|
||||
### 关键词
|
||||
|
||||
```
|
||||
极简、简洁、克制、海明威式
|
||||
冷硬、少废话、不啰嗦、留白
|
||||
不解释、硬汉风格、简约
|
||||
```
|
||||
|
||||
### 触发场景示例
|
||||
|
||||
> 用户:"简洁一点,不要那么多描写"
|
||||
> 用户:"海明威那种风格"
|
||||
|
||||
### 激活后行为模板
|
||||
|
||||
```markdown
|
||||
🎨 风格探测器已激活
|
||||
|
||||
检测到:【极简、海明威式】
|
||||
|
||||
建议使用:**minimal**(极简风格)
|
||||
|
||||
这个风格的特点:
|
||||
|
||||
- 高度简洁,删除所有修饰
|
||||
- 短句为主,节奏硬朗
|
||||
- 留白,不解释
|
||||
- 海明威式克制
|
||||
|
||||
⚠️ 警告:这个风格非常极端,不适合所有人
|
||||
|
||||
这个风格特别适合:
|
||||
✅ 悬疑推理
|
||||
✅ 冷硬派小说
|
||||
✅ 实验性作品
|
||||
|
||||
想要查看详细的风格指南吗?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用说明
|
||||
|
||||
当用户提到任何上述关键词时,按照对应的激活后行为模板与用户交互:
|
||||
|
||||
1. 确认探测到的关键词
|
||||
2. 建议对应的风格
|
||||
3. 简要说明特点和适用场景
|
||||
4. 询问是否查看详细指南
|
||||
|
||||
如果用户确认,继续执行加载知识库和写入配置的步骤。
|
||||
@@ -1,131 +0,0 @@
|
||||
---
|
||||
name: style-detector
|
||||
description: "探测用户的写作风格需求并加载对应指南。当用户提到口语化、生活化、真实感、文学性、严肃文学、纯文学、网文、爽文、快节奏、古风、武侠、古韵、极简、海明威、克制等关键词时自动激活。适用于讨论小说风格、写作文风、创作方向时使用。"
|
||||
allowed-tools: Read, Edit
|
||||
---
|
||||
|
||||
# 写作风格探测器
|
||||
|
||||
## 核心功能
|
||||
|
||||
自动探测用户的写作风格需求,并无缝加载对应的风格知识库。
|
||||
|
||||
## 可探测的风格
|
||||
|
||||
### 1. natural-voice(自然人声风格)
|
||||
|
||||
- **适合**:都市现代小说、现实题材、情感类小说
|
||||
- **特点**:口语化、生活化、真实感强
|
||||
- **触发词**:口语化、真实感、接地气、像说话一样
|
||||
|
||||
### 2. literary(文学风格)
|
||||
|
||||
- **适合**:严肃文学作品、历史小说、需要思想深度的故事
|
||||
- **特点**:优美、深刻、有文学性、注重意境
|
||||
- **触发词**:文学性、严肃文学、纯文学、有深度
|
||||
|
||||
### 3. web-novel(网文风格)
|
||||
|
||||
- **适合**:玄幻小说、都市爽文、系统流、重生流
|
||||
- **特点**:节奏快、冲突密集、爽点频繁
|
||||
- **触发词**:网文、爽文、打脸、装逼、升级流
|
||||
|
||||
### 4. ancient-style(古风)
|
||||
|
||||
- **适合**:武侠小说、仙侠、古代背景小说
|
||||
- **特点**:有古韵但不纯文言、意象丰富、诗意化
|
||||
- **触发词**:古风、古韵、武侠风、江湖味
|
||||
|
||||
### 5. minimal(极简风格)
|
||||
|
||||
- **适合**:悬疑推理、冷硬派小说、实验性作品
|
||||
- **特点**:高度简洁、海明威式克制、留白艺术
|
||||
- **触发词**:极简、海明威、克制、冷硬
|
||||
|
||||
详细关键词列表和触发场景请参阅 [KEYWORDS.md](KEYWORDS.md)。
|
||||
|
||||
---
|
||||
|
||||
## 激活后的工作流程
|
||||
|
||||
### 步骤 1:确认风格选择
|
||||
|
||||
当探测到关键词后,首先确认用户意图:
|
||||
|
||||
```
|
||||
我注意到你提到了【口语化】,这通常对应 natural-voice 风格。
|
||||
|
||||
我可以:
|
||||
1. 📖 展示这个风格的详细指南
|
||||
2. ✅ 直接应用这个风格到你的项目
|
||||
3. 🔍 看看其他风格选项
|
||||
|
||||
你想要哪一个?
|
||||
```
|
||||
|
||||
### 步骤 2:加载风格知识库
|
||||
|
||||
如果用户确认,使用 Read 工具读取对应的知识库文件:
|
||||
|
||||
```
|
||||
📖 读取:.claude/knowledge-base/styles/{style-name}.md
|
||||
```
|
||||
|
||||
然后展示核心要点,完整规范已加载到上下文中。
|
||||
|
||||
### 步骤 3:写入配置标记
|
||||
|
||||
使用 Edit 工具在用户的 `specification.md` 中添加配置:
|
||||
|
||||
```yaml
|
||||
---
|
||||
writing-style: natural-voice
|
||||
---
|
||||
```
|
||||
|
||||
提示用户配置已保存,在执行 /write 时会自动遵守该风格规范。
|
||||
|
||||
---
|
||||
|
||||
## 多风格处理
|
||||
|
||||
当探测到多个风格关键词时,进行兼容性检测:
|
||||
|
||||
- **兼容组合**:提供混合方案和比例建议
|
||||
- **冲突组合**:提示矛盾并给出解决方案
|
||||
|
||||
详细的冲突处理逻辑请参阅 [CONFLICT_RESOLUTION.md](CONFLICT_RESOLUTION.md)。
|
||||
|
||||
---
|
||||
|
||||
## 主动建议
|
||||
|
||||
- **基于故事类型建议风格**:分析 specification 中的故事类型,主动推荐适合的风格
|
||||
- **中途调整支持**:持续监控用户反馈,支持风格调整
|
||||
|
||||
---
|
||||
|
||||
## 与 requirement-detector 的配合
|
||||
|
||||
本 Skill 专注于文风层面,与 requirement-detector(规范层)协同工作:
|
||||
|
||||
```
|
||||
style-detector → 识别文风 → 加载 styles/*.md
|
||||
requirement-detector → 识别规范 → 加载 requirements/*.md
|
||||
|
||||
最终组合效果示例:
|
||||
natural-voice (风格) + anti-ai-v4 + fast-paced (规范)
|
||||
= 自然人声的快节奏爽文,强力去AI味
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
完整的对话示例和成功案例请参阅 [EXAMPLES.md](EXAMPLES.md)。
|
||||
|
||||
---
|
||||
|
||||
**Skill 版本**:v1.1
|
||||
**最后更新**:2025-10-19
|
||||
**兼容版本**:novel-writer-skills v1.0.5+
|
||||
@@ -1,420 +0,0 @@
|
||||
---
|
||||
name: novel-writer-workflow-guide
|
||||
description: "当用户开始小说项目或询问如何组织写作时使用 - 引导完成novel-writer的七步方法论并确保正确的工作流程"
|
||||
allowed-tools: Read, Grep
|
||||
---
|
||||
|
||||
# Novel Writer 系统化创作工作流
|
||||
|
||||
## 当用户说"我想写小说"
|
||||
|
||||
**立即激活此工作流指南。**
|
||||
|
||||
## 七步方法论概览
|
||||
|
||||
```
|
||||
1. /constitution → 建立创作原则
|
||||
2. /specify → 定义故事规格
|
||||
3. /clarify → 澄清模糊点
|
||||
4. /plan → 制定创作计划
|
||||
5. /tasks → 分解执行任务
|
||||
6. /write → AI 辅助写作
|
||||
7. /analyze → 质量验证分析
|
||||
```
|
||||
|
||||
## 详细步骤指导
|
||||
|
||||
### 步骤 1:建立创作原则
|
||||
|
||||
> "让我们从使用 `/constitution` 定义你的创作原则开始。这建立了你的核心价值观、质量标准和这个故事的不可协商规则。"
|
||||
|
||||
**为什么这很重要**:作为你的"创作宪法" - 决策会参考这些原则。
|
||||
|
||||
**包含什么**:
|
||||
|
||||
- 核心价值观(传递什么理念)
|
||||
- 质量底线(绝对不妥协的)
|
||||
- 风格原则(语言、节奏、氛围)
|
||||
- 内容原则(角色、情节、世界观规范)
|
||||
|
||||
**典型时长**:15-20 分钟
|
||||
|
||||
### 步骤 2:定义故事规格
|
||||
|
||||
> "现在使用 `/specify` 创建类似产品规格的故事文档。像产品经理一样思考:这个故事是什么,为谁写的,什么使它独特?"
|
||||
|
||||
**要包含什么**:
|
||||
|
||||
- 一句话概括
|
||||
- 目标读者
|
||||
- 核心冲突
|
||||
- 主要角色
|
||||
- 成功标准
|
||||
|
||||
**为什么这很重要**:
|
||||
|
||||
- 明确"为谁写"和"写什么"
|
||||
- 设定可衡量的成功标准
|
||||
- 为后续创作提供明确目标
|
||||
|
||||
**典型时长**:30-45 分钟
|
||||
|
||||
**特殊标记**:
|
||||
|
||||
- `[需要澄清]` - 标记需要进一步明确的点
|
||||
- `[核心需求]` - 不可妥协的需求
|
||||
- `[可选特性]` - 锦上添花的内容
|
||||
|
||||
### 步骤 3:澄清关键决策
|
||||
|
||||
> "运行 `/clarify` 通过 5 个精准问题解决任何不清楚的方面。AI 会识别你的规格中的模糊点,帮助你做出清晰的决定。"
|
||||
|
||||
**为什么这很重要**:规划中的模糊 = 写作中的混乱。
|
||||
|
||||
**过程**:
|
||||
|
||||
- AI 识别规格中的模糊点
|
||||
- 生成最多 5 个关键问题
|
||||
- 交互式回答,答案直接更新规格
|
||||
- 保留决策历史以便回溯
|
||||
|
||||
**典型问题**:
|
||||
|
||||
- "主角的核心动机是复仇还是正义?"
|
||||
- "故事节奏是快速爽文还是慢热精品?"
|
||||
- "结局是大团圆还是留有遗憾?"
|
||||
|
||||
**典型时长**:10-15 分钟
|
||||
|
||||
### 步骤 4:制定创作计划
|
||||
|
||||
> "使用 `/plan` 创建章节结构和技术方法。这是你决定如何实现你的规格的地方。"
|
||||
|
||||
**要设计什么**:
|
||||
|
||||
- 章节分解与活跃情节线
|
||||
- 节奏和张力分布
|
||||
- 伏笔计划
|
||||
- 角色弧线映射
|
||||
|
||||
**为什么这很重要**:
|
||||
|
||||
- 把抽象需求变成具体方案
|
||||
- 选择合适的写作方法和结构
|
||||
- 设计情节、人物、世界观的具体实现
|
||||
|
||||
**技术决策示例**:
|
||||
|
||||
- "使用七点结构增强悬念"
|
||||
- "采用多线叙事展现复杂性"
|
||||
- "通过限定视角增加神秘感"
|
||||
|
||||
**典型时长**:45-60 分钟
|
||||
|
||||
### 步骤 5:分解执行任务
|
||||
|
||||
> "执行 `/tasks` 生成带优先级、依赖关系和估算工作量的可操作任务列表。"
|
||||
|
||||
**任务类型**:
|
||||
|
||||
- 章节写作任务
|
||||
- 角色档案完善
|
||||
- 世界观设定补充
|
||||
- 修订和润色任务
|
||||
|
||||
**任务标记**:
|
||||
|
||||
- `[P]` - 可并行执行
|
||||
- `[依赖:X]` - 依赖任务 X 完成
|
||||
- `[高优]` - 高优先级任务
|
||||
|
||||
**为什么这很重要**:
|
||||
|
||||
- 大目标变成小步骤,降低创作难度
|
||||
- 明确优先级和依赖关系
|
||||
- 支持并行创作提高效率
|
||||
|
||||
**典型时长**:20-30 分钟
|
||||
|
||||
### 步骤 6:开始写作
|
||||
|
||||
> "现在 `/write` 逐章使用 AI 辅助。规格和计划指导每一章,确保一致性。"
|
||||
|
||||
**写作时**:
|
||||
|
||||
- 类型知识 skills 自动激活
|
||||
- 一致性检查器在后台运行
|
||||
- 节奏监控在检测到问题时提醒
|
||||
|
||||
**执行原则**:
|
||||
|
||||
- 严格遵循 constitution 的原则
|
||||
- 参考 plan 中的技术方案
|
||||
- 完成 tasks 中的具体任务
|
||||
- 保持与规格的一致性
|
||||
|
||||
**推荐节奏**:
|
||||
|
||||
- 每次写作会话 1-2 章
|
||||
- 每 3-5 章停下来回顾
|
||||
- 保持前进动力,不要过度编辑
|
||||
|
||||
### 步骤 7:质量检查
|
||||
|
||||
> "每 5 章运行 `/analyze` 保持质量并及早发现问题。"
|
||||
|
||||
**两种分析模式**:
|
||||
|
||||
- **框架分析**(写作前):验证规划
|
||||
- **内容分析**(写作后):验证执行
|
||||
|
||||
**验证维度**:
|
||||
|
||||
- 宪法合规性(是否违背核心原则)
|
||||
- 规格满足度(是否实现了需求)
|
||||
- 内容一致性(情节、时间、人物)
|
||||
- 质量标准(是否达到设定标准)
|
||||
|
||||
**何时运行**:
|
||||
|
||||
- 完成前 3 章后(早期验证)
|
||||
- 每 5 章(定期检查)
|
||||
- 完成草稿后(全面审查)
|
||||
|
||||
## Skills 自动激活
|
||||
|
||||
在遵循此工作流时,相关 skills 将基于上下文激活:
|
||||
|
||||
**在 `/specify` 期间**:
|
||||
|
||||
- 如果你提到"言情"→ Romance skill 激活
|
||||
- 如果你提到"悬疑"→ Mystery skill 激活
|
||||
- 如果你提到"奇幻"→ Fantasy skill 激活
|
||||
|
||||
**在 `/write` 期间**:
|
||||
|
||||
- 写对话 → Dialogue Techniques 激活
|
||||
- 写场景 → Scene Structure 激活
|
||||
- 任何写作 → Consistency Checker 后台运行
|
||||
|
||||
**整个过程中**:
|
||||
|
||||
- Workflow Guide(此 skill)保持活跃
|
||||
- 确保你不跳过关键步骤
|
||||
- 在需要时提供提醒
|
||||
|
||||
## 当用户偏离时
|
||||
|
||||
如果用户尝试跳过步骤或直接开始写作而没有计划:
|
||||
|
||||
**温和提醒**:
|
||||
|
||||
> "我注意到你直接跳到写作。Novel-writer 的优势在于系统性的前期计划。你想运行 `/constitution` 和 `/specify` 建立坚实基础吗?这会使写作过程更流畅并有助于保持一致性。"
|
||||
|
||||
**如果用户坚持跳过**:
|
||||
|
||||
> "我理解 - 你总是可以稍后创建规划文档。但是,请注意,没有 `/specify` 和 `/plan`,你需要手动跟踪一致性。"
|
||||
|
||||
## 不同规模项目的调整
|
||||
|
||||
### 短篇小说(1-3 万字)
|
||||
|
||||
**简化流程**:
|
||||
|
||||
```
|
||||
/specify → /clarify → /write → /analyze
|
||||
```
|
||||
|
||||
**重点**:明确核心冲突和转折
|
||||
|
||||
**时间**:1-2 天密集工作
|
||||
|
||||
### 中篇小说(10-20 万字)
|
||||
|
||||
**标准流程**:
|
||||
|
||||
```
|
||||
完整七步
|
||||
```
|
||||
|
||||
**重点**:计划和任务分解
|
||||
|
||||
**时间**:2-6 个月
|
||||
|
||||
### 长篇连载(50 万字+)
|
||||
|
||||
**强化流程**:
|
||||
|
||||
```
|
||||
重复循环 plan → tasks → write → analyze
|
||||
```
|
||||
|
||||
**重点**:持续的一致性验证
|
||||
|
||||
**时间**:6-18 个月
|
||||
|
||||
## 常见问题处理
|
||||
|
||||
### "我已经有大纲了"
|
||||
|
||||
> "太好了!让我们使用 `/specify` 将其转换为 novel-writer 的格式。这使其机器可读并启用所有追踪功能。"
|
||||
|
||||
**过程**:
|
||||
|
||||
1. 将现有大纲导入
|
||||
2. 用 `/specify` 格式化
|
||||
3. 用 `/clarify` 填补空白
|
||||
4. 用 `/plan` 创建详细的技术计划
|
||||
|
||||
### "这看起来设置很多"
|
||||
|
||||
> "设置需要 30-60 分钟,但节省了数小时的修订。你本质上是为你的小说创建'源代码' - 修改规格,重新生成内容。没有它,更改需要全文手动重写。"
|
||||
|
||||
**收益**:
|
||||
|
||||
- 保持一致性自动
|
||||
- 更改传播自动
|
||||
- 质量检查系统化
|
||||
- 修订更快更容易
|
||||
|
||||
### "我可以只使用部分工作流吗?"
|
||||
|
||||
> "可以,但有些命令相互依赖:
|
||||
>
|
||||
> - `/write` 需要 `/specify` 和 `/plan` 才能有效工作
|
||||
> - `/analyze` 需要已写的章节来评估
|
||||
> - `/track` 需要先 `/track-init`
|
||||
>
|
||||
> 最小可行工作流:`/constitution` → `/specify` → `/write`"
|
||||
|
||||
**完全可选**:
|
||||
|
||||
- `/clarify` - 如果你的规格已经清楚
|
||||
- `/tasks` - 如果你更喜欢自由形式写作
|
||||
- `/analyze` - 虽然强烈推荐
|
||||
|
||||
### "这适合我的写作风格吗?"
|
||||
|
||||
**兼容的写作风格**:
|
||||
|
||||
- **规划者**:会喜欢结构
|
||||
- **裤子作者**(凭感觉写):使用轻量级规格,专注于 `/write`
|
||||
- **混合型**:根据需要调整
|
||||
|
||||
**调整建议**:
|
||||
|
||||
- 规划者:在 `/plan` 上花更多时间
|
||||
- 裤子作者:保持 `/specify` 简短,允许发现
|
||||
- 混合型:使用完整流程但保持灵活
|
||||
|
||||
## 进度追踪
|
||||
|
||||
### 视觉进度指示器
|
||||
|
||||
当你进行工作流时,我会显示你的位置:
|
||||
|
||||
```
|
||||
✅ /constitution 完成
|
||||
✅ /specify 完成
|
||||
✅ /clarify 完成
|
||||
🔄 /plan 进行中...
|
||||
⏸️ /tasks 待定
|
||||
⏸️ /write 待定
|
||||
⏸️ /analyze 待定
|
||||
```
|
||||
|
||||
### 里程碑
|
||||
|
||||
**规划阶段完成**(steps 1-5):
|
||||
|
||||
- 你有完整的故事蓝图
|
||||
- 准备开始写作
|
||||
- 所有主要决策已做出
|
||||
|
||||
**第一稿完成**(步骤 6):
|
||||
|
||||
- 所有章节已写
|
||||
- 准备全面分析
|
||||
- 进入修订阶段
|
||||
|
||||
**质量验证通过**(步骤 7):
|
||||
|
||||
- 一致性验证
|
||||
- 符合质量标准
|
||||
- 准备发布或进一步润色
|
||||
|
||||
## 与其他 Skills 的集成
|
||||
|
||||
### 自动触发
|
||||
|
||||
**当你提到类型时**:
|
||||
|
||||
- "言情"→ Romance skill 提供惯例
|
||||
- "悬疑"→ Mystery skill 提供线索布置
|
||||
- "奇幻"→ Fantasy skill 提供世界构建
|
||||
|
||||
**当你遇到困难时**:
|
||||
|
||||
- "角色感觉平淡"→ 建议 Character Development commands
|
||||
- "场景拖沓"→ Scene Structure skill 激活
|
||||
- "对话僵硬"→ Dialogue Techniques skill 激活
|
||||
|
||||
### 协作工作流
|
||||
|
||||
**所有 Skills 都知道工作流**:
|
||||
|
||||
- 他们会参考你在工作流中的位置
|
||||
- 建议基于当前阶段适当
|
||||
- 在需要时提醒完成前面的步骤
|
||||
|
||||
## 成功模式
|
||||
|
||||
### 高生产力模式
|
||||
|
||||
```
|
||||
周一:/constitution + /specify(2-3小时)
|
||||
周二:/clarify + /plan(2-3小时)
|
||||
周三:/tasks + 开始 /write(2-3小时)
|
||||
周四-周日:/write 会话(每天1-2小时)
|
||||
下周一:/analyze + 计划下一批
|
||||
```
|
||||
|
||||
### 探索性模式
|
||||
|
||||
```
|
||||
第1周:/constitution + 轻量级 /specify
|
||||
第2-3周:/write 探索性章节
|
||||
第4周:基于学习更新 /specify 和 /plan
|
||||
第5-8周:结构化 /write
|
||||
第9周:/analyze 和修订
|
||||
```
|
||||
|
||||
### 冲刺模式(NaNoWriMo)
|
||||
|
||||
```
|
||||
第1天:快速 /constitution + /specify + /plan(4小时)
|
||||
第2-27天:密集 /write(每天2000字)
|
||||
第28-30天:/analyze + 紧急修复
|
||||
```
|
||||
|
||||
## 你不是孤单的
|
||||
|
||||
**在整个过程中**:
|
||||
|
||||
- 我在这里指导和提醒
|
||||
- Skills 自动应用专业知识
|
||||
- 一致性自动检查
|
||||
- 你专注于创作,系统处理组织
|
||||
|
||||
**你总是掌控**:
|
||||
|
||||
- 跳过你不需要的步骤
|
||||
- 调整以适应你的风格
|
||||
- 随时更改计划
|
||||
- 工具服务于你,不是相反
|
||||
|
||||
---
|
||||
|
||||
**记住**:这个工作流不是枷锁 - 它是脚手架。它支持你的创作过程,使强大的东西成为可能。一旦你熟悉它,它就变成第二天性,你会想知道你以前是如何在没有它的情况下写作的。
|
||||
|
||||
**准备开始了吗?让我们从 `/constitution` 开始!**
|
||||
@@ -1,389 +0,0 @@
|
||||
---
|
||||
name: natural-dialogue-techniques
|
||||
description: "在写作对话场景或用户询问角色对话时使用 - 提供自然、符合角色性格的对话技巧,展现角色并推进情节"
|
||||
allowed-tools: Read
|
||||
---
|
||||
|
||||
# 自然对话写作技巧
|
||||
|
||||
## 核心原则
|
||||
|
||||
### 通过语言展现角色
|
||||
|
||||
每个角色都应该有独特的声音:
|
||||
|
||||
1. **用词选择**
|
||||
- 受过教育的 vs 随意的
|
||||
- 正式的 vs 俚语
|
||||
- 技术术语 vs 日常语言
|
||||
- 角色背景决定词汇
|
||||
|
||||
2. **句子结构**
|
||||
- 短/断断续续 vs 长/流畅
|
||||
- 完整句子 vs 片段
|
||||
- 简单结构 vs 复杂从句
|
||||
- 反映思维方式
|
||||
|
||||
3. **言语模式**
|
||||
- 打断、停顿、重复
|
||||
- 口头禅和填充词
|
||||
- 独特的措辞习惯
|
||||
- 文化和地域特色
|
||||
|
||||
4. **不说什么**
|
||||
- 回避的话题
|
||||
- 说谎的模式
|
||||
- 沉默的时刻
|
||||
- 未说出口的含义
|
||||
|
||||
## 潜台词胜过直白
|
||||
|
||||
角色的意思 vs 说的话:
|
||||
|
||||
### ❌ 直白对话(说教式)
|
||||
|
||||
```
|
||||
"我对你生气,因为你昨晚对我撒谎了关于你去哪里。"
|
||||
```
|
||||
|
||||
### ✅ 富含潜台词的对话
|
||||
|
||||
```
|
||||
"你的商务会议开得怎么样?"
|
||||
"很好。"
|
||||
"我确定是这样。"
|
||||
```
|
||||
|
||||
**为什么更好**:
|
||||
|
||||
- 让读者参与推理
|
||||
- 创造张力和不适
|
||||
- 更真实(人们避免直接冲突)
|
||||
- 展示角色动态
|
||||
|
||||
### 潜台词的层次
|
||||
|
||||
**表面层**:字面意义
|
||||
**情感层**:真实感受
|
||||
**关系层**:权力和亲密度
|
||||
**主题层**:更大的故事意义
|
||||
|
||||
## 打断和重叠
|
||||
|
||||
真实对话不是有序的:
|
||||
|
||||
### 使用打断
|
||||
|
||||
```
|
||||
"听着,我知道你认为——"
|
||||
"你不知道我在想什么。"
|
||||
"——但如果你让我说完——"
|
||||
砰的一声,远处的门关上了。
|
||||
"算了。" 她转身离开。
|
||||
```
|
||||
|
||||
**何时使用打断**:
|
||||
|
||||
- 情绪高涨时
|
||||
- 急迫或恐慌
|
||||
- 权力斗争
|
||||
- 展示关系动态
|
||||
|
||||
### 思维打断言语
|
||||
|
||||
```
|
||||
"我只是想说——" 他的脸闪过什么。"没事。不重要。"
|
||||
```
|
||||
|
||||
**效果**:
|
||||
|
||||
- 展示内在冲突
|
||||
- 创造神秘感
|
||||
- 暗示隐藏信息
|
||||
- 角色自我审查
|
||||
|
||||
## 常见错误
|
||||
|
||||
### ❌ 信息倾倒
|
||||
|
||||
**问题**:角色说话只是为了传达信息给读者
|
||||
|
||||
**坏例子**:
|
||||
|
||||
```
|
||||
"如你所知,鲍勃,我们从 2015 年高中时就是朋友,
|
||||
当时我们都加入了篮球队,然后我们一起去了斯坦福,
|
||||
在那里学习工程学..."
|
||||
```
|
||||
|
||||
**好例子**:
|
||||
|
||||
```
|
||||
"还记得你三年级那个压哨球吗?"
|
||||
鲍勃笑了。"教练还在谈论它。"
|
||||
```
|
||||
|
||||
**解决方法**:
|
||||
|
||||
- 在行动中揭示信息
|
||||
- 角色只说他们会说的话
|
||||
- 使用简短的暗示而非完整历史
|
||||
- 让读者拼凑背景
|
||||
|
||||
### ❌ 每个人听起来都一样
|
||||
|
||||
**问题**:所有角色使用相同的词汇和言语模式
|
||||
|
||||
**解决方法**:为每个主要角色创建"声音表"
|
||||
|
||||
**声音表示例**:
|
||||
|
||||
| 角色 | 句子长度 | 词汇 | 怪癖 | 避免什么 |
|
||||
| ------ | ------------ | -------------- | ---------------- | ---------- |
|
||||
| 张医生 | 中长,复杂 | 正式,医学术语 | 解释过度 | 俚语 |
|
||||
| 李学生 | 短,片段 | 随意,网络语言 | "就是说"、"懂吧" | 承认不知道 |
|
||||
| 王老板 | 简短,命令式 | 商业,直接 | 很少浪费词 | 解释自己 |
|
||||
|
||||
### ❌ 随意言语中的完美语法
|
||||
|
||||
**太正式**:
|
||||
|
||||
```
|
||||
"我要去商店。你想让我为你买些什么吗?"
|
||||
```
|
||||
|
||||
**自然**:
|
||||
|
||||
```
|
||||
"去商店。要我带点啥吗?"
|
||||
```
|
||||
|
||||
**口语化技巧**:
|
||||
|
||||
- 缩略(想要 → 想,去 → 咱)
|
||||
- 省略词语(我去商店 → 去商店)
|
||||
- 片段句子
|
||||
- 口头填充词(嗯、呃、那个)
|
||||
|
||||
### ❌ 用对话进行叙述
|
||||
|
||||
**问题**:角色说出应该是叙述的内容
|
||||
|
||||
**坏例子**:
|
||||
|
||||
```
|
||||
"我站起来,走向门,打开它。是送货员。"
|
||||
```
|
||||
|
||||
**这不是对话**:
|
||||
|
||||
- 人们不会叙述自己的行动
|
||||
- 这是作者偷懒
|
||||
- 使用实际叙述或展示
|
||||
|
||||
## 高级技巧
|
||||
|
||||
### 对话作为行动
|
||||
|
||||
使用言语标签展示角色状态:
|
||||
|
||||
```
|
||||
"随便吧。" 她嘀咕道。(被击败)
|
||||
"随便吧!" 她厉声说道。(生气)
|
||||
"随便吧..." 她的声音渐渐消失。(不确定)
|
||||
```
|
||||
|
||||
**超越"说"**:
|
||||
|
||||
- 低语、嘀咕、咆哮(音量)
|
||||
- 厉声、尖叫、吼叫(强度)
|
||||
- 讥讽、嘲笑、低语(语调)
|
||||
- 但不要过度使用 - "说"通常就够了
|
||||
|
||||
### 沉默作为对话
|
||||
|
||||
有时不说什么很重要:
|
||||
|
||||
```
|
||||
"你爱我吗?"
|
||||
他看着自己的鞋子。
|
||||
```
|
||||
|
||||
**沉默的力量**:
|
||||
|
||||
- 说出言语无法说出的
|
||||
- 创造紧张
|
||||
- 展示不适或痛苦
|
||||
- 让读者填补
|
||||
|
||||
### 动作打破对话
|
||||
|
||||
不要让角色成为说话的头:
|
||||
|
||||
```
|
||||
"这不是我想要的。" 她把杯子推开。"不是这样的。"
|
||||
|
||||
他在房间里踱步。"那你想要什么?"
|
||||
|
||||
"我——" 她的手握紧了桌边。"我不知道。"
|
||||
```
|
||||
|
||||
**效果**:
|
||||
|
||||
- 打破单调
|
||||
- 展示身体语言
|
||||
- 添加视觉元素
|
||||
- 创造节奏变化
|
||||
|
||||
## 对话目的
|
||||
|
||||
### 每段对话应该至少做到以下一项:
|
||||
|
||||
1. **揭示角色**
|
||||
- 展示性格
|
||||
- 揭示动机
|
||||
- 显示关系
|
||||
- 表明成长
|
||||
|
||||
2. **推进情节**
|
||||
- 提供重要信息
|
||||
- 做出决定
|
||||
- 创造冲突
|
||||
- 解决问题
|
||||
|
||||
3. **建立氛围**
|
||||
- 设定基调
|
||||
- 创造紧张
|
||||
- 提供幽默
|
||||
- 深化情感
|
||||
|
||||
4. **展示冲突**
|
||||
- 目标对立
|
||||
- 误解
|
||||
- 权力斗争
|
||||
- 隐藏的议程
|
||||
|
||||
**如果对话不做这些**:删除它
|
||||
|
||||
## 特殊场景的对话
|
||||
|
||||
### 争吵/冲突
|
||||
|
||||
**有效技巧**:
|
||||
|
||||
- 短句,快速来回
|
||||
- 打断频繁
|
||||
- 言语变得更尖锐
|
||||
- 可能说出后悔的话
|
||||
- 升级然后冷静(或爆发)
|
||||
|
||||
```
|
||||
"你总是这样。"
|
||||
"这样怎样?"
|
||||
"假装——"
|
||||
"我没有假装任何事!"
|
||||
"——假装你在乎!"
|
||||
```
|
||||
|
||||
### 浪漫/亲密
|
||||
|
||||
**有效技巧**:
|
||||
|
||||
- 柔和的语调
|
||||
- 不完整的句子(情绪)
|
||||
- 身体亲近描述
|
||||
- 潜台词丰富
|
||||
- 脆弱性
|
||||
|
||||
```
|
||||
"我只是..." 他的拇指擦过她的下巴。"我不想搞砸这个。"
|
||||
|
||||
"那就别搞砸。" 她对他微笑。"简单。"
|
||||
|
||||
"简单。" 他笑了。"对。"
|
||||
```
|
||||
|
||||
### 悬疑/紧张
|
||||
|
||||
**有效技巧**:
|
||||
|
||||
- 低语或简短的话
|
||||
- 不完整的想法
|
||||
- 打断(外部威胁)
|
||||
- 加载停顿
|
||||
- 说不出的恐惧
|
||||
|
||||
```
|
||||
"你听到那个了吗?"
|
||||
|
||||
静默。然后:远处的脚步声。
|
||||
|
||||
"我们需要——"
|
||||
|
||||
一根树枝折断。两人都僵住了。
|
||||
```
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
### 在 `/specify` 时
|
||||
|
||||
- 为主要角色定义独特的声音
|
||||
- 识别关键对话场景
|
||||
- 计划主要通过对话揭示什么
|
||||
|
||||
### 在 `/plan` 期间
|
||||
|
||||
- 绘制高紧张度对话场景
|
||||
- 计划信息通过对话揭示
|
||||
- 设计角色声音弧(他们如何改变说话方式)
|
||||
|
||||
### 在 `/write` 时
|
||||
|
||||
- 自动应用角色声音一致性
|
||||
- 检查信息倾倒
|
||||
- 建议潜台词机会
|
||||
- 根据角色档案验证对话
|
||||
|
||||
### 在 `/analyze` 期间
|
||||
|
||||
- 检查角色声音一致性
|
||||
- 识别直白/说教对话
|
||||
- 验证每段对话都有目的
|
||||
- 建议可以加强的领域
|
||||
|
||||
## 对话写作检查清单
|
||||
|
||||
- [ ] 每个角色都有独特的声音
|
||||
- [ ] 对话推进情节或揭示角色
|
||||
- [ ] 使用潜台词而非直白
|
||||
- [ ] 包括自然的打断和重叠
|
||||
- [ ] 随意言语听起来随意
|
||||
- [ ] 没有信息倾倒
|
||||
- [ ] 动作打破大块对话
|
||||
- [ ] 沉默在适当的地方使用
|
||||
- [ ] 言语标签多样但不分散注意力
|
||||
- [ ] 每段对话都有明确目的
|
||||
|
||||
## 修订技巧
|
||||
|
||||
**大声朗读**:
|
||||
|
||||
- 听起来自然吗?
|
||||
- 你会被绕口令绊倒吗?
|
||||
- 节奏流畅吗?
|
||||
|
||||
**掩盖法**:
|
||||
|
||||
- 遮住言语标签
|
||||
- 你能从对话中分辨出是谁说的吗?
|
||||
- 如果不能,角色声音不够独特
|
||||
|
||||
**目的测试**:
|
||||
|
||||
- 这段对话达到什么目的?
|
||||
- 没有它会失去什么?
|
||||
- 可以更短、更锋利吗?
|
||||
|
||||
---
|
||||
|
||||
**记住**:伟大的对话感觉轻松但经过精心设计。它揭示的比说的更多,推进故事同时保持真实,并且每个字都有目的。少即是多 - 削减到精髓。
|
||||
@@ -1,397 +0,0 @@
|
||||
---
|
||||
name: scene-structure-techniques
|
||||
description: "在构建场景或规划章节内容时使用 - 提供场景-续场框架、张力管理和引人入胜场景的节拍式结构"
|
||||
allowed-tools: Read
|
||||
---
|
||||
|
||||
# 场景结构写作技巧
|
||||
|
||||
## 什么是场景?
|
||||
|
||||
**场景**是实时发生的冲突单元,角色追求目标并面对障碍。
|
||||
|
||||
**不是场景**:说明、背景故事、旅行、时间流逝
|
||||
**是场景**:争论、谈判、追逐、揭露
|
||||
|
||||
## 场景-续场模型
|
||||
|
||||
每个场景都应该遵循这个模式:
|
||||
|
||||
```
|
||||
场景(行动) 续场(反应)
|
||||
├── 目标 ├── 情绪
|
||||
├── 冲突 ├── 困境
|
||||
└── 灾难/成功 └── 决定
|
||||
```
|
||||
|
||||
## 场景结构(行动)
|
||||
|
||||
### 1. 目标
|
||||
|
||||
**POV角色在这个场景想要什么?**
|
||||
|
||||
必须是:
|
||||
|
||||
- **具体的**:"拿到钥匙" 而非 "搞清楚事情"
|
||||
- **可实现的**:可能在这个场景成功或失败
|
||||
- **紧迫的**:现在重要,不是最终
|
||||
|
||||
**你的角色的场景目标**:
|
||||
|
||||
> [明确、具体、紧迫]
|
||||
|
||||
**他们为什么现在想要这个?**:
|
||||
|
||||
> [情境/紧迫性]
|
||||
|
||||
### 2. 冲突
|
||||
|
||||
**什么阻止他们得到想要的?**
|
||||
|
||||
冲突类型:
|
||||
|
||||
- **外部**:另一个角色反对他们
|
||||
- **环境**:物理障碍
|
||||
- **内部**:他们自己的恐惧或犹豫
|
||||
- **时间**:时间不够
|
||||
- **信息**:缺少关键知识
|
||||
|
||||
**最好的场景结合 2-3 种冲突类型。**
|
||||
|
||||
**你的场景冲突**:
|
||||
|
||||
1. > [主要障碍]
|
||||
2. > [次要障碍]
|
||||
3. > [可选第三个]
|
||||
|
||||
### 3. 灾难或成功
|
||||
|
||||
**场景如何解决?**
|
||||
|
||||
**灾难**(更常见):
|
||||
|
||||
- 他们未能得到想要的
|
||||
- 他们得到了,但代价可怕
|
||||
- 他们得到了更糟的东西
|
||||
|
||||
**成功**(谨慎使用):
|
||||
|
||||
- 他们实现目标
|
||||
- 但揭示更大的问题
|
||||
- 或成功是空洞的
|
||||
|
||||
**你的场景解决**:
|
||||
|
||||
> [灾难或成功 + 后果]
|
||||
|
||||
## 续场结构(反应)
|
||||
|
||||
在紧张场景之后,读者需要**续场** - 角色处理的安静时刻。
|
||||
|
||||
### 1. 情绪反应
|
||||
|
||||
**角色对刚发生的事情感觉如何?**
|
||||
|
||||
展示不要说:
|
||||
|
||||
- **不好**:"莎拉感到悲伤"
|
||||
- **好**:"莎拉的手不停颤抖"
|
||||
|
||||
**你的角色的即时情绪**:
|
||||
|
||||
> [情绪的身体表现]
|
||||
|
||||
### 2. 困境
|
||||
|
||||
**灾难创造了一个困境 - 没有好选择:**
|
||||
|
||||
- 选项 A:安全但妥协价值观
|
||||
- 选项 B:冒险但保持正直
|
||||
- 选项 C:中间路线,但不确定
|
||||
|
||||
**你的角色的困境**:
|
||||
|
||||
- 选项 A:> [安全选择]
|
||||
- 选项 B:> [冒险选择]
|
||||
- 选项 C:> [中间地带]
|
||||
|
||||
### 3. 决定
|
||||
|
||||
**他们决定做什么?**
|
||||
|
||||
这个决定成为下一个场景的目标。
|
||||
|
||||
**你的角色的决定**:
|
||||
|
||||
> [他们接下来要做什么]
|
||||
|
||||
**这成为下一个场景的目标**,创造无缝的场景到场景连接。
|
||||
|
||||
## 场景节奏点
|
||||
|
||||
现在让我们构建场景的实际节奏(微时刻):
|
||||
|
||||
### 开场节奏
|
||||
|
||||
**我们如何进入场景?**
|
||||
|
||||
- 尽可能晚地开始
|
||||
- 直接进入冲突/张力
|
||||
- 快速建立 POV 和地点
|
||||
|
||||
**糟糕的开场**:"莎拉醒来,刷牙,吃早餐..."
|
||||
**好的开场**:"莎拉的手机嗡嗡响。信息来自她死去的姐姐。"
|
||||
|
||||
**你的开场节奏**:
|
||||
|
||||
> [用户提供]
|
||||
|
||||
### 上升张力节奏
|
||||
|
||||
**冲突如何升级?**
|
||||
|
||||
每个节奏应该:
|
||||
|
||||
1. **提高风险**
|
||||
2. **使情况复杂化**
|
||||
3. **揭示角色**
|
||||
|
||||
**示例升级**:
|
||||
|
||||
```
|
||||
节奏 1:莎拉要求文件 → 被拒绝
|
||||
节奏 2:莎拉诉诸友谊 → 老板揭示他知道她的秘密
|
||||
节奏 3:莎拉威胁辞职 → 老板揭示他一直在保护她
|
||||
节奏 4:莎拉意识到她错了 → 现在必须在忠诚中选择
|
||||
```
|
||||
|
||||
**你的升级节奏(3-5个)**:
|
||||
|
||||
1. > [第一个节奏]
|
||||
2. > [第二个节奏]
|
||||
3. > [第三个节奏]
|
||||
4. > [可选第四个]
|
||||
5. > [可选第五个]
|
||||
|
||||
### 高潮节奏
|
||||
|
||||
**最高张力的时刻**
|
||||
|
||||
这是:
|
||||
|
||||
- 角色做出关键选择的地方
|
||||
- 真相被揭示的地方
|
||||
- 行动达到峰值强度的地方
|
||||
- 一切悬而未决的地方
|
||||
|
||||
**你的高潮节奏**:
|
||||
|
||||
> [用户提供]
|
||||
|
||||
### 解决节奏
|
||||
|
||||
**即时后果**
|
||||
|
||||
不要在高潮结束 - 给一个节奏的余波:
|
||||
|
||||
- 角色的即时反应
|
||||
- 什么改变了
|
||||
- 暗示接下来会发生什么
|
||||
|
||||
**你的解决节奏**:
|
||||
|
||||
> [用户提供]
|
||||
|
||||
## 张力管理
|
||||
|
||||
### 张力级别
|
||||
|
||||
场景应该在强度上有所不同:
|
||||
|
||||
```
|
||||
高张力(30%) ⚡️ 行动、对抗、揭露
|
||||
中等张力(50%) 🔥 调查、计划、建立
|
||||
低张力(20%) 🌊 反思、连接、设置
|
||||
```
|
||||
|
||||
**太多高张力** = 读者疲劳
|
||||
**太多低张力** = 读者无聊
|
||||
|
||||
**这个场景的张力级别是什么?**
|
||||
|
||||
> [用户选择]
|
||||
|
||||
**上一个场景的张力是什么?**
|
||||
|
||||
> [用户提供或我参考追踪数据]
|
||||
|
||||
**基于节奏的建议**:
|
||||
|
||||
> [我建议这是否是好的节奏或是否应该调整]
|
||||
|
||||
## 场景检查清单
|
||||
|
||||
在你写这个场景之前,验证:
|
||||
|
||||
- [ ] **明确目标**:POV 角色想要具体的东西
|
||||
- [ ] **有意义的风险**:目标对角色重要
|
||||
- [ ] **重大冲突**:真正的障碍,不容易克服
|
||||
- [ ] **上升张力**:每个节奏增加压力
|
||||
- [ ] **灾难或成功**:场景以变化结束
|
||||
- [ ] **情感真实**:角色的反应是真实的
|
||||
- [ ] **故事推进**:场景推进情节或角色弧
|
||||
- [ ] **感官细节**:设定生动,不通用
|
||||
- [ ] **对话中的潜台词**:角色不直接说所有事情
|
||||
- [ ] **这个角色独有**:只有这个角色能以这种方式体验场景
|
||||
|
||||
**准备写了吗?** 我将根据你的答案提供场景大纲。
|
||||
|
||||
## 生成的场景大纲
|
||||
|
||||
基于你的答案,这是你的场景结构:
|
||||
|
||||
```markdown
|
||||
## 场景:[场景名称/描述]
|
||||
|
||||
**POV**:[角色名称]
|
||||
**地点**:[哪里]
|
||||
**时间**:[故事中的何时]
|
||||
**张力级别**:[高/中/低]
|
||||
|
||||
### 场景目标
|
||||
|
||||
[角色] 想要 [具体目标] 因为 [紧迫性/动机]。
|
||||
|
||||
### 冲突
|
||||
|
||||
1. [主要障碍]
|
||||
2. [次要障碍]
|
||||
3. [额外复杂化]
|
||||
|
||||
### 场景节奏
|
||||
|
||||
**开场**:[进入场景...]
|
||||
|
||||
**节奏 1 - 设置**:[角色行动/情况]
|
||||
**节奏 2 - 复杂化**:[引入冲突]
|
||||
**节奏 3 - 升级**:[风险提高]
|
||||
**节奏 4 - 危机**:[不归路]
|
||||
**节奏 5 - 高潮**:[最高张力时刻]
|
||||
|
||||
**解决**:[即时后果]
|
||||
|
||||
### 灾难/成功
|
||||
|
||||
[场景如何结束] → [后果]
|
||||
|
||||
### 续场(如果需要)
|
||||
|
||||
**情绪**:[角色的反应]
|
||||
**困境**:[他们权衡的选项]
|
||||
**决定**:[他们选择做什么]
|
||||
→ 这导致下一个场景目标:[下一个场景目标]
|
||||
|
||||
### 要包含的关键元素
|
||||
|
||||
- [ ] 感官细节:[特定的景象、声音、气味]
|
||||
- [ ] 对话潜台词:[什么没有被说]
|
||||
- [ ] 角色特定反应:[他们如何独特地响应]
|
||||
- [ ] 主题连接:[场景如何与故事主题相关]
|
||||
|
||||
### 写作笔记
|
||||
|
||||
[这个场景的任何特定指导]
|
||||
```
|
||||
|
||||
## 与 Novel-Writer 命令集成
|
||||
|
||||
**保存大纲到**:`scenes/[章节号]-[场景名称].md`
|
||||
|
||||
**写作时**:使用 `/write` 并参考这个大纲:
|
||||
|
||||
```
|
||||
/write 第5章 - 对抗场景
|
||||
|
||||
参考:scenes/chapter-5-confrontation.md
|
||||
```
|
||||
|
||||
场景大纲将指导写作,相关技能将激活:
|
||||
|
||||
- 对话技巧用于对话节奏
|
||||
- 节奏监控用于张力管理
|
||||
- 一致性检查用于角色行为
|
||||
|
||||
## 高级场景类型
|
||||
|
||||
一旦你熟悉基本场景,我可以指导你通过专门的场景类型:
|
||||
|
||||
- **动作场景**:管理多个同时发生的事件
|
||||
- **揭露场景**:控制信息披露
|
||||
- **亲密场景**:平衡身体和情感
|
||||
- **群体场景**:管理多个角色动态
|
||||
- **回忆场景**:整合过去与现在
|
||||
|
||||
**你想要任何这些专门场景类型的指导吗?**
|
||||
|
||||
## 场景续场平衡
|
||||
|
||||
**场景(行动)vs 续场(反应)的比例**:
|
||||
|
||||
- **快节奏惊悚**:80% 场景,20% 续场
|
||||
- **平衡故事**:60% 场景,40% 续场
|
||||
- **角色驱动**:50% 场景,50% 续场
|
||||
|
||||
**调整基于**:
|
||||
|
||||
- 类型期望
|
||||
- 当前故事阶段
|
||||
- 最近的张力级别
|
||||
- 读者需要喘息
|
||||
|
||||
## 常见场景问题
|
||||
|
||||
### 问题:场景拖沓,没有前进
|
||||
|
||||
**诊断**:
|
||||
|
||||
- 没有明确目标?
|
||||
- 冲突太弱?
|
||||
- 太多描述,不够行动?
|
||||
|
||||
**解决**:
|
||||
|
||||
- 明确目标
|
||||
- 增加障碍
|
||||
- 削减到本质
|
||||
|
||||
### 问题:场景感觉通用
|
||||
|
||||
**诊断**:
|
||||
|
||||
- 可能发生在任何角色身上?
|
||||
- 设定是通用的"房间"或"街道"?
|
||||
- 对话可以被任何人说?
|
||||
|
||||
**解决**:
|
||||
|
||||
- 添加角色特定的反应
|
||||
- 使用具体、独特的设定细节
|
||||
- 应用角色声音到对话
|
||||
|
||||
### 问题:读者困惑
|
||||
|
||||
**诊断**:
|
||||
|
||||
- POV 不清楚?
|
||||
- 太多角色同时?
|
||||
- 物理空间不清楚?
|
||||
|
||||
**解决**:
|
||||
|
||||
- 早期建立清晰的 POV
|
||||
- 限制活跃角色到 2-4
|
||||
- 描述空间布局
|
||||
|
||||
---
|
||||
|
||||
**记住**:一个精心构建的场景是有目的的伟大故事讲述的构建块。每个场景都应该改变某些东西 - 情况、关系或角色理解。如果场景结束时一切都一样,就删除它或重写它。
|
||||
@@ -8,12 +8,18 @@ description: Monisuo 项目结构化开发流程。需求分析 → 架构设计
|
||||
## 流程概览
|
||||
|
||||
```
|
||||
Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发 → [启动 Agent] → Phase 3-4: 测试+构建
|
||||
↑ │
|
||||
└──────────────────────── Bug 修复 ←─────────────────────────────────────────┘
|
||||
Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发
|
||||
↑ │
|
||||
│ ↓
|
||||
│ [Agent A] Phase 3: 精简 + 测试 + 构建
|
||||
│ │
|
||||
│ ↓ (通过)
|
||||
│ [Agent B] Phase 4: 功能验证(用例驱动)
|
||||
│ │
|
||||
└──────────────── Bug 修复 ←──────────────────┘
|
||||
```
|
||||
|
||||
**Phase 1-1.5-2 在主对话完成,Phase 3-4 启动独立 Agent。**
|
||||
**Phase 1-1.5-2 在主对话完成,Phase 3 和 Phase 4 分别启动独立 Agent。**
|
||||
|
||||
---
|
||||
|
||||
@@ -93,17 +99,17 @@ Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发
|
||||
|
||||
---
|
||||
|
||||
## Phase 3-4: 测试与构建(独立 Agent)
|
||||
## Phase 3: 精简 + 测试 + 构建(Agent A)
|
||||
|
||||
Phase 2 完成后,启动独立 Agent 执行测试和构建。
|
||||
Phase 2 完成后,启动独立 Agent 执行代码精简、自动化测试和构建。
|
||||
|
||||
### 启动 Agent
|
||||
### 启动 Agent A
|
||||
|
||||
```
|
||||
Agent(
|
||||
description: "测试验证与构建",
|
||||
description: "精简+测试验证与构建",
|
||||
prompt: |
|
||||
你是 Monisuo 项目测试 Agent,独立完成以下任务,不要询问用户。
|
||||
你是 Monisuo 项目质量 Agent,独立完成以下任务,不要询问用户。
|
||||
|
||||
## 1. 读取 Spec
|
||||
- 路径: docs/features/[feature-name].md
|
||||
@@ -114,19 +120,24 @@ Agent(
|
||||
- Flutter: flutter analyze, AppSpacing/AppRadius/AppColorScheme 规范
|
||||
- Java: @Transactional 资金方法, 统一异常处理, RESTful 设计
|
||||
|
||||
## 3. 测试
|
||||
## 3. 代码精简(simplify)
|
||||
- 对变更代码执行 /simplify:审查复用性、质量和效率,修复发现的问题
|
||||
- 精简完成后重新运行 git diff 确认变更合理
|
||||
|
||||
## 4. 测试
|
||||
- 后端: mvn test
|
||||
- Flutter: cd flutter_monisuo && flutter test
|
||||
- API: ./tests/api/test-[feature].sh(如存在)
|
||||
|
||||
## 4. 构建
|
||||
## 5. 构建
|
||||
- 后端: mvn clean package -DskipTests → target/monisuo-*.jar
|
||||
- Flutter: cd flutter_monisuo && flutter build web --release --dart-define=ENV=prod → build/web/
|
||||
|
||||
## 5. 输出报告
|
||||
## 6. 输出报告
|
||||
| 项目 | 状态 | 备注 |
|
||||
|------|------|------|
|
||||
| 代码审查 | ✅/❌ | |
|
||||
| 代码精简 | ✅/❌ | 改动摘要 |
|
||||
| 后端测试 | ✅/❌ | |
|
||||
| Flutter 测试 | ✅/❌ | |
|
||||
| 后端构建 | ✅/❌ | |
|
||||
@@ -136,5 +147,60 @@ Agent(
|
||||
)
|
||||
```
|
||||
|
||||
### Bug 修复循环
|
||||
Agent 发现 Bug → 主对话修复 → 重新启动 Agent 验证 → 全部通过
|
||||
---
|
||||
|
||||
## Phase 4: 功能验证(Agent B)
|
||||
|
||||
**Agent A 全部通过后**,启动第二个独立 Agent,基于 Spec 中的测试用例验证功能正确性。
|
||||
|
||||
### 启动 Agent B
|
||||
|
||||
```
|
||||
Agent(
|
||||
description: "功能验证(用例驱动)",
|
||||
prompt: |
|
||||
你是 Monisuo 项目功能验证 Agent。基于 Feature Spec 中的测试用例,验证功能实现是否正确。不要询问用户。
|
||||
|
||||
## 1. 读取 Spec
|
||||
- 路径: docs/features/[feature-name].md
|
||||
- 提取「测试用例」和「验收标准」
|
||||
|
||||
## 2. 读取变更代码
|
||||
- git diff 查看本次变更的文件列表
|
||||
- 阅读变更的 Controller、Service、Provider、UI 代码
|
||||
- 对照 Spec 中的 API 设计,确认实现与契约一致
|
||||
|
||||
## 3. 逐条验证测试用例
|
||||
对 Spec 中的每条测试用例:
|
||||
- **正常流程**:追踪代码路径,确认主流程逻辑正确(参数传递、返回值、状态变更)
|
||||
- **异常流程**:确认错误处理覆盖(参数校验、权限检查、边界条件)
|
||||
- **边界条件**:空值、零值、溢出、并发等极端场景是否有防护
|
||||
|
||||
### 验证方法
|
||||
- **后端 API**:阅读 Controller → Service → Mapper 代码路径,确认请求参数、业务逻辑、数据库操作与 Spec 一致
|
||||
- **前端页面**:阅读 UI → Provider/State → Service 代码路径,确认交互流程、状态管理、错误展示正确
|
||||
- **数据一致性**:确认资金变动相关的操作有事务注解、余额校验、流水记录
|
||||
|
||||
## 4. 输出验证报告
|
||||
| 用例编号 | 用例描述 | 验证结果 | 备注 |
|
||||
|----------|----------|----------|------|
|
||||
| TC-01 | 正常:xxx | ✅ 通过 / ❌ 失败 | 具体原因 |
|
||||
| TC-02 | 异常:xxx | ✅ 通过 / ❌ 失败 | 具体原因 |
|
||||
| ... | ... | ... | ... |
|
||||
|
||||
### 总结
|
||||
- 通过率:X/Y
|
||||
- 未通过用例:列出失败原因和修复建议
|
||||
- 风险点:潜在问题或遗漏
|
||||
|
||||
如有未通过用例,返回主对话修复后重新启动验证。
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bug 修复循环
|
||||
|
||||
- **Agent A 失败**(测试/构建不通过)→ 主对话修复 Bug → 重新启动 Agent A
|
||||
- **Agent B 失败**(功能验证不通过)→ 主对话修复逻辑 → 重新启动 Agent B
|
||||
- **全部通过** → 开发完成
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-De70L21J.js";import{r as s}from"./button-DveXNdlZ.js";var c=n({__name:`AlertDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-description`,class:r(i(o)(`text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`AlertTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-title`,class:r(i(o)(`col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight`,s.class))},[a(n.$slots,`default`)],2))}}),u=s(`relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,{variants:{variant:{default:`bg-card text-card-foreground`,destructive:`text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90`}},defaultVariants:{variant:`default`}}),d=n({__name:`Alert`,props:{class:{type:[Boolean,null,String,Object,Array]},variant:{}},setup(n){let s=n;return(c,l)=>(e(),t(`div`,{"data-slot":`alert`,class:r(i(o)(i(u)({variant:n.variant}),s.class)),role:`alert`},[a(c.$slots,`default`)],2))}});export{l as n,c as r,d as t};
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";import{r as s}from"./button-BTKRNUhQ.js";var c=n({__name:`AlertDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-description`,class:r(i(o)(`text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`AlertTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-title`,class:r(i(o)(`col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight`,s.class))},[a(n.$slots,`default`)],2))}}),u=s(`relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,{variants:{variant:{default:`bg-card text-card-foreground`,destructive:`text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90`}},defaultVariants:{variant:`default`}}),d=n({__name:`Alert`,props:{class:{type:[Boolean,null,String,Object,Array]},variant:{}},setup(n){let s=n;return(c,l)=>(e(),t(`div`,{"data-slot":`alert`,class:r(i(o)(i(u)({variant:n.variant}),s.class)),role:`alert`},[a(c.$slots,`default`)],2))}});export{l as n,c as r,d as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,Q as n,Y as r,_ as i,g as a,ut as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u,v as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-De70L21J.js";import{i as p}from"./button-DveXNdlZ.js";import{t as m}from"./useForwardExpose-CNhbE6SX.js";import{r as h}from"./AvatarImage-Ck1aL522.js";var g=s({__name:`AvatarFallback`,props:{delayMs:{type:Number,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let s=e,u=h();m();let f=o(s.delayMs===void 0);return r(e=>{if(s.delayMs&&d){let t=window.setTimeout(()=>{f.value=!0},s.delayMs);e(()=>{window.clearTimeout(t)})}}),(e,r)=>f.value&&c(u).imageLoadingStatus.value!==`loaded`?(t(),a(c(p),{key:0,"as-child":e.asChild,as:e.as},{default:n(()=>[l(e.$slots,`default`)]),_:3},8,[`as-child`,`as`])):i(`v-if`,!0)}}),_=s({__name:`AvatarFallback`,props:{delayMs:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(r){let i=r,o=u(i,`class`);return(r,s)=>(t(),a(c(g),e({"data-slot":`avatar-fallback`},c(o),{class:c(f)(`bg-muted flex size-full items-center justify-center rounded-full`,i.class)}),{default:n(()=>[l(r.$slots,`default`)]),_:3},16,[`class`]))}});export{_ as t};
|
||||
import{A as e,I as t,Q as n,Y as r,_ as i,g as a,ut as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u,v as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-BpHHjIYv.js";import{i as p}from"./button-BTKRNUhQ.js";import{t as m}from"./useForwardExpose-CNhbE6SX.js";import{r as h}from"./AvatarImage-Ct5I9mHM.js";var g=s({__name:`AvatarFallback`,props:{delayMs:{type:Number,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let s=e,u=h();m();let f=o(s.delayMs===void 0);return r(e=>{if(s.delayMs&&d){let t=window.setTimeout(()=>{f.value=!0},s.delayMs);e(()=>{window.clearTimeout(t)})}}),(e,r)=>f.value&&c(u).imageLoadingStatus.value!==`loaded`?(t(),a(c(p),{key:0,"as-child":e.asChild,as:e.as},{default:n(()=>[l(e.$slots,`default`)]),_:3},8,[`as-child`,`as`])):i(`v-if`,!0)}}),_=s({__name:`AvatarFallback`,props:{delayMs:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(r){let i=r,o=u(i,`class`);return(r,s)=>(t(),a(c(g),e({"data-slot":`avatar-fallback`},c(o),{class:c(f)(`bg-muted flex size-full items-center justify-center rounded-full`,i.class)}),{default:n(()=>[l(r.$slots,`default`)]),_:3},16,[`class`]))}});export{_ as t};
|
||||
@@ -1 +1 @@
|
||||
import{$ as e,A as t,I as n,J as r,N as i,P as a,Q as o,Y as s,a as c,g as l,gt as u,m as d,ut as f,x as p,xt as m,yt as h,z as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{v as _}from"./dist-3yfE1dPa.js";import{J as v}from"./index-De70L21J.js";import{O as y}from"./Teleport-DzgMZwe8.js";import{i as b}from"./button-DveXNdlZ.js";import{t as x}from"./useForwardExpose-CNhbE6SX.js";var[S,C]=y(`AvatarRoot`),w=p({__name:`AvatarRoot`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){return x(),C({imageLoadingStatus:f(`idle`)}),(e,t)=>(n(),l(h(b),{"as-child":e.asChild,as:e.as},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`as-child`,`as`]))}});function T(e,t){return e?t?(e.src!==t&&(e.src=t),e.complete&&e.naturalWidth>0?`loaded`:`loading`):`error`:`idle`}function E(e,{referrerPolicy:t,crossOrigin:n}={}){let r=f(!1),o=f(null),c=d(()=>r.value?(!o.value&&_&&(o.value=new window.Image),o.value):null),l=f(T(c.value,e.value)),u=e=>()=>{r.value&&(l.value=e)};return i(()=>{r.value=!0,s(r=>{let i=c.value;if(!i)return;l.value=T(i,e.value);let a=u(`loaded`),o=u(`error`);i.addEventListener(`load`,a),i.addEventListener(`error`,o),t?.value&&(i.referrerPolicy=t.value),typeof n?.value==`string`&&(i.crossOrigin=n.value),r(()=>{i.removeEventListener(`load`,a),i.removeEventListener(`error`,o)})})}),a(()=>{r.value=!1}),l}var D=p({__name:`AvatarImage`,props:{src:{type:String,required:!0},referrerPolicy:{type:null,required:!1},crossOrigin:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`img`}},emits:[`loadingStatusChange`],setup(t,{emit:i}){let a=t,s=i,{src:d,referrerPolicy:f,crossOrigin:p}=u(a);x();let m=S(),_=E(d,{referrerPolicy:f,crossOrigin:p});return r(_,e=>{s(`loadingStatusChange`,e),e!==`idle`&&(m.imageLoadingStatus.value=e)},{immediate:!0}),(t,r)=>e((n(),l(h(b),{role:`img`,"as-child":t.asChild,as:t.as,src:h(d),referrerpolicy:h(f),crossorigin:h(p)},{default:o(()=>[g(t.$slots,`default`)]),_:3},8,[`as-child`,`as`,`src`,`referrerpolicy`,`crossorigin`])),[[c,h(_)===`loaded`]])}}),O=p({__name:`Avatar`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,r)=>(n(),l(h(w),{"data-slot":`avatar`,class:m(h(v)(`relative flex size-8 shrink-0 overflow-hidden rounded-full`,t.class))},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`class`]))}}),k=p({__name:`AvatarImage`,props:{src:{},referrerPolicy:{},crossOrigin:{},asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,i)=>(n(),l(h(D),t({"data-slot":`avatar-image`},r,{class:`aspect-square size-full`}),{default:o(()=>[g(e.$slots,`default`)]),_:3},16))}});export{O as n,S as r,k as t};
|
||||
import{$ as e,A as t,I as n,J as r,N as i,P as a,Q as o,Y as s,a as c,g as l,gt as u,m as d,ut as f,x as p,xt as m,yt as h,z as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{v as _}from"./dist-3yfE1dPa.js";import{J as v}from"./index-BpHHjIYv.js";import{O as y}from"./Teleport-qOjHMYM8.js";import{i as b}from"./button-BTKRNUhQ.js";import{t as x}from"./useForwardExpose-CNhbE6SX.js";var[S,C]=y(`AvatarRoot`),w=p({__name:`AvatarRoot`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){return x(),C({imageLoadingStatus:f(`idle`)}),(e,t)=>(n(),l(h(b),{"as-child":e.asChild,as:e.as},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`as-child`,`as`]))}});function T(e,t){return e?t?(e.src!==t&&(e.src=t),e.complete&&e.naturalWidth>0?`loaded`:`loading`):`error`:`idle`}function E(e,{referrerPolicy:t,crossOrigin:n}={}){let r=f(!1),o=f(null),c=d(()=>r.value?(!o.value&&_&&(o.value=new window.Image),o.value):null),l=f(T(c.value,e.value)),u=e=>()=>{r.value&&(l.value=e)};return i(()=>{r.value=!0,s(r=>{let i=c.value;if(!i)return;l.value=T(i,e.value);let a=u(`loaded`),o=u(`error`);i.addEventListener(`load`,a),i.addEventListener(`error`,o),t?.value&&(i.referrerPolicy=t.value),typeof n?.value==`string`&&(i.crossOrigin=n.value),r(()=>{i.removeEventListener(`load`,a),i.removeEventListener(`error`,o)})})}),a(()=>{r.value=!1}),l}var D=p({__name:`AvatarImage`,props:{src:{type:String,required:!0},referrerPolicy:{type:null,required:!1},crossOrigin:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`img`}},emits:[`loadingStatusChange`],setup(t,{emit:i}){let a=t,s=i,{src:d,referrerPolicy:f,crossOrigin:p}=u(a);x();let m=S(),_=E(d,{referrerPolicy:f,crossOrigin:p});return r(_,e=>{s(`loadingStatusChange`,e),e!==`idle`&&(m.imageLoadingStatus.value=e)},{immediate:!0}),(t,r)=>e((n(),l(h(b),{role:`img`,"as-child":t.asChild,as:t.as,src:h(d),referrerpolicy:h(f),crossorigin:h(p)},{default:o(()=>[g(t.$slots,`default`)]),_:3},8,[`as-child`,`as`,`src`,`referrerpolicy`,`crossorigin`])),[[c,h(_)===`loaded`]])}}),O=p({__name:`Avatar`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,r)=>(n(),l(h(w),{"data-slot":`avatar`,class:m(h(v)(`relative flex size-8 shrink-0 overflow-hidden rounded-full`,t.class))},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`class`]))}}),k=p({__name:`AvatarImage`,props:{src:{},referrerPolicy:{},crossOrigin:{},asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,i)=>(n(),l(h(D),t({"data-slot":`avatar-image`},r,{class:`aspect-square size-full`}),{default:o(()=>[g(e.$slots,`default`)]),_:3},16))}});export{O as n,S as r,k as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-De70L21J.js";import{i as l,r as u}from"./button-DveXNdlZ.js";var d=u(`inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90`,secondary:`border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90`,destructive:`border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground`}},defaultVariants:{variant:`default`}}),f=i({__name:`Badge`,props:{asChild:{type:Boolean},as:{},variant:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,f=s(u,`class`);return(s,p)=>(t(),r(a(l),e({"data-slot":`badge`,class:a(c)(a(d)({variant:i.variant}),u.class)},a(f)),{default:n(()=>[o(s.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{i as l,r as u}from"./button-BTKRNUhQ.js";var d=u(`inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90`,secondary:`border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90`,destructive:`border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground`}},defaultVariants:{variant:`default`}}),f=i({__name:`Badge`,props:{asChild:{type:Boolean},as:{},variant:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,f=s(u,`class`);return(s,p)=>(t(),r(a(l),e({"data-slot":`badge`,class:a(c)(a(d)({variant:i.variant}),u.class)},a(f)),{default:n(()=>[o(s.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-De70L21J.js";var s=n({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card`,class:r(i(o)(`bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card`,class:r(i(o)(`bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-De70L21J.js";var s=n({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-content`,class:r(i(o)(`px-6`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-content`,class:r(i(o)(`px-6`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-De70L21J.js";var s=n({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-header`,class:r(i(o)(`@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,s.class))},[a(n.$slots,`default`)],2))}}),c=n({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`p`,{"data-slot":`card-description`,class:r(i(o)(`text-muted-foreground text-sm`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`h3`,{"data-slot":`card-title`,class:r(i(o)(`leading-none font-semibold`,s.class))},[a(n.$slots,`default`)],2))}});export{c as n,s as r,l as t};
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-header`,class:r(i(o)(`@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,s.class))},[a(n.$slots,`default`)],2))}}),c=n({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`p`,{"data-slot":`card-description`,class:r(i(o)(`text-muted-foreground text-sm`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`h3`,{"data-slot":`card-title`,class:r(i(o)(`leading-none font-semibold`,s.class))},[a(n.$slots,`default`)],2))}});export{c as n,s as r,l as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,C as t,I as n,Q as r,St as i,V as a,_ as o,b as s,g as c,m as l,o as u,s as d,x as f,yt as p,z as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as h,p as g}from"./dist-3yfE1dPa.js";import{o as _}from"./SelectValue-BHFTqCZG.js";import{J as v}from"./index-De70L21J.js";import{n as y,r as b}from"./VisuallyHidden-Bt6f1zl_.js";import{O as x,T as S,g as C,y as w}from"./Teleport-DzgMZwe8.js";import{i as T}from"./button-DveXNdlZ.js";import{t as E}from"./useForwardExpose-CNhbE6SX.js";import{t as D}from"./VisuallyHiddenInput-DMuZ1Evg.js";import{t as O}from"./RovingFocusItem-CMmJUGZJ.js";function k(e,t){return S(e)?!1:Array.isArray(e)?e.some(e=>b(e,t)):b(e,t)}var[A,j]=x(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=x(`CheckboxRoot`),I=f({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(t,{emit:i}){let s=t,f=i,{forwardRef:h,currentElement:_}=E(),v=A(null),x=g(s,`modelValue`,f,{defaultValue:s.defaultValue??s.falseValue,passive:s.modelValue===void 0}),C=l(()=>v?.disabled.value||s.disabled),w=l(()=>b(x.value,s.trueValue)),j=l(()=>S(v?.modelValue.value)?x.value===`indeterminate`?`indeterminate`:w.value:k(v.modelValue.value,s.value));function P(){if(S(v?.modelValue.value))x.value===`indeterminate`?x.value=s.trueValue:x.value=w.value?s.falseValue:s.trueValue;else{let e=[...v.modelValue.value||[]];if(k(e,s.value)){let t=e.findIndex(e=>b(e,s.value));e.splice(t,1)}else e.push(s.value);v.modelValue.value=e}}let I=y(_),L=l(()=>s.id&&_.value?document.querySelector(`[for="${s.id}"]`)?.innerText:void 0);return F({disabled:C,state:j}),(t,i)=>(n(),c(a(p(v)?.rovingFocus.value?p(O):p(T)),e(t.$attrs,{id:t.id,ref:p(h),role:`checkbox`,"as-child":t.asChild,as:t.as,type:t.as===`button`?`button`:void 0,"aria-checked":p(M)(j.value)?`mixed`:j.value,"aria-required":t.required,"aria-label":t.$attrs[`aria-label`]||L.value,"data-state":p(N)(j.value),"data-disabled":C.value?``:void 0,disabled:C.value,focusable:p(v)?.rovingFocus.value?!C.value:void 0,onKeydown:u(d(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:r(()=>[m(t.$slots,`default`,{modelValue:p(x),state:j.value}),p(I)&&t.name&&!p(v)?(n(),c(p(D),{key:0,type:`checkbox`,checked:!!j.value,name:t.name,value:t.value,disabled:C.value,required:t.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=f({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(t){let{forwardRef:i}=E(),a=P();return(t,o)=>(n(),c(p(C),{present:t.forceMount||p(M)(p(a).state.value)||p(a).state.value===!0},{default:r(()=>[s(p(T),e({ref:p(i),"data-state":p(N)(p(a).state.value),"data-disabled":p(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":t.asChild,as:t.as},t.$attrs),{default:r(()=>[m(t.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=f({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:o}){let l=a,u=o,d=w(h(l,`class`),u);return(a,o)=>(n(),c(p(I),e({"data-slot":`checkbox`},p(d),{class:p(v)(`peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,l.class)}),{default:r(e=>[s(p(L),{"data-slot":`checkbox-indicator`,class:`grid place-content-center text-current transition-none`},{default:r(()=>[m(a.$slots,`default`,i(t(e)),()=>[s(p(_),{class:`size-3.5`})])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
|
||||
import{A as e,C as t,I as n,Q as r,St as i,V as a,_ as o,b as s,g as c,m as l,o as u,s as d,x as f,yt as p,z as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as h,p as g}from"./dist-3yfE1dPa.js";import{o as _}from"./SelectValue-By3tfEiu.js";import{J as v}from"./index-BpHHjIYv.js";import{n as y,r as b}from"./VisuallyHidden-_sQ0xQ9O.js";import{O as x,T as S,g as C,y as w}from"./Teleport-qOjHMYM8.js";import{i as T}from"./button-BTKRNUhQ.js";import{t as E}from"./useForwardExpose-CNhbE6SX.js";import{t as D}from"./VisuallyHiddenInput-CE3zkTxY.js";import{t as O}from"./RovingFocusItem-BInhij-V.js";function k(e,t){return S(e)?!1:Array.isArray(e)?e.some(e=>b(e,t)):b(e,t)}var[A,j]=x(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=x(`CheckboxRoot`),I=f({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(t,{emit:i}){let s=t,f=i,{forwardRef:h,currentElement:_}=E(),v=A(null),x=g(s,`modelValue`,f,{defaultValue:s.defaultValue??s.falseValue,passive:s.modelValue===void 0}),C=l(()=>v?.disabled.value||s.disabled),w=l(()=>b(x.value,s.trueValue)),j=l(()=>S(v?.modelValue.value)?x.value===`indeterminate`?`indeterminate`:w.value:k(v.modelValue.value,s.value));function P(){if(S(v?.modelValue.value))x.value===`indeterminate`?x.value=s.trueValue:x.value=w.value?s.falseValue:s.trueValue;else{let e=[...v.modelValue.value||[]];if(k(e,s.value)){let t=e.findIndex(e=>b(e,s.value));e.splice(t,1)}else e.push(s.value);v.modelValue.value=e}}let I=y(_),L=l(()=>s.id&&_.value?document.querySelector(`[for="${s.id}"]`)?.innerText:void 0);return F({disabled:C,state:j}),(t,i)=>(n(),c(a(p(v)?.rovingFocus.value?p(O):p(T)),e(t.$attrs,{id:t.id,ref:p(h),role:`checkbox`,"as-child":t.asChild,as:t.as,type:t.as===`button`?`button`:void 0,"aria-checked":p(M)(j.value)?`mixed`:j.value,"aria-required":t.required,"aria-label":t.$attrs[`aria-label`]||L.value,"data-state":p(N)(j.value),"data-disabled":C.value?``:void 0,disabled:C.value,focusable:p(v)?.rovingFocus.value?!C.value:void 0,onKeydown:u(d(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:r(()=>[m(t.$slots,`default`,{modelValue:p(x),state:j.value}),p(I)&&t.name&&!p(v)?(n(),c(p(D),{key:0,type:`checkbox`,checked:!!j.value,name:t.name,value:t.value,disabled:C.value,required:t.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=f({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(t){let{forwardRef:i}=E(),a=P();return(t,o)=>(n(),c(p(C),{present:t.forceMount||p(M)(p(a).state.value)||p(a).state.value===!0},{default:r(()=>[s(p(T),e({ref:p(i),"data-state":p(N)(p(a).state.value),"data-disabled":p(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":t.asChild,as:t.as},t.$attrs),{default:r(()=>[m(t.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=f({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:o}){let l=a,u=o,d=w(h(l,`class`),u);return(a,o)=>(n(),c(p(I),e({"data-slot":`checkbox`},p(d),{class:p(v)(`peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,l.class)}),{default:r(e=>[s(p(L),{"data-slot":`checkbox-indicator`,class:`grid place-content-center text-current transition-none`},{default:r(()=>[m(a.$slots,`default`,i(t(e)),()=>[s(p(_),{class:`size-3.5`})])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-De70L21J.js";import{b as l}from"./Teleport-DzgMZwe8.js";import{i as u}from"./button-DveXNdlZ.js";import{t as d}from"./useForwardExpose-CNhbE6SX.js";import{d as f}from"./DialogTitle-DtKBAtxD.js";var p=i({__name:`DialogDescription`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`p`}},setup(i){let s=i;d();let c=f();return(i,l)=>(t(),r(a(u),e(s,{id:a(c).descriptionId}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`id`]))}}),m=i({__name:`DialogDescription`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,d=l(s(u,`class`));return(i,s)=>(t(),r(a(p),e({"data-slot":`dialog-description`},a(d),{class:a(c)(`text-muted-foreground text-sm`,u.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{p as n,m as t};
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{b as l}from"./Teleport-qOjHMYM8.js";import{i as u}from"./button-BTKRNUhQ.js";import{t as d}from"./useForwardExpose-CNhbE6SX.js";import{d as f}from"./DialogTitle-Do1F-aV6.js";var p=i({__name:`DialogDescription`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`p`}},setup(i){let s=i;d();let c=f();return(i,l)=>(t(),r(a(u),e(s,{id:a(c).descriptionId}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`id`]))}}),m=i({__name:`DialogDescription`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,d=l(s(u,`class`));return(i,s)=>(t(),r(a(p),e({"data-slot":`dialog-description`},a(d),{class:a(c)(`text-muted-foreground text-sm`,u.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{p as n,m as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-De70L21J.js";var s=n({__name:`DialogFooter`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`dialog-footer`,class:r(i(o)(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`DialogFooter`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`dialog-footer`,class:r(i(o)(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,ut as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-De70L21J.js";import{O as p,_ as m,b as h,d as g,g as _,l as v}from"./Teleport-DzgMZwe8.js";import{i as y}from"./button-DveXNdlZ.js";import{t as b}from"./useForwardExpose-CNhbE6SX.js";var[x,S]=p([`MenuCheckboxItem`,`MenuRadioItem`],`MenuItemIndicatorContext`),C=c({__name:`MenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let t=x({modelValue:s(!1)});return(e,i)=>(n(),o(l(_),{present:e.forceMount||l(g)(l(t).modelValue.value)||l(t).modelValue.value===!0},{default:r(()=>[a(l(y),{as:e.as,"as-child":e.asChild,"data-state":l(v)(l(t).modelValue.value)},{default:r(()=>[u(e.$slots,`default`)]),_:3},8,[`as`,`as-child`,`data-state`])]),_:3},8,[`present`]))}}),[w,T]=p(`MenuGroup`),E=c({__name:`MenuGroup`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,a=m(void 0,`reka-menu-group`);return T({id:a}),(t,s)=>(n(),o(l(y),e({role:`group`},i,{"aria-labelledby":l(a)}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`aria-labelledby`]))}}),D=c({__name:`MenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`div`}},setup(t){let i=t,a=w({id:``});return(t,s)=>(n(),o(l(y),e(i,{id:l(a).id||void 0}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`id`]))}}),O=c({__name:`MenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t;return(t,a)=>(n(),o(l(y),e(i,{role:`separator`,"aria-orientation":`horizontal`}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16))}}),k=c({__name:`DropdownMenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(C),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),A=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(D),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),j=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(O),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),M=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=d(r,`class`);return(t,a)=>(n(),o(l(j),e({"data-slot":`dropdown-menu-separator`},l(i),{class:l(f)(`bg-border -mx-1 my-1 h-px`,r.class)}),null,16,[`class`]))}}),N=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]},inset:{type:Boolean}},setup(t){let i=t,a=h(d(i,`class`,`inset`));return(s,c)=>(n(),o(l(A),e({"data-slot":`dropdown-menu-label`,"data-inset":t.inset?``:void 0},l(a),{class:l(f)(`px-2 py-1.5 text-sm font-medium data-[inset]:pl-8`,i.class)}),{default:r(()=>[u(s.$slots,`default`)]),_:3},16,[`data-inset`,`class`]))}});export{S as a,E as i,M as n,k as r,N as t};
|
||||
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,ut as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-BpHHjIYv.js";import{O as p,_ as m,b as h,d as g,g as _,l as v}from"./Teleport-qOjHMYM8.js";import{i as y}from"./button-BTKRNUhQ.js";import{t as b}from"./useForwardExpose-CNhbE6SX.js";var[x,S]=p([`MenuCheckboxItem`,`MenuRadioItem`],`MenuItemIndicatorContext`),C=c({__name:`MenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let t=x({modelValue:s(!1)});return(e,i)=>(n(),o(l(_),{present:e.forceMount||l(g)(l(t).modelValue.value)||l(t).modelValue.value===!0},{default:r(()=>[a(l(y),{as:e.as,"as-child":e.asChild,"data-state":l(v)(l(t).modelValue.value)},{default:r(()=>[u(e.$slots,`default`)]),_:3},8,[`as`,`as-child`,`data-state`])]),_:3},8,[`present`]))}}),[w,T]=p(`MenuGroup`),E=c({__name:`MenuGroup`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,a=m(void 0,`reka-menu-group`);return T({id:a}),(t,s)=>(n(),o(l(y),e({role:`group`},i,{"aria-labelledby":l(a)}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`aria-labelledby`]))}}),D=c({__name:`MenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`div`}},setup(t){let i=t,a=w({id:``});return(t,s)=>(n(),o(l(y),e(i,{id:l(a).id||void 0}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`id`]))}}),O=c({__name:`MenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t;return(t,a)=>(n(),o(l(y),e(i,{role:`separator`,"aria-orientation":`horizontal`}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16))}}),k=c({__name:`DropdownMenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(C),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),A=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(D),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),j=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(O),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),M=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=d(r,`class`);return(t,a)=>(n(),o(l(j),e({"data-slot":`dropdown-menu-separator`},l(i),{class:l(f)(`bg-border -mx-1 my-1 h-px`,r.class)}),null,16,[`class`]))}}),N=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]},inset:{type:Boolean}},setup(t){let i=t,a=h(d(i,`class`,`inset`));return(s,c)=>(n(),o(l(A),e({"data-slot":`dropdown-menu-label`,"data-inset":t.inset?``:void 0},l(a),{class:l(f)(`px-2 py-1.5 text-sm font-medium data-[inset]:pl-8`,i.class)}),{default:r(()=>[u(s.$slots,`default`)]),_:3},16,[`data-inset`,`class`]))}});export{S as a,E as i,M as n,k as r,N as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,gt as s,h as c,m as l,x as u,yt as d,z as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as p,p as m}from"./dist-3yfE1dPa.js";import{t as h}from"./circle-Cc5GzalR.js";import{J as g}from"./index-De70L21J.js";import{O as _,b as v,l as y,x as b,y as x}from"./Teleport-DzgMZwe8.js";import{a as S}from"./DropdownMenuTrigger-CvM5INxe.js";import{t as C}from"./useForwardExpose-CNhbE6SX.js";import{a as w,i as T,r as E}from"./DropdownMenuLabel-D34bF97h.js";var[D,O]=_(`MenuRadioGroup`),k=u({__name:`MenuRadioGroup`,props:{modelValue:{type:null,required:!1,default:``},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=a,l=v(p(s,[`modelValue`])),u=m(s,`modelValue`,c);return O({modelValue:u,onValueChange:e=>{u.value=e}}),(e,a)=>(n(),o(T,i(t(d(l))),{default:r(()=>[f(e.$slots,`default`,{modelValue:d(u)})]),_:3},16))}}),A=u({__name:`MenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(t,{emit:i}){let a=t,c=i,u=v(p(a,[`value`])),{value:m}=s(a),h=D(),g=l(()=>h.modelValue.value===m?.value);return w({modelValue:g}),(t,i)=>(n(),o(S,e({role:`menuitemradio`},d(u),{"aria-checked":g.value,"data-state":d(y)(g.value),onSelect:i[0]||=async e=>{c(`select`,e),d(h).onValueChange(d(m))}}),{default:r(()=>[f(t.$slots,`default`)]),_:3},16,[`aria-checked`,`data-state`]))}}),j=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=b(a);return C(),(e,a)=>(n(),o(d(k),i(t({...s,...d(c)})),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),M=u({__name:`DropdownMenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(e,{emit:a}){let s=x(e,a);return C(),(e,a)=>(n(),o(d(A),i(t(d(s))),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),N=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{},asChild:{type:Boolean},as:{}},emits:[`update:modelValue`],setup(t,{emit:i}){let a=x(t,i);return(t,i)=>(n(),o(d(j),e({"data-slot":`dropdown-menu-radio-group`},d(a)),{default:r(()=>[f(t.$slots,`default`)]),_:3},16))}}),P={class:`pointer-events-none absolute left-2 flex size-3.5 items-center justify-center`},F=u({__name:`DropdownMenuRadioItem`,props:{value:{},disabled:{type:Boolean},textValue:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`select`],setup(t,{emit:i}){let s=t,l=i,u=x(p(s,`class`),l);return(t,i)=>(n(),o(d(M),e({"data-slot":`dropdown-menu-radio-item`},d(u),{class:d(g)(`focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,s.class)}),{default:r(()=>[c(`span`,P,[a(d(E),null,{default:r(()=>[f(t.$slots,`indicator-icon`,{},()=>[a(d(h),{class:`size-2 fill-current`})])]),_:3})]),f(t.$slots,`default`)]),_:3},16,[`class`]))}});export{N as n,F as t};
|
||||
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,gt as s,h as c,m as l,x as u,yt as d,z as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as p,p as m}from"./dist-3yfE1dPa.js";import{t as h}from"./circle-Cc5GzalR.js";import{J as g}from"./index-BpHHjIYv.js";import{O as _,b as v,l as y,x as b,y as x}from"./Teleport-qOjHMYM8.js";import{a as S}from"./DropdownMenuTrigger-Dmk4lbKz.js";import{t as C}from"./useForwardExpose-CNhbE6SX.js";import{a as w,i as T,r as E}from"./DropdownMenuLabel-Bls_J4kr.js";var[D,O]=_(`MenuRadioGroup`),k=u({__name:`MenuRadioGroup`,props:{modelValue:{type:null,required:!1,default:``},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=a,l=v(p(s,[`modelValue`])),u=m(s,`modelValue`,c);return O({modelValue:u,onValueChange:e=>{u.value=e}}),(e,a)=>(n(),o(T,i(t(d(l))),{default:r(()=>[f(e.$slots,`default`,{modelValue:d(u)})]),_:3},16))}}),A=u({__name:`MenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(t,{emit:i}){let a=t,c=i,u=v(p(a,[`value`])),{value:m}=s(a),h=D(),g=l(()=>h.modelValue.value===m?.value);return w({modelValue:g}),(t,i)=>(n(),o(S,e({role:`menuitemradio`},d(u),{"aria-checked":g.value,"data-state":d(y)(g.value),onSelect:i[0]||=async e=>{c(`select`,e),d(h).onValueChange(d(m))}}),{default:r(()=>[f(t.$slots,`default`)]),_:3},16,[`aria-checked`,`data-state`]))}}),j=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=b(a);return C(),(e,a)=>(n(),o(d(k),i(t({...s,...d(c)})),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),M=u({__name:`DropdownMenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(e,{emit:a}){let s=x(e,a);return C(),(e,a)=>(n(),o(d(A),i(t(d(s))),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),N=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{},asChild:{type:Boolean},as:{}},emits:[`update:modelValue`],setup(t,{emit:i}){let a=x(t,i);return(t,i)=>(n(),o(d(j),e({"data-slot":`dropdown-menu-radio-group`},d(a)),{default:r(()=>[f(t.$slots,`default`)]),_:3},16))}}),P={class:`pointer-events-none absolute left-2 flex size-3.5 items-center justify-center`},F=u({__name:`DropdownMenuRadioItem`,props:{value:{},disabled:{type:Boolean},textValue:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`select`],setup(t,{emit:i}){let s=t,l=i,u=x(p(s,`class`),l);return(t,i)=>(n(),o(d(M),e({"data-slot":`dropdown-menu-radio-item`},d(u),{class:d(g)(`focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,s.class)}),{default:r(()=>[c(`span`,P,[a(d(E),null,{default:r(()=>[f(t.$slots,`indicator-icon`,{},()=>[a(d(h),{class:`size-2 fill-current`})])]),_:3})]),f(t.$slots,`default`)]),_:3},16,[`class`]))}});export{N as n,F as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{$ as e,I as t,at as n,i as r,v as i,x as a,xt as o,yt as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as c}from"./dist-3yfE1dPa.js";import{J as l}from"./index-De70L21J.js";var u=a({__name:`Input`,props:{defaultValue:{},modelValue:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:u}){let d=a,f=c(d,`modelValue`,u,{passive:!0,defaultValue:d.defaultValue});return(a,c)=>e((t(),i(`input`,{"onUpdate:modelValue":c[0]||=e=>n(f)?f.value=e:null,"data-slot":`input`,class:o(s(l)(`file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]`,`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,d.class))},null,2)),[[r,s(f)]])}});export{u as t};
|
||||
import{$ as e,I as t,at as n,i as r,v as i,x as a,xt as o,yt as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as c}from"./dist-3yfE1dPa.js";import{J as l}from"./index-BpHHjIYv.js";var u=a({__name:`Input`,props:{defaultValue:{},modelValue:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:u}){let d=a,f=c(d,`modelValue`,u,{passive:!0,defaultValue:d.defaultValue});return(a,c)=>e((t(),i(`input`,{"onUpdate:modelValue":c[0]||=e=>n(f)?f.value=e:null,"data-slot":`input`,class:o(s(l)(`file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]`,`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,d.class))},null,2)),[[r,s(f)]])}});export{u as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-De70L21J.js";import{i as l}from"./button-DveXNdlZ.js";import{t as u}from"./useForwardExpose-CNhbE6SX.js";var d=i({__name:`Label`,props:{for:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`label`}},setup(i){let s=i;return u(),(i,c)=>(t(),r(a(l),e(s,{onMousedown:c[0]||=e=>{!e.defaultPrevented&&e.detail>1&&e.preventDefault()}}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16))}}),f=i({__name:`Label`,props:{for:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let l=i,u=s(l,`class`);return(i,s)=>(t(),r(a(d),e({"data-slot":`label`},a(u),{class:a(c)(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,l.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
|
||||
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{i as l}from"./button-BTKRNUhQ.js";import{t as u}from"./useForwardExpose-CNhbE6SX.js";var d=i({__name:`Label`,props:{for:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`label`}},setup(i){let s=i;return u(),(i,c)=>(t(),r(a(l),e(s,{onMousedown:c[0]||=e=>{!e.defaultPrevented&&e.detail>1&&e.preventDefault()}}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16))}}),f=i({__name:`Label`,props:{for:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let l=i,u=s(l,`class`);return(i,s)=>(t(),r(a(d),e({"data-slot":`label`},a(u),{class:a(c)(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,l.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{I as e,Q as t,b as n,g as r,gt as i,ut as a,x as o,yt as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as l}from"./dist-3yfE1dPa.js";import{D as u,O as d}from"./Teleport-DzgMZwe8.js";import{i as f}from"./button-DveXNdlZ.js";import{o as p,u as m}from"./PopperContent-DR7IJ4Zs.js";var h=`rovingFocusGroup.onEntryFocus`,g={bubbles:!1,cancelable:!0},_={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function v(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function y(e,t,n){let r=v(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return _[r]}function b(e,t=!1){let n=u();for(let r of e)if(r===n||(r.focus({preventScroll:t}),u()!==n))return}function x(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var[S,C]=d(`RovingFocusGroup`),w=o({__name:`RovingFocusGroup`,props:{orientation:{type:String,required:!1,default:void 0},dir:{type:String,required:!1},loop:{type:Boolean,required:!1,default:!1},currentTabStopId:{type:[String,null],required:!1},defaultCurrentTabStopId:{type:String,required:!1},preventScrollOnEntryFocus:{type:Boolean,required:!1,default:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`entryFocus`,`update:currentTabStopId`],setup(o,{expose:u,emit:d}){let _=o,v=d,{loop:y,orientation:x,dir:S}=i(_),w=m(S),T=l(_,`currentTabStopId`,v,{defaultValue:_.defaultCurrentTabStopId,passive:_.currentTabStopId===void 0}),E=a(!1),D=a(!1),O=a(0),{getItems:k,CollectionSlot:A}=p({isProvider:!0});function j(e){let t=!D.value;if(e.currentTarget&&e.target===e.currentTarget&&t&&!E.value){let t=new CustomEvent(h,g);if(e.currentTarget.dispatchEvent(t),v(`entryFocus`,t),!t.defaultPrevented){let e=k().map(e=>e.ref).filter(e=>e.dataset.disabled!==``);b([e.find(e=>e.getAttribute(`data-active`)===``),e.find(e=>e.getAttribute(`data-highlighted`)===``),e.find(e=>e.id===T.value),...e].filter(Boolean),_.preventScrollOnEntryFocus)}}D.value=!1}function M(){setTimeout(()=>{D.value=!1},1)}return u({getItems:k}),C({loop:y,dir:w,orientation:x,currentTabStopId:T,onItemFocus:e=>{T.value=e},onItemShiftTab:()=>{E.value=!0},onFocusableItemAdd:()=>{O.value++},onFocusableItemRemove:()=>{O.value--}}),(i,a)=>(e(),r(s(A),null,{default:t(()=>[n(s(f),{tabindex:E.value||O.value===0?-1:0,"data-orientation":s(x),as:i.as,"as-child":i.asChild,dir:s(w),style:{outline:`none`},onMousedown:a[0]||=e=>D.value=!0,onMouseup:M,onFocus:j,onBlur:a[1]||=e=>E.value=!1},{default:t(()=>[c(i.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`as`,`as-child`,`dir`])]),_:3}))}});export{x as a,y as i,S as n,b as r,w as t};
|
||||
import{I as e,Q as t,b as n,g as r,gt as i,ut as a,x as o,yt as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as l}from"./dist-3yfE1dPa.js";import{D as u,O as d}from"./Teleport-qOjHMYM8.js";import{i as f}from"./button-BTKRNUhQ.js";import{o as p,u as m}from"./PopperContent-oFiuPLDs.js";var h=`rovingFocusGroup.onEntryFocus`,g={bubbles:!1,cancelable:!0},_={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function v(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function y(e,t,n){let r=v(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return _[r]}function b(e,t=!1){let n=u();for(let r of e)if(r===n||(r.focus({preventScroll:t}),u()!==n))return}function x(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var[S,C]=d(`RovingFocusGroup`),w=o({__name:`RovingFocusGroup`,props:{orientation:{type:String,required:!1,default:void 0},dir:{type:String,required:!1},loop:{type:Boolean,required:!1,default:!1},currentTabStopId:{type:[String,null],required:!1},defaultCurrentTabStopId:{type:String,required:!1},preventScrollOnEntryFocus:{type:Boolean,required:!1,default:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`entryFocus`,`update:currentTabStopId`],setup(o,{expose:u,emit:d}){let _=o,v=d,{loop:y,orientation:x,dir:S}=i(_),w=m(S),T=l(_,`currentTabStopId`,v,{defaultValue:_.defaultCurrentTabStopId,passive:_.currentTabStopId===void 0}),E=a(!1),D=a(!1),O=a(0),{getItems:k,CollectionSlot:A}=p({isProvider:!0});function j(e){let t=!D.value;if(e.currentTarget&&e.target===e.currentTarget&&t&&!E.value){let t=new CustomEvent(h,g);if(e.currentTarget.dispatchEvent(t),v(`entryFocus`,t),!t.defaultPrevented){let e=k().map(e=>e.ref).filter(e=>e.dataset.disabled!==``);b([e.find(e=>e.getAttribute(`data-active`)===``),e.find(e=>e.getAttribute(`data-highlighted`)===``),e.find(e=>e.id===T.value),...e].filter(Boolean),_.preventScrollOnEntryFocus)}}D.value=!1}function M(){setTimeout(()=>{D.value=!1},1)}return u({getItems:k}),C({loop:y,dir:w,orientation:x,currentTabStopId:T,onItemFocus:e=>{T.value=e},onItemShiftTab:()=>{E.value=!0},onFocusableItemAdd:()=>{O.value++},onFocusableItemRemove:()=>{O.value--}}),(i,a)=>(e(),r(s(A),null,{default:t(()=>[n(s(f),{tabindex:E.value||O.value===0?-1:0,"data-orientation":s(x),as:i.as,"as-child":i.asChild,dir:s(w),style:{outline:`none`},onMousedown:a[0]||=e=>D.value=!0,onMouseup:M,onFocus:j,onBlur:a[1]||=e=>E.value=!1},{default:t(()=>[c(i.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`as`,`as-child`,`dir`])]),_:3}))}});export{x as a,y as i,S as n,b as r,w as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,N as t,P as n,Q as r,b as i,g as a,j as o,m as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{_ as d}from"./Teleport-DzgMZwe8.js";import{i as f}from"./button-DveXNdlZ.js";import{o as p}from"./PopperContent-DR7IJ4Zs.js";import{a as m,i as h,n as g,r as _}from"./RovingFocusGroup-Bx77j9bL.js";var v=c({__name:`RovingFocusItem`,props:{tabStopId:{type:String,required:!1},focusable:{type:Boolean,required:!1,default:!0},active:{type:Boolean,required:!1},allowShiftKey:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(c){let v=c,y=g(),b=d(),x=s(()=>v.tabStopId||b),S=s(()=>y.currentTabStopId.value===x.value),{getItems:C,CollectionItem:w}=p();t(()=>{v.focusable&&y.onFocusableItemAdd()}),n(()=>{v.focusable&&y.onFocusableItemRemove()});function T(e){if(e.key===`Tab`&&e.shiftKey){y.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=h(e,y.orientation.value,y.dir.value);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||!v.allowShiftKey&&e.shiftKey)return;e.preventDefault();let n=[...C().map(e=>e.ref).filter(e=>e.dataset.disabled!==``)];if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=y.loop.value?m(n,r+1):n.slice(r+1)}o(()=>_(n))}}return(t,n)=>(e(),a(l(w),null,{default:r(()=>[i(l(f),{tabindex:S.value?0:-1,"data-orientation":l(y).orientation.value,"data-active":t.active?``:void 0,"data-disabled":t.focusable?void 0:``,as:t.as,"as-child":t.asChild,onMousedown:n[0]||=e=>{t.focusable?l(y).onItemFocus(x.value):e.preventDefault()},onFocus:n[1]||=e=>l(y).onItemFocus(x.value),onKeydown:T},{default:r(()=>[u(t.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`data-active`,`data-disabled`,`as`,`as-child`])]),_:3}))}});export{v as t};
|
||||
import{I as e,N as t,P as n,Q as r,b as i,g as a,j as o,m as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{_ as d}from"./Teleport-qOjHMYM8.js";import{i as f}from"./button-BTKRNUhQ.js";import{o as p}from"./PopperContent-oFiuPLDs.js";import{a as m,i as h,n as g,r as _}from"./RovingFocusGroup--sGcMhFA.js";var v=c({__name:`RovingFocusItem`,props:{tabStopId:{type:String,required:!1},focusable:{type:Boolean,required:!1,default:!0},active:{type:Boolean,required:!1},allowShiftKey:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(c){let v=c,y=g(),b=d(),x=s(()=>v.tabStopId||b),S=s(()=>y.currentTabStopId.value===x.value),{getItems:C,CollectionItem:w}=p();t(()=>{v.focusable&&y.onFocusableItemAdd()}),n(()=>{v.focusable&&y.onFocusableItemRemove()});function T(e){if(e.key===`Tab`&&e.shiftKey){y.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=h(e,y.orientation.value,y.dir.value);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||!v.allowShiftKey&&e.shiftKey)return;e.preventDefault();let n=[...C().map(e=>e.ref).filter(e=>e.dataset.disabled!==``)];if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=y.loop.value?m(n,r+1):n.slice(r+1)}o(()=>_(n))}}return(t,n)=>(e(),a(l(w),null,{default:r(()=>[i(l(f),{tabindex:S.value?0:-1,"data-orientation":l(y).orientation.value,"data-active":t.active?``:void 0,"data-disabled":t.focusable?void 0:``,as:t.as,"as-child":t.asChild,onMousedown:n[0]||=e=>{t.focusable?l(y).onItemFocus(x.value):e.preventDefault()},onFocus:n[1]||=e=>l(y).onItemFocus(x.value),onKeydown:T},{default:r(()=>[u(t.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`data-active`,`data-disabled`,`as`,`as-child`])]),_:3}))}});export{v as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{A as e,C as t,I as n,Q as r,St as i,g as a,m as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u}from"./dist-3yfE1dPa.js";import{J as d}from"./index-De70L21J.js";import{i as f}from"./button-DveXNdlZ.js";var p=s({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,s=[`horizontal`,`vertical`];function u(e){return s.includes(e)}let d=o(()=>u(i.orientation)?i.orientation:`horizontal`),p=o(()=>d.value===`vertical`?i.orientation:void 0),m=o(()=>i.decorative?{role:`none`}:{"aria-orientation":p.value,role:`separator`});return(t,i)=>(n(),a(c(f),e({as:t.as,"as-child":t.asChild,"data-orientation":d.value},m.value),{default:r(()=>[l(t.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),m=s({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let o=e;return(e,s)=>(n(),a(p,i(t(o)),{default:r(()=>[l(e.$slots,`default`)]),_:3},16))}}),h=s({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=u(r,`class`);return(t,o)=>(n(),a(c(m),e({"data-slot":`separator`},c(i),{class:c(d)(`bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,r.class)}),null,16,[`class`]))}});export{m as n,h as t};
|
||||
import{A as e,C as t,I as n,Q as r,St as i,g as a,m as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u}from"./dist-3yfE1dPa.js";import{J as d}from"./index-BpHHjIYv.js";import{i as f}from"./button-BTKRNUhQ.js";var p=s({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,s=[`horizontal`,`vertical`];function u(e){return s.includes(e)}let d=o(()=>u(i.orientation)?i.orientation:`horizontal`),p=o(()=>d.value===`vertical`?i.orientation:void 0),m=o(()=>i.decorative?{role:`none`}:{"aria-orientation":p.value,role:`separator`});return(t,i)=>(n(),a(c(f),e({as:t.as,"as-child":t.asChild,"data-orientation":d.value},m.value),{default:r(()=>[l(t.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),m=s({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let o=e;return(e,s)=>(n(),a(p,i(t(o)),{default:r(()=>[l(e.$slots,`default`)]),_:3},16))}}),h=s({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=u(r,`class`);return(t,o)=>(n(),a(c(m),e({"data-slot":`separator`},c(i),{class:c(d)(`bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,r.class)}),null,16,[`class`]))}});export{m as n,h as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,h as t,v as n,x as r,xt as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as s}from"./index-De70L21J.js";var c={"data-slot":`table-container`,class:`relative w-full overflow-auto`},l=r({__name:`Table`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let l=r;return(r,u)=>(e(),n(`div`,c,[t(`table`,{"data-slot":`table`,class:i(a(s)(`w-full caption-bottom text-sm`,l.class))},[o(r.$slots,`default`)],2)]))}}),u=r({__name:`TableBody`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tbody`,{"data-slot":`table-body`,class:i(a(s)(`[&_tr:last-child]:border-0`,r.class))},[o(t.$slots,`default`)],2))}}),d=r({__name:`TableCell`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`td`,{"data-slot":`table-cell`,class:i(a(s)(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}}),f=r({__name:`TableHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`thead`,{"data-slot":`table-header`,class:i(a(s)(`[&_tr]:border-b`,r.class))},[o(t.$slots,`default`)],2))}}),p=r({__name:`TableRow`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tr`,{"data-slot":`table-row`,class:i(a(s)(`hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors`,r.class))},[o(t.$slots,`default`)],2))}}),m=r({__name:`TableHead`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`th`,{"data-slot":`table-head`,class:i(a(s)(`text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}});export{u as a,d as i,p as n,l as o,f as r,m as t};
|
||||
import{I as e,h as t,v as n,x as r,xt as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as s}from"./index-BpHHjIYv.js";var c={"data-slot":`table-container`,class:`relative w-full overflow-auto`},l=r({__name:`Table`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let l=r;return(r,u)=>(e(),n(`div`,c,[t(`table`,{"data-slot":`table`,class:i(a(s)(`w-full caption-bottom text-sm`,l.class))},[o(r.$slots,`default`)],2)]))}}),u=r({__name:`TableBody`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tbody`,{"data-slot":`table-body`,class:i(a(s)(`[&_tr:last-child]:border-0`,r.class))},[o(t.$slots,`default`)],2))}}),d=r({__name:`TableCell`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`td`,{"data-slot":`table-cell`,class:i(a(s)(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}}),f=r({__name:`TableHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`thead`,{"data-slot":`table-header`,class:i(a(s)(`[&_tr]:border-b`,r.class))},[o(t.$slots,`default`)],2))}}),p=r({__name:`TableRow`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tr`,{"data-slot":`table-row`,class:i(a(s)(`hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors`,r.class))},[o(t.$slots,`default`)],2))}}),m=r({__name:`TableHead`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`th`,{"data-slot":`table-head`,class:i(a(s)(`text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}});export{u as a,d as i,p as n,l as o,f as r,m as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{I as e,Q as t,_t as n,g as r,m as i,x as a,yt as o,z as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{i as c}from"./dist-3yfE1dPa.js";import{i as l}from"./button-DveXNdlZ.js";function u(e){return typeof e==`string`?`'${e}'`:new d().serialize(e)}var d=function(){class e{#e=new Map;compare(e,t){let n=typeof e,r=typeof t;return n===`string`&&r===`string`?e.localeCompare(t):n===`number`&&r===`number`?e-t:String.prototype.localeCompare.call(this.serialize(e,!0),this.serialize(t,!0))}serialize(e,t){if(e===null)return`null`;switch(typeof e){case`string`:return t?e:`'${e}'`;case`bigint`:return`${e}n`;case`object`:return this.$object(e);case`function`:return this.$function(e)}return String(e)}serializeObject(e){let t=Object.prototype.toString.call(e);if(t!==`[object Object]`)return this.serializeBuiltInType(t.length<10?`unknown:${t}`:t.slice(8,-1),e);let n=e.constructor,r=n===Object||n===void 0?``:n.name;if(r!==``&&globalThis[r]===n)return this.serializeBuiltInType(r,e);if(typeof e.toJSON==`function`){let t=e.toJSON();return r+(typeof t==`object`&&t?this.$object(t):`(${this.serialize(t)})`)}return this.serializeObjectEntries(r,Object.entries(e))}serializeBuiltInType(e,t){let n=this[`$`+e];if(n)return n.call(this,t);if(typeof t?.entries==`function`)return this.serializeObjectEntries(e,t.entries());throw Error(`Cannot serialize ${e}`)}serializeObjectEntries(e,t){let n=Array.from(t).sort((e,t)=>this.compare(e[0],t[0])),r=`${e}{`;for(let e=0;e<n.length;e++){let[t,i]=n[e];r+=`${this.serialize(t,!0)}:${this.serialize(i)}`,e<n.length-1&&(r+=`,`)}return r+`}`}$object(e){let t=this.#e.get(e);return t===void 0&&(this.#e.set(e,`#${this.#e.size}`),t=this.serializeObject(e),this.#e.set(e,t)),t}$function(e){let t=Function.prototype.toString.call(e);return t.slice(-15)===`[native code] }`?`${e.name||``}()[native]`:`${e.name}(${e.length})${t.replace(/\s*\n\s*/g,``)}`}$Array(e){let t=`[`;for(let n=0;n<e.length;n++)t+=this.serialize(e[n]),n<e.length-1&&(t+=`,`);return t+`]`}$Date(e){try{return`Date(${e.toISOString()})`}catch{return`Date(null)`}}$ArrayBuffer(e){return`ArrayBuffer[${new Uint8Array(e).join(`,`)}]`}$Set(e){return`Set${this.$Array(Array.from(e).sort((e,t)=>this.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e}();function f(e,t){return e===t||u(e)===u(t)}function p(e){return i(()=>n(e)?!!c(e)?.closest(`form`):!0)}var m=a({__name:`VisuallyHidden`,props:{feature:{type:String,required:!1,default:`focusable`},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){return(n,i)=>(e(),r(o(l),{as:n.as,"as-child":n.asChild,"aria-hidden":n.feature===`focusable`?`true`:void 0,"data-hidden":n.feature===`fully-hidden`?``:void 0,tabindex:n.feature===`fully-hidden`?`-1`:void 0,style:{position:`absolute`,border:0,width:`1px`,height:`1px`,padding:0,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,clipPath:`inset(50%)`,whiteSpace:`nowrap`,wordWrap:`normal`,top:`-1px`,left:`-1px`}},{default:t(()=>[s(n.$slots,`default`)]),_:3},8,[`as`,`as-child`,`aria-hidden`,`data-hidden`,`tabindex`]))}});export{p as n,f as r,m as t};
|
||||
import{I as e,Q as t,_t as n,g as r,m as i,x as a,yt as o,z as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{i as c}from"./dist-3yfE1dPa.js";import{i as l}from"./button-BTKRNUhQ.js";function u(e){return typeof e==`string`?`'${e}'`:new d().serialize(e)}var d=function(){class e{#e=new Map;compare(e,t){let n=typeof e,r=typeof t;return n===`string`&&r===`string`?e.localeCompare(t):n===`number`&&r===`number`?e-t:String.prototype.localeCompare.call(this.serialize(e,!0),this.serialize(t,!0))}serialize(e,t){if(e===null)return`null`;switch(typeof e){case`string`:return t?e:`'${e}'`;case`bigint`:return`${e}n`;case`object`:return this.$object(e);case`function`:return this.$function(e)}return String(e)}serializeObject(e){let t=Object.prototype.toString.call(e);if(t!==`[object Object]`)return this.serializeBuiltInType(t.length<10?`unknown:${t}`:t.slice(8,-1),e);let n=e.constructor,r=n===Object||n===void 0?``:n.name;if(r!==``&&globalThis[r]===n)return this.serializeBuiltInType(r,e);if(typeof e.toJSON==`function`){let t=e.toJSON();return r+(typeof t==`object`&&t?this.$object(t):`(${this.serialize(t)})`)}return this.serializeObjectEntries(r,Object.entries(e))}serializeBuiltInType(e,t){let n=this[`$`+e];if(n)return n.call(this,t);if(typeof t?.entries==`function`)return this.serializeObjectEntries(e,t.entries());throw Error(`Cannot serialize ${e}`)}serializeObjectEntries(e,t){let n=Array.from(t).sort((e,t)=>this.compare(e[0],t[0])),r=`${e}{`;for(let e=0;e<n.length;e++){let[t,i]=n[e];r+=`${this.serialize(t,!0)}:${this.serialize(i)}`,e<n.length-1&&(r+=`,`)}return r+`}`}$object(e){let t=this.#e.get(e);return t===void 0&&(this.#e.set(e,`#${this.#e.size}`),t=this.serializeObject(e),this.#e.set(e,t)),t}$function(e){let t=Function.prototype.toString.call(e);return t.slice(-15)===`[native code] }`?`${e.name||``}()[native]`:`${e.name}(${e.length})${t.replace(/\s*\n\s*/g,``)}`}$Array(e){let t=`[`;for(let n=0;n<e.length;n++)t+=this.serialize(e[n]),n<e.length-1&&(t+=`,`);return t+`]`}$Date(e){try{return`Date(${e.toISOString()})`}catch{return`Date(null)`}}$ArrayBuffer(e){return`ArrayBuffer[${new Uint8Array(e).join(`,`)}]`}$Set(e){return`Set${this.$Array(Array.from(e).sort((e,t)=>this.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e}();function f(e,t){return e===t||u(e)===u(t)}function p(e){return i(()=>n(e)?!!c(e)?.closest(`form`):!0)}var m=a({__name:`VisuallyHidden`,props:{feature:{type:String,required:!1,default:`focusable`},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){return(n,i)=>(e(),r(o(l),{as:n.as,"as-child":n.asChild,"aria-hidden":n.feature===`focusable`?`true`:void 0,"data-hidden":n.feature===`fully-hidden`?``:void 0,tabindex:n.feature===`fully-hidden`?`-1`:void 0,style:{position:`absolute`,border:0,width:`1px`,height:`1px`,padding:0,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,clipPath:`inset(50%)`,whiteSpace:`nowrap`,wordWrap:`normal`,top:`-1px`,left:`-1px`}},{default:t(()=>[s(n.$slots,`default`)]),_:3},8,[`as`,`as-child`,`aria-hidden`,`data-hidden`,`tabindex`]))}});export{p as n,f as r,m as t};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,J as n,R as r,_ as i,g as a,l as o,m as s,v as c,x as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as u}from"./VisuallyHidden-Bt6f1zl_.js";import{s as d}from"./PopperContent-DR7IJ4Zs.js";var f=l({inheritAttrs:!1,__name:`VisuallyHiddenInputBubble`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(r){let i=r,{primitiveElement:o,currentElement:c}=d();return n(s(()=>i.checked??i.value),(e,t)=>{if(!c.value)return;let n=c.value,r=window.HTMLInputElement.prototype,i=Object.getOwnPropertyDescriptor(r,`value`).set;if(i&&e!==t){let t=new Event(`input`,{bubbles:!0}),r=new Event(`change`,{bubbles:!0});i.call(n,e),n.dispatchEvent(t),n.dispatchEvent(r)}}),(n,r)=>(t(),a(u,e({ref_key:`primitiveElement`,ref:o},{...i,...n.$attrs},{as:`input`}),null,16))}}),p=l({inheritAttrs:!1,__name:`VisuallyHiddenInput`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(n){let l=n,u=s(()=>typeof l.value==`object`&&Array.isArray(l.value)&&l.value.length===0&&l.required),d=s(()=>typeof l.value==`string`||typeof l.value==`number`||typeof l.value==`boolean`||l.value===null||l.value===void 0?[{name:l.name,value:l.value}]:typeof l.value==`object`&&Array.isArray(l.value)?l.value.flatMap((e,t)=>typeof e==`object`?Object.entries(e).map(([e,n])=>({name:`${l.name}[${t}][${e}]`,value:n})):{name:`${l.name}[${t}]`,value:e}):l.value!==null&&typeof l.value==`object`&&!Array.isArray(l.value)?Object.entries(l.value).map(([e,t])=>({name:`${l.name}[${e}]`,value:t})):[]);return(n,s)=>(t(),c(o,null,[i(` We render single input if it's required `),u.value?(t(),a(f,e({key:n.name},{...l,...n.$attrs},{name:n.name,value:n.value}),null,16,[`name`,`value`])):(t(!0),c(o,{key:1},r(d.value,r=>(t(),a(f,e({key:r.name},{ref_for:!0},{...l,...n.$attrs},{name:r.name,value:r.value}),null,16,[`name`,`value`]))),128))],2112))}});export{p as t};
|
||||
import{A as e,I as t,J as n,R as r,_ as i,g as a,l as o,m as s,v as c,x as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as u}from"./VisuallyHidden-_sQ0xQ9O.js";import{s as d}from"./PopperContent-oFiuPLDs.js";var f=l({inheritAttrs:!1,__name:`VisuallyHiddenInputBubble`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(r){let i=r,{primitiveElement:o,currentElement:c}=d();return n(s(()=>i.checked??i.value),(e,t)=>{if(!c.value)return;let n=c.value,r=window.HTMLInputElement.prototype,i=Object.getOwnPropertyDescriptor(r,`value`).set;if(i&&e!==t){let t=new Event(`input`,{bubbles:!0}),r=new Event(`change`,{bubbles:!0});i.call(n,e),n.dispatchEvent(t),n.dispatchEvent(r)}}),(n,r)=>(t(),a(u,e({ref_key:`primitiveElement`,ref:o},{...i,...n.$attrs},{as:`input`}),null,16))}}),p=l({inheritAttrs:!1,__name:`VisuallyHiddenInput`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(n){let l=n,u=s(()=>typeof l.value==`object`&&Array.isArray(l.value)&&l.value.length===0&&l.required),d=s(()=>typeof l.value==`string`||typeof l.value==`number`||typeof l.value==`boolean`||l.value===null||l.value===void 0?[{name:l.name,value:l.value}]:typeof l.value==`object`&&Array.isArray(l.value)?l.value.flatMap((e,t)=>typeof e==`object`?Object.entries(e).map(([e,n])=>({name:`${l.name}[${t}][${e}]`,value:n})):{name:`${l.name}[${t}]`,value:e}):l.value!==null&&typeof l.value==`object`&&!Array.isArray(l.value)?Object.entries(l.value).map(([e,t])=>({name:`${l.name}[${e}]`,value:t})):[]);return(n,s)=>(t(),c(o,null,[i(` We render single input if it's required `),u.value?(t(),a(f,e({key:n.name},{...l,...n.$attrs},{name:n.name,value:n.value}),null,16,[`name`,`value`])):(t(!0),c(o,{key:1},r(d.value,r=>(t(),a(f,e({key:r.name},{ref_for:!0},{...l,...n.$attrs},{name:r.name,value:r.value}),null,16,[`name`,`value`]))),128))],2112))}});export{p as t};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,Q as t,b as n,h as r,v as i,wt as a,x as o,y as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./button-DveXNdlZ.js";import{t as u}from"./route-block-BCBU0UBp.js";var d={class:`max-w-2xl mx-auto text-center`},f={class:`font-bold text-8xl`},p={class:`mt-4 text-2xl font-bold`},m={class:`text-stone-400`},h={class:`mt-8`},g={class:`flex justify-center gap-2`},_=o({__name:`custom-error`,props:{code:{},subtitle:{},error:{}},setup(o){return(u,_)=>{let v=l;return e(),i(`div`,d,[r(`h1`,f,a(o.code),1),r(`h2`,p,a(o.subtitle),1),r(`p`,m,a(o.error),1),r(`footer`,h,[c(u.$slots,`default`,{},()=>[r(`div`,g,[n(v,{variant:`outline`,onClick:_[0]||=e=>u.$router.back()},{default:t(()=>[..._[2]||=[s(` Go Back `,-1)]]),_:1}),n(v,{onClick:_[1]||=e=>u.$router.push(`/`)},{default:t(()=>[..._[3]||=[s(` Back to Home `,-1)]]),_:1})])])])])}}}),v={class:`flex items-center justify-center h-screen`},y=o({__name:`[...path]`,setup(t){return(t,r)=>(e(),i(`div`,v,[n(_,{code:404,subtitle:`Page Not Found`,error:`The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.`})]))}});typeof u==`function`&&u(y);var b=y;export{b as default};
|
||||
import{I as e,Q as t,b as n,h as r,v as i,wt as a,x as o,y as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./button-BTKRNUhQ.js";import{t as u}from"./route-block-BCBU0UBp.js";var d={class:`max-w-2xl mx-auto text-center`},f={class:`font-bold text-8xl`},p={class:`mt-4 text-2xl font-bold`},m={class:`text-stone-400`},h={class:`mt-8`},g={class:`flex justify-center gap-2`},_=o({__name:`custom-error`,props:{code:{},subtitle:{},error:{}},setup(o){return(u,_)=>{let v=l;return e(),i(`div`,d,[r(`h1`,f,a(o.code),1),r(`h2`,p,a(o.subtitle),1),r(`p`,m,a(o.error),1),r(`footer`,h,[c(u.$slots,`default`,{},()=>[r(`div`,g,[n(v,{variant:`outline`,onClick:_[0]||=e=>u.$router.back()},{default:t(()=>[..._[2]||=[s(` Go Back `,-1)]]),_:1}),n(v,{onClick:_[1]||=e=>u.$router.push(`/`)},{default:t(()=>[..._[3]||=[s(` Back to Home `,-1)]]),_:1})])])])])}}}),v={class:`flex items-center justify-center h-screen`},y=o({__name:`[...path]`,setup(t){return(t,r)=>(e(),i(`div`,v,[n(_,{code:404,subtitle:`Page Not Found`,error:`The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.`})]))}});typeof u==`function`&&u(y);var b=y;export{b as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-De70L21J.js";import{t as i}from"./route-block-BCBU0UBp.js";var a={};function o(r,i){let a=e(`router-view`);return t(),n(a)}typeof i==`function`&&i(a);var s=r(a,[[`render`,o]]);export{s as default};
|
||||
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-BpHHjIYv.js";import{t as i}from"./route-block-BCBU0UBp.js";var a={};function o(r,i){let a=e(`router-view`);return t(),n(a)}typeof i==`function`&&i(a);var s=r(a,[[`render`,o]]);export{s as default};
|
||||
@@ -1 +1 @@
|
||||
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-De70L21J.js";var i={};function a(r,i){let a=e(`router-view`);return t(),n(a)}var o=r(i,[[`render`,a]]);export{o as default};
|
||||
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-BpHHjIYv.js";var i={};function a(r,i){let a=e(`router-view`);return t(),n(a)}var o=r(i,[[`render`,a]]);export{o as default};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,I as t,Q as n,c as r,g as i,l as a,p as o,w as s,x as c,xt as l,yt as u,z as d}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as f,X as p}from"./index-De70L21J.js";function m(e){return e?e.flatMap(e=>e.type===a?m(e.children):[e]):[]}var h=c({name:`PrimitiveSlot`,inheritAttrs:!1,setup(t,{attrs:n,slots:i}){return()=>{if(!i.default)return null;let t=m(i.default()),a=t.findIndex(e=>e.type!==r);if(a===-1)return t;let s=t[a];delete s.props?.ref;let c=s.props?e(n,s.props):n,l=o({...s,props:{}},c);return t.length===1?l:(t[a]=l,t)}}}),g=[`area`,`img`,`input`],_=c({name:`Primitive`,inheritAttrs:!1,props:{asChild:{type:Boolean,default:!1},as:{type:[String,Object],default:`div`}},setup(e,{attrs:t,slots:n}){let r=e.asChild?`template`:e.as;return typeof r==`string`&&g.includes(r)?()=>s(r,t):r===`template`?()=>s(h,t,{default:n.default}):()=>s(e.as,t,{default:n.default})}}),v=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,y=p,b=(e,t)=>n=>{if(t?.variants==null)return y(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=v(t)||v(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return y(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},x=c({__name:`Button`,props:{variant:{},size:{},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`}},setup(e){let r=e;return(a,o)=>(t(),i(u(_),{"data-slot":`button`,as:e.as,"as-child":e.asChild,class:l(u(f)(u(S)({variant:e.variant,size:e.size}),r.class))},{default:n(()=>[d(a.$slots,`default`)]),_:3},8,[`as`,`as-child`,`class`]))}}),S=b(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`,"icon-sm":`size-8`,"icon-lg":`size-10`}},defaultVariants:{variant:`default`,size:`default`}});export{h as a,_ as i,x as n,m as o,b as r,S as t};
|
||||
import{A as e,I as t,Q as n,c as r,g as i,l as a,p as o,w as s,x as c,xt as l,yt as u,z as d}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as f,X as p}from"./index-BpHHjIYv.js";function m(e){return e?e.flatMap(e=>e.type===a?m(e.children):[e]):[]}var h=c({name:`PrimitiveSlot`,inheritAttrs:!1,setup(t,{attrs:n,slots:i}){return()=>{if(!i.default)return null;let t=m(i.default()),a=t.findIndex(e=>e.type!==r);if(a===-1)return t;let s=t[a];delete s.props?.ref;let c=s.props?e(n,s.props):n,l=o({...s,props:{}},c);return t.length===1?l:(t[a]=l,t)}}}),g=[`area`,`img`,`input`],_=c({name:`Primitive`,inheritAttrs:!1,props:{asChild:{type:Boolean,default:!1},as:{type:[String,Object],default:`div`}},setup(e,{attrs:t,slots:n}){let r=e.asChild?`template`:e.as;return typeof r==`string`&&g.includes(r)?()=>s(r,t):r===`template`?()=>s(h,t,{default:n.default}):()=>s(e.as,t,{default:n.default})}}),v=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,y=p,b=(e,t)=>n=>{if(t?.variants==null)return y(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=v(t)||v(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return y(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},x=c({__name:`Button`,props:{variant:{},size:{},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`}},setup(e){let r=e;return(a,o)=>(t(),i(u(_),{"data-slot":`button`,as:e.as,"as-child":e.asChild,class:l(u(f)(u(S)({variant:e.variant,size:e.size}),r.class))},{default:n(()=>[d(a.$slots,`default`)]),_:3},8,[`as`,`as-child`,`class`]))}}),S=b(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`,"icon-sm":`size-8`,"icon-lg":`size-10`}},defaultVariants:{variant:`default`,size:`default`}});export{h as a,_ as i,x as n,m as o,b as r,S as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{B as e,I as t,Q as n,R as r,V as i,_ as a,b as o,g as s,h as c,l,m as u,v as d,wt as f,x as p,xt as m,y as h,yt as g,z as _}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as v}from"./chevrons-up-down-Bbw1im9J.js";import{J as y,N as b}from"./index-De70L21J.js";import{n as x}from"./button-DveXNdlZ.js";import{i as S,n as C,r as w,t as T}from"./DropdownMenuTrigger-CvM5INxe.js";var E={class:`text-2xl font-bold`},D={key:0,class:`text-muted-foreground`},O={class:`flex items-center gap-2 flex-wrap`},k=p({__name:`basic-header`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(n,r)=>(t(),d(`header`,{class:m(g(y)(`flex flex-col md:flex-row gap-2 justify-between py-2`,e.sticky?`sticky top-0 z-40 bg-background`:``))},[c(`main`,null,[c(`h1`,E,f(e.title),1),e.description?(t(),d(`p`,D,f(e.description),1)):a(``,!0)]),c(`aside`,O,[_(n.$slots,`actions`)])],2))}}),A={class:`py-4`},j=p({__name:`basic-page`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(r,i)=>(t(),d(`main`,null,[o(k,{title:e.title,description:e.description,sticky:e.sticky},{actions:n(()=>[_(r.$slots,`actions`)]),_:3},8,[`title`,`description`,`sticky`]),c(`main`,A,[_(r.$slots,`default`)])]))}}),M={class:`flex flex-col gap-2`},N=`text-primary font-semibold bg-primary/5`,P=p({__name:`two-col-aside`,props:{nav:{}},setup(a){let p=a,_=b(),y=u(()=>_.path),E=u(()=>p.nav.find(e=>e.url===y.value));return(a,u)=>{let _=e(`router-link`),b=x,D=T,O=C,k=w,A=S;return t(),d(`nav`,M,[(t(!0),d(l,null,r(p.nav,e=>(t(),s(_,{key:e.url,to:e.url,class:m([`items-center hidden px-2 py-1 rounded-md lg:flex hover:bg-primary/5`,e.url===g(y)?N:``])},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),c(`span`,null,f(e.title),1)]),_:2},1032,[`to`,`class`]))),128)),o(A,{class:`lg:hidden`},{default:n(()=>[o(D,{"as-child":``},{default:n(()=>[o(b,{variant:`outline`,class:`w-48 lg:hidden`},{default:n(()=>[(t(),s(i(g(E)?.icon),{class:`size-4 mr-1`})),c(`span`,null,f(g(E)?.title),1),o(g(v),{class:`size-4 ml-auto`})]),_:1})]),_:1}),o(k,{class:`w-48`,align:`start`},{default:n(()=>[(t(!0),d(l,null,r(p.nav,e=>(t(),s(O,{key:e.url,onClick:t=>a.$router.push(e.url)},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),h(` `+f(e.title),1)]),_:2},1032,[`onClick`]))),128))]),_:1})]),_:1})])}}}),F=p({__name:`two-col`,setup(e){return(e,n)=>(t(),d(`div`,{class:m(g(y)(`grid grid-cols-1 lg:grid-cols-[200px_1fr] gap-4 w-full`))},[c(`aside`,null,[_(e.$slots,`aside`)]),c(`section`,null,[_(e.$slots,`default`)])],2))}});export{P as n,j as r,F as t};
|
||||
import{B as e,I as t,Q as n,R as r,V as i,_ as a,b as o,g as s,h as c,l,m as u,v as d,wt as f,x as p,xt as m,y as h,yt as g,z as _}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as v}from"./chevrons-up-down-Bbw1im9J.js";import{J as y,N as b}from"./index-BpHHjIYv.js";import{n as x}from"./button-BTKRNUhQ.js";import{i as S,n as C,r as w,t as T}from"./DropdownMenuTrigger-Dmk4lbKz.js";var E={class:`text-2xl font-bold`},D={key:0,class:`text-muted-foreground`},O={class:`flex items-center gap-2 flex-wrap`},k=p({__name:`basic-header`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(n,r)=>(t(),d(`header`,{class:m(g(y)(`flex flex-col md:flex-row gap-2 justify-between py-2`,e.sticky?`sticky top-0 z-40 bg-background`:``))},[c(`main`,null,[c(`h1`,E,f(e.title),1),e.description?(t(),d(`p`,D,f(e.description),1)):a(``,!0)]),c(`aside`,O,[_(n.$slots,`actions`)])],2))}}),A={class:`py-4`},j=p({__name:`basic-page`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(r,i)=>(t(),d(`main`,null,[o(k,{title:e.title,description:e.description,sticky:e.sticky},{actions:n(()=>[_(r.$slots,`actions`)]),_:3},8,[`title`,`description`,`sticky`]),c(`main`,A,[_(r.$slots,`default`)])]))}}),M={class:`flex flex-col gap-2`},N=`text-primary font-semibold bg-primary/5`,P=p({__name:`two-col-aside`,props:{nav:{}},setup(a){let p=a,_=b(),y=u(()=>_.path),E=u(()=>p.nav.find(e=>e.url===y.value));return(a,u)=>{let _=e(`router-link`),b=x,D=T,O=C,k=w,A=S;return t(),d(`nav`,M,[(t(!0),d(l,null,r(p.nav,e=>(t(),s(_,{key:e.url,to:e.url,class:m([`items-center hidden px-2 py-1 rounded-md lg:flex hover:bg-primary/5`,e.url===g(y)?N:``])},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),c(`span`,null,f(e.title),1)]),_:2},1032,[`to`,`class`]))),128)),o(A,{class:`lg:hidden`},{default:n(()=>[o(D,{"as-child":``},{default:n(()=>[o(b,{variant:`outline`,class:`w-48 lg:hidden`},{default:n(()=>[(t(),s(i(g(E)?.icon),{class:`size-4 mr-1`})),c(`span`,null,f(g(E)?.title),1),o(g(v),{class:`size-4 ml-auto`})]),_:1})]),_:1}),o(k,{class:`w-48`,align:`start`},{default:n(()=>[(t(!0),d(l,null,r(p.nav,e=>(t(),s(O,{key:e.url,onClick:t=>a.$router.push(e.url)},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),h(` `+f(e.title),1)]),_:2},1032,[`onClick`]))),128))]),_:1})]),_:1})])}}}),F=p({__name:`two-col`,setup(e){return(e,n)=>(t(),d(`div`,{class:m(g(y)(`grid grid-cols-1 lg:grid-cols-[200px_1fr] gap-4 w-full`))},[c(`aside`,null,[_(e.$slots,`aside`)]),c(`section`,null,[_(e.$slots,`default`)])],2))}});export{P as n,j as r,F as t};
|
||||
1
monisuo-admin/dist/assets/index-BeMvYSwb.css
vendored
1
monisuo-admin/dist/assets/index-BeMvYSwb.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
monisuo-admin/dist/assets/index-DzGkD_L8.css
vendored
Normal file
1
monisuo-admin/dist/assets/index-DzGkD_L8.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{B as e,I as t,Q as n,R as r,b as i,g as a,h as o,l as s,v as c,wt as l,x as u,y as d,yt as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{o as p}from"./dist-3yfE1dPa.js";import{n as m,t as h}from"./toggle-theme-SM1NpiUo.js";import{$ as g,K as _}from"./index-De70L21J.js";import"./Teleport-DzgMZwe8.js";import{n as v}from"./button-DveXNdlZ.js";import{n as y,t as b}from"./AvatarImage-Ck1aL522.js";var x={class:`min-h-18 flex items-center justify-between`},S={class:`flex items-center gap-2`},C=u({__name:`the-footer`,setup(e){let a=p(),l=[{name:`bluesky`,icon:`simple-icons:bluesky`,url:`https://bsky.app/profile/bitmc.bsky.social`},{name:`github`,icon:`simple-icons:github`,url:`https://www.github.com/whbbit1999/shadcn-vue-admin`},{name:`bilibili`,icon:`simple-icons:bilibili`,url:`https://space.bilibili.com/104376935`}];return(e,u)=>{let d=b,p=y,m=v;return t(),c(`footer`,x,[i(p,null,{default:n(()=>[i(d,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),u[0]||=o(`div`,null,`© 2025 Whbbit1999`,-1),o(`div`,S,[(t(),c(s,null,r(l,e=>i(m,{key:e.name,variant:`outline`,size:`icon`,as:`a`,href:e.url,target:`_blank`},{default:n(()=>[i(f(g),{icon:e.icon},null,8,[`icon`])]),_:2},1032,[`href`])),64))])])}}}),w={};function T(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-in`},{default:n(()=>[d(l(e.$t(`login`)),1)]),_:1})}var E=_(w,[[`render`,T]]),D={};function O(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-up`,variant:`outline`},{default:n(()=>[d(l(e.$t(`register`)),1)]),_:1})}var k=_(D,[[`render`,O]]),A={class:`h-14 flex items-center marketing-header sticky top-0 z-99`},j={class:`mr-2 hidden lg:flex lg:gap-2`},M={class:`flex gap-2`},N=_(u({__name:`the-header`,setup(r){let a=p();return(r,s)=>{let l=b,u=y,d=e(`router-link`);return t(),c(`header`,A,[i(d,{to:`/`,class:`flex items-center gap-2`},{default:n(()=>[i(u,null,{default:n(()=>[i(l,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),s[0]||=o(`span`,{class:`text-base font-bold`},`Shadcn Vue Admin`,-1)]),_:1}),s[1]||=o(`div`,{class:`flex-1`},null,-1),o(`div`,j,[i(E),i(k)]),o(`div`,M,[i(m),i(h)])])}}}),[[`__scopeId`,`data-v-8a713a75`]]),P={class:`container mx-auto`},F={class:`mx-2 lg:p-0`},I=u({__name:`marketing`,setup(n){return(n,r)=>{let a=e(`router-view`);return t(),c(`div`,P,[o(`div`,F,[i(N),o(`main`,null,[i(a)]),i(C)])])}}});export{I as default};
|
||||
import{B as e,I as t,Q as n,R as r,b as i,g as a,h as o,l as s,v as c,wt as l,x as u,y as d,yt as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{o as p}from"./dist-3yfE1dPa.js";import{n as m,t as h}from"./toggle-theme-9ZMsSjs2.js";import{$ as g,K as _}from"./index-BpHHjIYv.js";import"./Teleport-qOjHMYM8.js";import{n as v}from"./button-BTKRNUhQ.js";import{n as y,t as b}from"./AvatarImage-Ct5I9mHM.js";var x={class:`min-h-18 flex items-center justify-between`},S={class:`flex items-center gap-2`},C=u({__name:`the-footer`,setup(e){let a=p(),l=[{name:`bluesky`,icon:`simple-icons:bluesky`,url:`https://bsky.app/profile/bitmc.bsky.social`},{name:`github`,icon:`simple-icons:github`,url:`https://www.github.com/whbbit1999/shadcn-vue-admin`},{name:`bilibili`,icon:`simple-icons:bilibili`,url:`https://space.bilibili.com/104376935`}];return(e,u)=>{let d=b,p=y,m=v;return t(),c(`footer`,x,[i(p,null,{default:n(()=>[i(d,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),u[0]||=o(`div`,null,`© 2025 Whbbit1999`,-1),o(`div`,S,[(t(),c(s,null,r(l,e=>i(m,{key:e.name,variant:`outline`,size:`icon`,as:`a`,href:e.url,target:`_blank`},{default:n(()=>[i(f(g),{icon:e.icon},null,8,[`icon`])]),_:2},1032,[`href`])),64))])])}}}),w={};function T(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-in`},{default:n(()=>[d(l(e.$t(`login`)),1)]),_:1})}var E=_(w,[[`render`,T]]),D={};function O(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-up`,variant:`outline`},{default:n(()=>[d(l(e.$t(`register`)),1)]),_:1})}var k=_(D,[[`render`,O]]),A={class:`h-14 flex items-center marketing-header sticky top-0 z-99`},j={class:`mr-2 hidden lg:flex lg:gap-2`},M={class:`flex gap-2`},N=_(u({__name:`the-header`,setup(r){let a=p();return(r,s)=>{let l=b,u=y,d=e(`router-link`);return t(),c(`header`,A,[i(d,{to:`/`,class:`flex items-center gap-2`},{default:n(()=>[i(u,null,{default:n(()=>[i(l,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),s[0]||=o(`span`,{class:`text-base font-bold`},`Shadcn Vue Admin`,-1)]),_:1}),s[1]||=o(`div`,{class:`flex-1`},null,-1),o(`div`,j,[i(E),i(k)]),o(`div`,M,[i(m),i(h)])])}}}),[[`__scopeId`,`data-v-8a713a75`]]),P={class:`container mx-auto`},F={class:`mx-2 lg:p-0`},I=u({__name:`marketing`,setup(n){return(n,r)=>{let a=e(`router-view`);return t(),c(`div`,P,[o(`div`,F,[i(N),o(`main`,null,[i(a)]),i(C)])])}}});export{I as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{I as e,Q as t,Y as n,_ as r,at as i,b as a,g as o,h as s,s as c,ut as l,v as u,wt as d,x as f,y as p,yt as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as h}from"./dist-3yfE1dPa.js";import{t as g}from"./eye-off-DDZmXXZv.js";import{P as _,q as v}from"./index-De70L21J.js";import{n as y}from"./button-DveXNdlZ.js";import{t as b}from"./Label-BVEAnVwl.js";import{t as x}from"./Input-ChmjFEBQ.js";import"./monisuo-admin.api-fJhTc-_0.js";import{t as S}from"./use-auth-DSbeyb7x.js";import{t as C}from"./route-block-BCBU0UBp.js";import{t as w}from"./Card-P0ucPgP6.js";import{t as T}from"./CardContent-CVpAbhEk.js";import{r as E,t as D}from"./Alert-BF_7iK6A.js";import{n as O,r as k,t as A}from"./CardTitle-BnorzgWP.js";var j=h(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),M=h(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),N=h(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),P={class:`min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4`},F={class:`flex justify-center mb-4`},I={class:`size-12 rounded-xl bg-primary flex items-center justify-center`},L={class:`space-y-2`},R={class:`relative`},z={class:`space-y-2`},B={class:`relative`},V=f({__name:`sign-in`,setup(f){let h=l(``),C=l(``),V=l(!1),{login:H,loading:U,error:W,isLogin:G}=S(),K=_();n(()=>{m(G)&&K.push(`/monisuo/dashboard`)});async function q(){!h.value||!C.value||await H(h.value,C.value)}return(n,l)=>{let f=A,_=O,S=k,H=b,G=x,K=E,J=D,Y=v,X=y,Z=T,Q=w;return e(),u(`div`,P,[a(Q,{class:`w-full max-w-md`},{default:t(()=>[a(S,{class:`space-y-1 text-center`},{default:t(()=>[s(`div`,F,[s(`div`,I,[a(m(M),{class:`size-6 text-primary-foreground`})])]),a(f,{class:`text-2xl font-bold`},{default:t(()=>[...l[3]||=[p(` Monisuo Admin `,-1)]]),_:1}),a(_,null,{default:t(()=>[...l[4]||=[p(` 管理员登录 `,-1)]]),_:1})]),_:1}),a(Z,null,{default:t(()=>[s(`form`,{onSubmit:c(q,[`prevent`]),class:`space-y-4`},[s(`div`,L,[a(H,{for:`username`},{default:t(()=>[...l[5]||=[p(`用户名`,-1)]]),_:1}),s(`div`,R,[a(m(N),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`username`,modelValue:m(h),"onUpdate:modelValue":l[0]||=e=>i(h)?h.value=e:null,type:`text`,placeholder:`请输入用户名`,class:`pl-9`,disabled:m(U)},null,8,[`modelValue`,`disabled`])])]),s(`div`,z,[a(H,{for:`password`},{default:t(()=>[...l[6]||=[p(`密码`,-1)]]),_:1}),s(`div`,B,[a(m(M),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`password`,modelValue:m(C),"onUpdate:modelValue":l[1]||=e=>i(C)?C.value=e:null,type:m(V)?`text`:`password`,placeholder:`请输入密码`,class:`pl-9 pr-9`,disabled:m(U)},null,8,[`modelValue`,`type`,`disabled`]),s(`button`,{type:`button`,class:`absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,onClick:l[2]||=e=>V.value=!m(V)},[m(V)?(e(),o(m(g),{key:1,class:`size-4`})):(e(),o(m(j),{key:0,class:`size-4`}))])])]),m(W)?(e(),o(J,{key:0,variant:`destructive`},{default:t(()=>[a(K,null,{default:t(()=>[p(d(m(W)),1)]),_:1})]),_:1})):r(``,!0),a(X,{type:`submit`,class:`w-full`,disabled:m(U)},{default:t(()=>[m(U)?(e(),o(Y,{key:0,class:`size-4 mr-2`})):r(``,!0),p(` `+d(m(U)?`登录中...`:`登录`),1)]),_:1},8,[`disabled`])],32)]),_:1})]),_:1})])}}});typeof C==`function`&&C(V);var H=V;export{H as default};
|
||||
import{I as e,Q as t,Y as n,_ as r,at as i,b as a,g as o,h as s,s as c,ut as l,v as u,wt as d,x as f,y as p,yt as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as h}from"./dist-3yfE1dPa.js";import{t as g}from"./eye-off-DDZmXXZv.js";import{P as _,q as v}from"./index-BpHHjIYv.js";import{n as y}from"./button-BTKRNUhQ.js";import{t as b}from"./Label-sjjJXKKd.js";import{t as x}from"./Input-DOTs5aTB.js";import"./monisuo-admin.api-DyXM8BcP.js";import{t as S}from"./use-auth-BEiiAXZl.js";import{t as C}from"./route-block-BCBU0UBp.js";import{t as w}from"./Card-o8MCRg3I.js";import{t as T}from"./CardContent-BXRdn2MY.js";import{r as E,t as D}from"./Alert-ChDGwKFB.js";import{n as O,r as k,t as A}from"./CardTitle-C-tfNzWl.js";var j=h(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),M=h(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),N=h(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),P={class:`min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4`},F={class:`flex justify-center mb-4`},I={class:`size-12 rounded-xl bg-primary flex items-center justify-center`},L={class:`space-y-2`},R={class:`relative`},z={class:`space-y-2`},B={class:`relative`},V=f({__name:`sign-in`,setup(f){let h=l(``),C=l(``),V=l(!1),{login:H,loading:U,error:W,isLogin:G}=S(),K=_();n(()=>{m(G)&&K.push(`/monisuo/dashboard`)});async function q(){!h.value||!C.value||await H(h.value,C.value)}return(n,l)=>{let f=A,_=O,S=k,H=b,G=x,K=E,J=D,Y=v,X=y,Z=T,Q=w;return e(),u(`div`,P,[a(Q,{class:`w-full max-w-lg`},{default:t(()=>[a(S,{class:`space-y-1 text-center`},{default:t(()=>[s(`div`,F,[s(`div`,I,[a(m(M),{class:`size-6 text-primary-foreground`})])]),a(f,{class:`text-2xl font-bold`},{default:t(()=>[...l[3]||=[p(` Monisuo Admin `,-1)]]),_:1}),a(_,null,{default:t(()=>[...l[4]||=[p(` 管理员登录 `,-1)]]),_:1})]),_:1}),a(Z,null,{default:t(()=>[s(`form`,{onSubmit:c(q,[`prevent`]),class:`space-y-4`},[s(`div`,L,[a(H,{for:`username`},{default:t(()=>[...l[5]||=[p(`用户名`,-1)]]),_:1}),s(`div`,R,[a(m(N),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`username`,modelValue:m(h),"onUpdate:modelValue":l[0]||=e=>i(h)?h.value=e:null,type:`text`,placeholder:`请输入用户名`,class:`pl-9`,disabled:m(U)},null,8,[`modelValue`,`disabled`])])]),s(`div`,z,[a(H,{for:`password`},{default:t(()=>[...l[6]||=[p(`密码`,-1)]]),_:1}),s(`div`,B,[a(m(M),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`password`,modelValue:m(C),"onUpdate:modelValue":l[1]||=e=>i(C)?C.value=e:null,type:m(V)?`text`:`password`,placeholder:`请输入密码`,class:`pl-9 pr-9`,disabled:m(U)},null,8,[`modelValue`,`type`,`disabled`]),s(`button`,{type:`button`,class:`absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,onClick:l[2]||=e=>V.value=!m(V)},[m(V)?(e(),o(m(g),{key:1,class:`size-4`})):(e(),o(m(j),{key:0,class:`size-4`}))])])]),m(W)?(e(),o(J,{key:0,variant:`destructive`},{default:t(()=>[a(K,null,{default:t(()=>[p(d(m(W)),1)]),_:1})]),_:1})):r(``,!0),a(X,{type:`submit`,class:`w-full`,disabled:m(U)},{default:t(()=>[m(U)?(e(),o(Y,{key:0,class:`size-4 mr-2`})):r(``,!0),p(` `+d(m(U)?`登录中...`:`登录`),1)]),_:1},8,[`disabled`])],32)]),_:1})]),_:1})])}}});typeof C==`function`&&C(V);var H=V;export{H as default};
|
||||
@@ -1 +1 @@
|
||||
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-DzgMZwe8.js";import{n as u}from"./button-DveXNdlZ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-CSACWwFG.js";var g=o({__name:`task-delete`,props:{task:{}},setup(o){let g=o;function _(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(g.task,null,2)))})}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this task: `+a(o.task.id)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a task with the ID `+a(o.task.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:_},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
|
||||
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-qOjHMYM8.js";import{n as u}from"./button-BTKRNUhQ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-DKtIxxgh.js";var g=o({__name:`task-delete`,props:{task:{}},setup(o){let g=o;function _(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(g.task,null,2)))})}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this task: `+a(o.task.id)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a task with the ID `+a(o.task.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:_},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{t as e}from"./task-resource-dialog-BX-kib4A.js";import"./Teleport-DzgMZwe8.js";import"./button-DveXNdlZ.js";import"./modal-CSACWwFG.js";export{e as default};
|
||||
1
monisuo-admin/dist/assets/task-resource-dialog-DEJrfsXK.js
vendored
Normal file
1
monisuo-admin/dist/assets/task-resource-dialog-DEJrfsXK.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{t as e}from"./task-resource-dialog-8MJRe8qY.js";import"./Teleport-qOjHMYM8.js";import"./button-BTKRNUhQ.js";import"./modal-DKtIxxgh.js";export{e as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{I as e,Q as t,at as n,b as r,g as i,h as a,wt as o,x as s,y as c,yt as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as u,o as d}from"./dist-3yfE1dPa.js";import{$ as f,I as p,L as m,R as h}from"./index-De70L21J.js";import{n as g}from"./button-DveXNdlZ.js";import{i as _,n as v,r as y,t as b}from"./DropdownMenuTrigger-CvM5INxe.js";import{n as x,t as S}from"./DropdownMenuLabel-D34bF97h.js";import{n as C,t as w}from"./DropdownMenuRadioItem-31gls3j1.js";var T=u(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),E=u(`sun-moon`,[[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715`,key:`xlf6rm`}],[`path`,{d:`M16 12a4 4 0 0 0-4-4`,key:`6vsxu`}],[`path`,{d:`m19 5-1.256 1.256`,key:`1yg6a6`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}]]),D=u(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),O=s({__name:`language-change`,setup(s){let{locale:u}=h();function d(){u.value=`en`,m.value=`en`}function v(e){if(typeof e!=`string`||!p.has(e)){d();return}u.value=e,m.value=e}return(s,d)=>{let p=g,m=b,h=S,T=x,E=w,D=C,O=y,k=_;return e(),i(k,null,{default:t(()=>[r(m,{"as-child":``},{default:t(()=>[r(p,{variant:`outline`},{default:t(()=>[r(l(f),{icon:`mdi:translate`,class:`mr-2`}),c(` `+o(s.$t(`language`)),1)]),_:1})]),_:1}),r(O,null,{default:t(()=>[r(h,null,{default:t(()=>[c(o(s.$t(`changeLanguage`)),1)]),_:1}),r(T),r(D,{modelValue:l(u),"onUpdate:modelValue":[d[0]||=e=>n(u)?u.value=e:null,v]},{default:t(()=>[r(E,{value:`en`},{default:t(()=>[r(l(f),{icon:`flag:us-4x3`}),d[1]||=a(`span`,{class:`ml-2`},`English`,-1)]),_:1}),r(E,{value:`zh`},{default:t(()=>[r(l(f),{icon:`flag:cn-4x3`}),d[2]||=a(`span`,{class:`ml-2`},`中文`,-1)]),_:1})]),_:1},8,[`modelValue`])]),_:1})]),_:1})}}}),k=s({__name:`toggle-theme`,setup(n){let o=d();return(n,s)=>{let u=g,d=b,f=v,p=y,m=_;return e(),i(m,null,{default:t(()=>[r(d,{"as-child":``},{default:t(()=>[r(u,{variant:`outline`,size:`icon`},{default:t(()=>[r(l(T),{class:`rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0`}),r(l(D),{class:`absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100`}),s[3]||=a(`span`,{class:`sr-only`},`Toggle theme`,-1)]),_:1})]),_:1}),r(p,{align:`end`},{default:t(()=>[r(f,{onClick:s[0]||=e=>o.value=`light`},{default:t(()=>[r(l(D)),s[4]||=c(` Light `,-1)]),_:1}),r(f,{onClick:s[1]||=e=>o.value=`dark`},{default:t(()=>[r(l(T)),s[5]||=c(` Dark `,-1)]),_:1}),r(f,{onClick:s[2]||=e=>o.value=`auto`},{default:t(()=>[r(l(E)),s[6]||=c(` System `,-1)]),_:1})]),_:1})]),_:1})}}});export{T as a,E as i,O as n,D as r,k as t};
|
||||
import{I as e,Q as t,at as n,b as r,g as i,h as a,wt as o,x as s,y as c,yt as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as u,o as d}from"./dist-3yfE1dPa.js";import{$ as f,I as p,L as m,R as h}from"./index-BpHHjIYv.js";import{n as g}from"./button-BTKRNUhQ.js";import{i as _,n as v,r as y,t as b}from"./DropdownMenuTrigger-Dmk4lbKz.js";import{n as x,t as S}from"./DropdownMenuLabel-Bls_J4kr.js";import{n as C,t as w}from"./DropdownMenuRadioItem-QlCzvFJ2.js";var T=u(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),E=u(`sun-moon`,[[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715`,key:`xlf6rm`}],[`path`,{d:`M16 12a4 4 0 0 0-4-4`,key:`6vsxu`}],[`path`,{d:`m19 5-1.256 1.256`,key:`1yg6a6`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}]]),D=u(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),O=s({__name:`language-change`,setup(s){let{locale:u}=h();function d(){u.value=`en`,m.value=`en`}function v(e){if(typeof e!=`string`||!p.has(e)){d();return}u.value=e,m.value=e}return(s,d)=>{let p=g,m=b,h=S,T=x,E=w,D=C,O=y,k=_;return e(),i(k,null,{default:t(()=>[r(m,{"as-child":``},{default:t(()=>[r(p,{variant:`outline`},{default:t(()=>[r(l(f),{icon:`mdi:translate`,class:`mr-2`}),c(` `+o(s.$t(`language`)),1)]),_:1})]),_:1}),r(O,null,{default:t(()=>[r(h,null,{default:t(()=>[c(o(s.$t(`changeLanguage`)),1)]),_:1}),r(T),r(D,{modelValue:l(u),"onUpdate:modelValue":[d[0]||=e=>n(u)?u.value=e:null,v]},{default:t(()=>[r(E,{value:`en`},{default:t(()=>[r(l(f),{icon:`flag:us-4x3`}),d[1]||=a(`span`,{class:`ml-2`},`English`,-1)]),_:1}),r(E,{value:`zh`},{default:t(()=>[r(l(f),{icon:`flag:cn-4x3`}),d[2]||=a(`span`,{class:`ml-2`},`中文`,-1)]),_:1})]),_:1},8,[`modelValue`])]),_:1})]),_:1})}}}),k=s({__name:`toggle-theme`,setup(n){let o=d();return(n,s)=>{let u=g,d=b,f=v,p=y,m=_;return e(),i(m,null,{default:t(()=>[r(d,{"as-child":``},{default:t(()=>[r(u,{variant:`outline`,size:`icon`},{default:t(()=>[r(l(T),{class:`rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0`}),r(l(D),{class:`absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100`}),s[3]||=a(`span`,{class:`sr-only`},`Toggle theme`,-1)]),_:1})]),_:1}),r(p,{align:`end`},{default:t(()=>[r(f,{onClick:s[0]||=e=>o.value=`light`},{default:t(()=>[r(l(D)),s[4]||=c(` Light `,-1)]),_:1}),r(f,{onClick:s[1]||=e=>o.value=`dark`},{default:t(()=>[r(l(T)),s[5]||=c(` Dark `,-1)]),_:1}),r(f,{onClick:s[2]||=e=>o.value=`auto`},{default:t(()=>[r(l(E)),s[6]||=c(` System `,-1)]),_:1})]),_:1})]),_:1})}}});export{T as a,E as i,O as n,D as r,k as t};
|
||||
@@ -1 +1 @@
|
||||
import{ut as e}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{G as t,M as n,P as r}from"./index-De70L21J.js";import{t as i}from"./monisuo-admin.api-fJhTc-_0.js";function a(){let a=r(),o=n(),{isLogin:s,adminInfo:c}=t(o),l=e(!1),u=e(null),d=i();function f(){o.logout(),a.push({path:`/auth/sign-in`})}function p(){a.push({path:`/monisuo/dashboard`})}async function m(e,t){l.value=!0,u.value=null;try{let n=await d.mutateAsync({username:e,password:t});if(console.log(`Login result:`,n),n.code===`0000`&&n.data){console.log(`Setting token and adminInfo...`),o.setToken(n.data.token),o.setAdminInfo(n.data.adminInfo),console.log(`isLogin after setToken:`,o.isLogin);let e=a.currentRoute.value.query.redirect;console.log(`Redirecting to:`,e||`/monisuo/dashboard`),!e||e.startsWith(`//`)?p():a.push(e)}else console.log(`Login failed:`,n.code,n.msg),u.value=n.msg||`登录失败`}catch(e){console.error(`Login error:`,e),u.value=e.response?.data?.msg||`网络错误,请稍后重试`}finally{l.value=!1}}return{loading:l,error:u,isLogin:s,adminInfo:c,logout:f,login:m}}export{a as t};
|
||||
import{ut as e}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{G as t,M as n,P as r}from"./index-BpHHjIYv.js";import{t as i}from"./monisuo-admin.api-DyXM8BcP.js";function a(){let a=r(),o=n(),{isLogin:s,adminInfo:c}=t(o),l=e(!1),u=e(null),d=i();function f(){o.logout(),a.push({path:`/auth/sign-in`})}function p(){a.push({path:`/monisuo/dashboard`})}async function m(e,t){l.value=!0,u.value=null;try{let n=await d.mutateAsync({username:e,password:t});if(console.log(`Login result:`,n),n.code===`0000`&&n.data){console.log(`Setting token and adminInfo...`),o.setToken(n.data.token),o.setAdminInfo(n.data.adminInfo),console.log(`isLogin after setToken:`,o.isLogin);let e=a.currentRoute.value.query.redirect;console.log(`Redirecting to:`,e||`/monisuo/dashboard`),!e||e.startsWith(`//`)?p():a.push(e)}else console.log(`Login failed:`,n.code,n.msg),u.value=n.msg||`登录失败`}catch(e){console.error(`Login error:`,e),u.value=e.response?.data?.msg||`网络错误,请稍后重试`}finally{l.value=!1}}return{loading:l,error:u,isLogin:s,adminInfo:c,logout:f,login:m}}export{a as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-DzgMZwe8.js";import{n as u}from"./button-DveXNdlZ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-CSACWwFG.js";var g=o({__name:`user-delete`,props:{user:{}},emits:[`remove`],setup(o,{emit:g}){let _=g;function v(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(o.user,null,2)))}),_(`remove`)}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this user: `+a(o.user.username)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a user with the ID `+a(o.user.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:v},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
|
||||
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-qOjHMYM8.js";import{n as u}from"./button-BTKRNUhQ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-DKtIxxgh.js";var g=o({__name:`user-delete`,props:{user:{}},emits:[`remove`],setup(o,{emit:g}){let _=g;function v(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(o.user,null,2)))}),_(`remove`)}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this user: `+a(o.user.username)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a user with the ID `+a(o.user.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:v},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
|
||||
1
monisuo-admin/dist/assets/user-resource-B_HhaB4h.js
vendored
Normal file
1
monisuo-admin/dist/assets/user-resource-B_HhaB4h.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import"./Teleport-qOjHMYM8.js";import"./button-BTKRNUhQ.js";import"./modal-DKtIxxgh.js";import{t as e}from"./user-resource-p1iwSw42.js";export{e as default};
|
||||
@@ -1 +0,0 @@
|
||||
import"./Teleport-DzgMZwe8.js";import"./button-DveXNdlZ.js";import"./modal-CSACWwFG.js";import{t as e}from"./user-resource-CZSXvHZo.js";export{e as default};
|
||||
@@ -1 +1 @@
|
||||
import{A as e,C as t,I as n,Q as r,R as i,St as a,b as o,ct as s,h as c,l,m as u,v as d,w as f,wt as p,x as m,y as h,yt as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{a as _,i as v,n as y,r as b,t as x}from"./SelectValue-BHFTqCZG.js";import{n as S}from"./lib-CC9cpJ8Y.js";import{c as C,d as w,l as T,r as E,s as D,u as O}from"./index-De70L21J.js";import{n as k}from"./button-DveXNdlZ.js";import{a as A,n as j,r as M}from"./modal-CSACWwFG.js";import{a as N,c as P,i as F,l as I,n as L,r as R,s as z,t as B}from"./vee-validate-zod-E1WJ2z9M.js";import{t as V}from"./Input-ChmjFEBQ.js";var H=D([`active`,`inactive`,`invited`,`suspended`]),U=D([`superadmin`,`admin`,`cashier`,`manager`]);C(O({id:w(),firstName:w(),lastName:w(),username:w(),email:w(),phoneNumber:w(),status:H,role:U,createdAt:E(),updatedAt:E()}));var W=O({id:w().optional(),firstName:w().min(1),lastName:w().min(1),username:w().min(1),email:T().min(1),phoneNumber:w().min(1),status:H,role:U}),G={class:`max-h-[500px] overflow-y-auto`},K=m({__name:`user-form`,props:{user:{}},emits:[`close`],setup(u,{emit:m}){let C=m,w=[`superadmin`,`admin`,`cashier`,`manager`],T=[`active`,`inactive`,`invited`,`suspended`],E=s({firstName:u.user?.firstName||``,lastName:u.user?.lastName||``,username:u.user?.username||``,email:u.user?.email||``,phoneNumber:u.user?.phoneNumber||``,status:u.user?.status||`active`,role:u.user?.role||`cashier`}),{handleSubmit:D}=P({validationSchema:B(W),initialValues:E}),O=D(e=>{let t={...e};u.user&&(t.id=u.user.id),S(`You submitted the following values:`,{description:f(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},f(`code`,{class:`text-white`},JSON.stringify(t,null,2)))}),C(`close`)});return(s,u)=>(n(),d(`div`,G,[c(`form`,{class:`space-y-8`,onSubmit:u[0]||=(...e)=>g(O)&&g(O)(...e)},[o(g(z),{name:`firstName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[1]||=[h(`First Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`lastName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[2]||=[h(`Last Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`username`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[3]||=[h(`User Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`email`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[4]||=[h(`Email address`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`phoneNumber`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[5]||=[h(`Phone Number`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`status`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[6]||=[h(`Status`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a status`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(T,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`role`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[7]||=[h(`Role`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a role`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(w,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(k),{type:`submit`,class:`w-full`},{default:r(()=>[...u[8]||=[h(` SaveChanges `,-1)]]),_:1})],32)]))}}),q=m({__name:`user-resource`,props:{user:{}},emits:[`close`],setup(e){let t=e,i=u(()=>t.user),a=u(()=>i.value?.id?`Edit User`:`New User`),s=u(()=>i.value?.id?`Edit user ${i.value.username}`:`Create new user`);return(e,t)=>(n(),d(`div`,null,[o(g(M),null,{default:r(()=>[o(g(j),null,{default:r(()=>[h(p(g(a)),1)]),_:1}),o(g(A),null,{default:r(()=>[h(p(g(s)),1)]),_:1})]),_:1}),o(K,{user:g(i),onClose:t[0]||=t=>e.$emit(`close`)},null,8,[`user`])]))}});export{q as t};
|
||||
import{A as e,C as t,I as n,Q as r,R as i,St as a,b as o,ct as s,h as c,l,m as u,v as d,w as f,wt as p,x as m,y as h,yt as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{a as _,i as v,n as y,r as b,t as x}from"./SelectValue-By3tfEiu.js";import{n as S}from"./lib-CC9cpJ8Y.js";import{c as C,d as w,l as T,r as E,s as D,u as O}from"./index-BpHHjIYv.js";import{n as k}from"./button-BTKRNUhQ.js";import{a as A,n as j,r as M}from"./modal-DKtIxxgh.js";import{a as N,c as P,i as F,l as I,n as L,r as R,s as z,t as B}from"./vee-validate-zod-DAPvk_fs.js";import{t as V}from"./Input-DOTs5aTB.js";var H=D([`active`,`inactive`,`invited`,`suspended`]),U=D([`superadmin`,`admin`,`cashier`,`manager`]);C(O({id:w(),firstName:w(),lastName:w(),username:w(),email:w(),phoneNumber:w(),status:H,role:U,createdAt:E(),updatedAt:E()}));var W=O({id:w().optional(),firstName:w().min(1),lastName:w().min(1),username:w().min(1),email:T().min(1),phoneNumber:w().min(1),status:H,role:U}),G={class:`max-h-[500px] overflow-y-auto`},K=m({__name:`user-form`,props:{user:{}},emits:[`close`],setup(u,{emit:m}){let C=m,w=[`superadmin`,`admin`,`cashier`,`manager`],T=[`active`,`inactive`,`invited`,`suspended`],E=s({firstName:u.user?.firstName||``,lastName:u.user?.lastName||``,username:u.user?.username||``,email:u.user?.email||``,phoneNumber:u.user?.phoneNumber||``,status:u.user?.status||`active`,role:u.user?.role||`cashier`}),{handleSubmit:D}=P({validationSchema:B(W),initialValues:E}),O=D(e=>{let t={...e};u.user&&(t.id=u.user.id),S(`You submitted the following values:`,{description:f(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},f(`code`,{class:`text-white`},JSON.stringify(t,null,2)))}),C(`close`)});return(s,u)=>(n(),d(`div`,G,[c(`form`,{class:`space-y-8`,onSubmit:u[0]||=(...e)=>g(O)&&g(O)(...e)},[o(g(z),{name:`firstName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[1]||=[h(`First Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`lastName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[2]||=[h(`Last Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`username`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[3]||=[h(`User Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`email`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[4]||=[h(`Email address`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`phoneNumber`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[5]||=[h(`Phone Number`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`status`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[6]||=[h(`Status`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a status`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(T,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`role`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[7]||=[h(`Role`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a role`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(w,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(k),{type:`submit`,class:`w-full`},{default:r(()=>[...u[8]||=[h(` SaveChanges `,-1)]]),_:1})],32)]))}}),q=m({__name:`user-resource`,props:{user:{}},emits:[`close`],setup(e){let t=e,i=u(()=>t.user),a=u(()=>i.value?.id?`Edit User`:`New User`),s=u(()=>i.value?.id?`Edit user ${i.value.username}`:`Create new user`);return(e,t)=>(n(),d(`div`,null,[o(g(M),null,{default:r(()=>[o(g(j),null,{default:r(()=>[h(p(g(a)),1)]),_:1}),o(g(A),null,{default:r(()=>[h(p(g(s)),1)]),_:1})]),_:1}),o(K,{user:g(i),onClose:t[0]||=t=>e.$emit(`close`)},null,8,[`user`])]))}});export{q as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
monisuo-admin/dist/index.html
vendored
4
monisuo-admin/dist/index.html
vendored
@@ -14,11 +14,11 @@
|
||||
name="keywords"
|
||||
content="vue,vue-router,vite,typescript,tailwindcss,shadcn-vue,tanstack-vue-query,tanstack-table,eslint,pinia,pnpm"
|
||||
/>
|
||||
<script type="module" crossorigin src="/assets/index-De70L21J.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BpHHjIYv.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue.runtime.esm-bundler-DS0mm12S.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dist-3yfE1dPa.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lib-CC9cpJ8Y.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BeMvYSwb.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DzGkD_L8.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user