Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions plugins/tiga/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Dependencies
node_modules/

# Build output
dist/

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*

# Environment
.env
.env.local
.env.*.local

# Vite
*.local

# TypeScript
*.tsbuildinfo

# Auto-generated by unplugin-auto-import / unplugin-vue-components
# 注:auto-imports.d.ts 与 components.d.ts 需纳入版本控制,
# 以保证 CI 与协作者的类型检查(vue-tsc)正常运行
138 changes: 138 additions & 0 deletions plugins/tiga/.mimicode/skills/note-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
name: note-workflow
description: 按规则优化、合并、发布笔记的统一工作流。适用于 Area/ 和 Resource/ 下的笔记处理,包含格式优化、多源合并、发布文章三种模式。
---

# 笔记处理工作流

> 该技能封装了 my-note 项目中反复执行的笔记处理工作流:按规则优化、按规则合并、按规则创建发布笔记。

## 适用场景

用户说以下任一表述时触发此技能:

- "按规则优化Area/XXX/第Y章笔记"
- "按规则合并Resource/JavaSE/Java第Y章..."
- "按规则创建发布笔记Output/GoF设计模式/..."
- "提炼笔记"、"提取发布笔记"
- 任何包含"按规则"且涉及笔记处理的请求

## 前置条件

1. 确认当前工作目录是笔记项目(存在 `.claude/rules/` 目录)
2. 识别目标路径,确定适用的规则文件

## 统一工作流

### Step 1: 识别模式

根据用户指令判断处理模式:

| 模式 | 信号词 | 输入 | 输出 |
|------|--------|------|------|
| **优化** | "优化"、"格式优化" | 单个来源笔记 | 优化后的笔记(同路径覆盖或新建) |
| **合并** | "合并"、"整合" | 多个来源笔记 | 合并后的笔记(Resource/ 下) |
| **发布** | "创建发布"、"提炼"、"提取发布" | Area/ 下的笔记 | Output/ 下的发布文章 |

### Step 2: 加载规则

根据目标路径查找适用的规则文件:

```
规则查找顺序:
1. .claude/rules/Area/{子路径}-rules.md — 领域专属规则
2. .claude/rules/Output/{子路径}-rules.md — 发布规范(发布模式)
3. .claude/rules/common.md — 通用格式规则
```

**已知规则文件映射**:
| 目标路径 | 规则文件 |
|----------|----------|
| `Area/JDBC/**` | `Area/jdbc-rules.md` |
| `Area/Java/JavaSE/**` | `Area/javase-rules.md` |
| `Area/Java/设计模式/**` | `Area/design-pattern-rules.md` |
| `Output/**`(设计模式) | `Output/design-pattern-article-rules.md` |
| 所有路径 | `common.md` |

**必须完整阅读规则文件**,不能跳过或只读部分。

### Step 3: 读取来源笔记

**优化模式**:
- 读取目标笔记的完整内容
- 如有多个来源目录(如 JDBC 的 `2024老杜` 和 `老版老杜`),按规则文件中的来源分配表读取

**合并模式**:
- 按规则文件中的"整合章节清单"找到所有来源
- 逐个读取来源笔记的完整内容
- 标记每个来源的独有内容

**发布模式**:
- 读取 Area/ 下的源笔记
- 读取发布规范文件(如 `design-pattern-article-rules.md`)

### Step 4: 按规则处理

**优化模式执行清单**:
- [ ] 代码块、引用块、列表前面无空行
- [ ] 表格前面允许空行
- [ ] 标题无序号
- [ ] 代码块前有文字描述
- [ ] ⚠️ 和 💡 标记正确使用
- [ ] 面试问答使用引用块格式(问句在上,`> 答案` 在下)
- [ ] 内容准确真实,不编造
- [ ] 添加"进阶内容"和"要点速记"章节

**合并模式执行清单**:
- [ ] 去重:多个来源都讲的内容,保留最清晰版本
- [ ] 互补:每个来源独有的内容全部收录
- [ ] 升级:补充面试问法、实战场景、踩坑经验
- [ ] 检查规则文件中的"注释提取清单"(如有)
- [ ] 合并后自检:对照来源目录逐项确认无遗漏
- [ ] 应用所有优化模式的格式规则

**发布模式执行清单**:
- [ ] 按发布规范的章节结构编写(前言→概念→实现→总结→相似模式区分→练习→扩展)
- [ ] 必须有 mermaid UML 图
- [ ] 实现代码使用 GoF 原始类名
- [ ] 业务场景代码有实际含义的命名
- [ ] 不使用第二人称
- [ ] 总结包含:本质、什么时候用、什么时候不用、简单记忆口诀

### Step 5: 写入输出

**优化模式**:
- 将优化后的笔记写入目标路径
- 询问用户是否归档原笔记(除非用户明确说"不要归档")

**合并模式**:
- 将合并后的笔记写入 `Resource/` 下对应路径
- 将原笔记归档到 `Archive/` 下对应路径

**发布模式**:
- 将发布文章写入 `Output/` 下对应路径
- 不添加笔记属性(frontmatter)

### Step 6: 自检

处理完成后,执行最终自检:

1. **格式自检**:抽查 3-5 处代码块/引用块/列表,确认前面无空行
2. **内容自检**:确认无编造内容,不确定的标注提醒用户
3. **完整性自检**(合并模式):对照来源目录逐项确认
4. **输出确认**:告知用户处理完成,列出变更摘要

## 常见问题处理

### 笔记中有图片
- 保留图片引用,使用相对路径 `assets/章节名/图片文件名`
- 如果图片无法解析,用文字描述图片内容

### 来源笔记质量差
- 不要照搬质量差的内容
- 按规则文件中的"取舍规则"决定保留/删除/补充

### 用户对结果不满意
- 用户可能说"内容很浅,没有深度"→ 补充"为什么"、实战场景、踩坑经验
- 用户可能说"不要精简"→ 保留代码示例和表格,只优化格式
- 用户可能说"面试题格式不对"→ 确认使用引用块格式
49 changes: 49 additions & 0 deletions plugins/tiga/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# tiga

ZTools 插件:定时提醒提肛运动。Vue 3 + Vite + TypeScript + Element Plus。

## 命令

- `npm run dev` — Vite 开发服务器,地址 `localhost:5173`
- `npm run build` — `vue-tsc && vite build`(先类型检查再打包)

无 lint、format 或 test 命令。

## 两个执行上下文

这是最重要的架构事实:

1. **Vue 渲染层**(`src/`)— 标准 Vue 3 应用,挂载在 `index.html`,运行在浏览器/WebView 中。
2. **Node.js preload 层**(`public/preload/services.js`)— CommonJS(`require()`),运行在 ZTools 主进程中。负责定时器、通知和存储。`public/preload/package.json` 设置了 `"type": "commonjs"`。

两者通过 `window.services`(preload 暴露)和 `window.ztools`(ZTools 宿主 API)通信。

## 关键文件

- `public/plugin.json` — ZTools 插件清单,定义 features、commands、preload 路径和开发 URL。
- `public/preload/services.js` — 定时器管理、工作时段判断、桌面通知、存储(生产用 `ztools.dbStorage`,开发用文件存储)。
- `public/exercise-guide.html` — 独立的原生 JS 弹窗(**不是** Vue 组件),在 `notify+popup` 模式下通过 `BrowserWindow` 加载。
- `src/types.ts` — 所有 TypeScript 接口、默认配置、存储键名、工具函数。
- `src/App.vue` — 标签页路由(统计/设置/教程),包含开发模式下 `window.services` 和 `window.ztools` 的 mock 降级。
- `src/env.d.ts` — `window.services` 和 `Services` 接口的全局类型声明。

## 开发模式

`npm run dev` 时无 ZTools API 可用。`App.vue` 中的 mock:
- `window.services` — 用 `localStorage` 降级
- `window.ztools` — 用 console.log 占位

preload 服务(`services.js`)在开发模式下**不会加载**。运动弹窗降级为 Vue `ExerciseGuide` 组件(模态覆盖层),而非真实 `BrowserWindow`。

## 构建

- `vite.config.js` 设置 `base: './'` 以使用相对路径(ZTools 插件加载必需)。
- `tsconfig.json` 中 `"strict": false`,`"noImplicitAny": false`。
- TypeScript 类型来自 `@ztools-center/ztools-api-types`。

## 存储

两个存储键:`tiga_config` 和 `tiga_stats`。
- 生产环境:`window.ztools.dbStorage.getItem/setItem`
- 开发降级(preload):基于文件的 JSON,存储在 `userData` 路径
- 开发降级(渲染层):`localStorage`
52 changes: 52 additions & 0 deletions plugins/tiga/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 更新日志

## 1.1.0 (2026-06-16)

### 新增

- 统计页新增"总打卡天数"和"总完成次数"展示
- 设置页新增"恢复默认设置"按钮,一键重置为推荐配置
- 教程文档全面重写,聚焦久坐办公人群,内容更通俗易读
- 教程渲染器支持四级标题(####)和引用块(>)
- Element Plus 按需自动引入,减少打包体积

### 优化

- 默认运动参数调整为教程推荐值:收缩 5 秒、放松 10 秒、重复 2 次
- 连续打卡算法修复:中间缺失一天即中断,真正计算连续天数
- 连续打卡算法性能优化:O(n) 查找改为 O(1) Map 查找
- 通知 API 优先使用 ZTools 平台 `showNotification`,仅在需要点击回调时降级到 Web Notification
- 设置页 watcher 缩窄为只监听 `workTimeMode` 字段,减少不必要的重计算
- 统一计数逻辑为 `services.addRecord()` 单一入口,消除三处重复代码
- 移除所有非 ZTools 环境的降级代码,简化整体架构
- App.vue 大幅精简,移除开发模式 mock 和冗余弹窗逻辑

### 修复

- 修复通知点击后出现两个弹窗的问题(生产环境只弹一个)
- 修复统计页 `el-switch` 绑定只读 computed 的潜在问题
- 修复 `exercise-guide.html` CSS 属性重复覆盖
- 修复 `exercise-guide.html` 运动完成后打卡记录静默丢失的问题

## 1.0.0 (2026-06-11)

### 新增

- 定时提醒功能,可自定义提醒间隔(1-120分钟)及工作时段
- 桌面通知提醒,支持多种文案风格(随机/正经/搞怪)
- 运动引导弹窗,展示收缩/放松倒计时,引导用户完成运动
- 统计打卡功能,记录每日完成次数和连续打卡天数
- 每次完成的时间点记录,可在统计页查看详细时间
- 教程指南,基于医学文献的专业提肛运动指导
- 三种工作时段模式:固定时段、多时段、周几+时段
- 两种提醒方式:仅通知、通知+弹窗
- 两种计数方式:自动计数、手动计数
- 自定义通知文案,支持添加正经和搞怪文案
- 深色模式适配

### 优化

- 运动弹窗倒计时动画改为 requestAnimationFrame,60fps 平滑过渡
- 运动弹窗关闭按钮样式简化
- 设置页面切换后配置正确保留
- 修复弹窗重复打开的问题
99 changes: 99 additions & 0 deletions plugins/tiga/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# 提肛助手(tiga)

> 定时提醒提肛运动,关爱久坐族盆底健康

## 最近更新

**v1.1.0** (2026-06-16)

- 统计页新增总打卡天数和总完成次数
- 设置页新增"恢复默认设置"按钮
- 教程全面重写,聚焦久坐办公人群
- 默认运动参数调整为推荐值(收缩 5 秒、放松 10 秒、重复 2 次)
- 修复通知点击后弹窗重复的问题

[完整更新日志](CHANGELOG.md)

---

## 功能介绍

### 定时提醒

每 30 分钟(可自定义)自动发送桌面通知,提醒你站起来活动。专为久坐办公人群设计。

### 运动引导

弹出运动引导窗口,按节奏完成收缩/放松盆底肌训练,全程倒计时引导,60fps 平滑动画。

### 统计打卡

记录每次完成情况,展示今日完成次数、连续打卡天数、总打卡天数和总完成次数。

### 教程指南

专为久坐族编写的通俗教程,覆盖正确姿势、呼吸配合、训练频率、注意事项等。

## 使用方法

在 ZTools 中输入以下命令:

| 命令 | 功能 |
|------|------|
| `提肛` / `提肛助手` | 打开设置页面 |
| `提肛统计` | 查看完成记录 |
| `提肛教程` | 学习正确姿势 |

## 设置说明

### 提醒间隔

两次提醒之间的间隔时间,范围 1-120 分钟,默认 **30 分钟**(每坐半小时提醒一次)。

### 工作时段

只在设定的时间段内提醒:

- **固定时段**:单个时间范围,如 09:00 - 18:00
- **多时段**:多个时间段,如 09:00-12:00, 14:00-18:00
- **周几+时段**:按周一到周日分别配置

### 提醒方式

- **仅插件通知**:直接弹出运动引导窗口
- **桌面通知+弹窗**:发送系统通知,点击后弹出运动引导窗口

### 运动参数

- **收缩时长**:默认 5 秒
- **放松时长**:默认 10 秒(收缩的 2 倍,给肌肉充分休息)
- **重复次数**:默认 2 次(偏保守,适合碎片化提醒)

> 默认参数采用"碎片化提醒"策略:每次提醒只做 2 下,安全不累。如果你想做完整训练,可以把重复次数调到 10~15。

### 文案风格

- **随机**:从全部文案中随机选择
- **正经**:只使用正式风格的文案
- **搞怪**:只使用趣味风格的文案

支持自定义添加文案。

### 恢复默认设置

设置页底部可一键恢复所有设置为推荐值。

## 推荐用法

**"每天专心练 3 组,每次起身做 2 下。"**

- **专心练**:选早、中、晚固定时间,安静做一组(10~15 次)
- **起身做**:每次站起来接水、上厕所时,顺便收紧 2 下,不求做满

## 技术栈

Vue 3 + Vite + TypeScript + Element Plus

## 开源协议

MIT License
11 changes: 11 additions & 0 deletions plugins/tiga/auto-imports.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const ElMessage: typeof import('element-plus/es').ElMessage
const ElMessageBox: typeof import('element-plus/es').ElMessageBox
}
Loading
Loading