WidgetDesk Skill
Environment
- - Widget directory: INLINECODE0
- Template directory:
~/.claude/skills/widget/templates/ after install, or .claude/skills/widget/templates/ inside this repo - Host requirement: Übersicht is installed and available at
/Applications/Übersicht.app or INLINECODE4
First Step
- - When working inside a WidgetDesk repo clone, run
bash scripts/setup.sh first - INLINECODE6 is the default entrypoint: it installs missing host dependencies, starts Übersicht, prepares the widget directory, installs the skill, and verifies the result
- Use
bash scripts/setup.sh --check only when the user explicitly wants a dry-run check or when you are diagnosing an installation problem - Use
bash ~/.claude/skills/widget/scripts/doctor.sh only for a fast post-install health check - After setup, use the installed skill path under INLINECODE9
Reference Files
- - Reusable implementation patterns: patterns.md
- Host management scripts:
scripts/ for setup, starting Übersicht, checking the environment, installing widgets, and listing widgets
Hard Constraints
1. Layout
- - All widgets should default to INLINECODE11
- Any bottom-aligned widget must keep INLINECODE12
- Default edge spacing is INLINECODE13
- Default width should stay within
140px to INLINECODE15 - Default height should stay within
48px to INLINECODE17 - Only exceed these dimensions when the user explicitly asks for a large widget
2. Interaction
- - Display-only widgets should default to INLINECODE18
- Only enable interaction when the widget truly needs clicking, dragging, or text input
- Interactive controls must stay easy to hit
- Avoid complex multi-step desktop interactions by default
3. Refresh
- - Command-driven widgets should normally refresh between
1000ms and INLINECODE20 - Refresh below
1000ms only for clocks or clearly time-sensitive UI - Pure frontend widgets should use INLINECODE22
- Avoid high-frequency network requests
4. Implementation
- - Use lowercase kebab-case filenames
- Prefer existing templates and
patterns.md before inventing new structure - Prefer built-in macOS capabilities over extra dependencies
- Do not hardcode secrets
- Keep widgets single-file by default unless the user explicitly asks for more complexity
5. Visual Style
- - Keep the style consistent, restrained, and macOS-like
- Default to dark translucent cards
- Recommended corner radius:
14px to INLINECODE25 - Prefer
SF Pro Display and INLINECODE27 - Keep motion short, light, and purposeful
- Do not invent a brand-new visual language for every widget
Operations
CODEBLOCK0
Prefer the scripts/ helpers for host operations. Only write raw widget files directly when creating or replacing actual JSX content.
When the user asks for a standard widget that already exists as a built-in template, do not rewrite it from scratch. Run scripts/setup.sh if needed, then install the matching template.
Do not install or copy any widget file until scripts/setup.sh has completed successfully and the host app is available.
Widget Format
CODEBLOCK1
Required Rules
Rule 1: Never import React from react
CODEBLOCK2
Rule 2: Never call hooks directly inside render
CODEBLOCK3
Rule 3: Never return a function from a state updater
// Bad
setRemaining(r => {
if (r <= 1) return p => p === 'work' ? BREAK : WORK
})
// Good
useEffect(() => {
if (remaining !== 0) return
setPhase(p => p === 'work' ? 'break' : 'work')
setRemaining(p => p === 'work' ? BREAK : WORK)
}, [remaining])
Position Cheatsheet
| Position | CSS |
|---|
| Bottom right | INLINECODE33 |
| Bottom left |
bottom: 90px; left: 40px; |
| Top right |
top: 40px; right: 40px; |
| Top left |
top: 40px; left: 40px; |
Built-In Templates
| File | Purpose | Default Position |
|---|
| INLINECODE37 | Clock and date | Bottom right |
| INLINECODE38 |
Alternate horizontal clock | Bottom right |
|
pomodoro.jsx | Pomodoro timer | Bottom left |
|
now-playing.jsx | Apple Music now playing | Bottom center |
|
system-stats.jsx | CPU, memory, battery | Top right |
|
weather-canvas.jsx | Animated weather card | Top left |
|
git-pulse.jsx | Local Git activity heatmap | Top right |
|
memo-capsule.jsx | Local quick-note capsule | Top center |
|
volume-knob.jsx | System volume control knob | Right side |
|
tap-counter.jsx | Simple interactive counter with persisted local state | Bottom right |
Copy a template directly when it already matches the request, or use it as the starting point for a custom widget.
Style Baseline
CODEBLOCK5
Add this for display-only widgets:
CODEBLOCK6
Useful macOS Shell Commands
CODEBLOCK7
Remember to .trim() command output before rendering it.
WidgetDesk 技能
环境
- - 小组件目录:~/Library/Application Support/Übersicht/widgets/
- 模板目录:安装后为 ~/.claude/skills/widget/templates/,或本仓库内的 .claude/skills/widget/templates/
- 宿主要求:已安装 Übersicht 且位于 /Applications/Übersicht.app 或 /Applications/Uebersicht.app
第一步
- - 在 WidgetDesk 仓库克隆内工作时,先运行 bash scripts/setup.sh
- scripts/setup.sh 是默认入口点:它会安装缺失的宿主依赖、启动 Übersicht、准备小组件目录、安装技能并验证结果
- 仅当用户明确要求进行空运行检查或排查安装问题时,才使用 bash scripts/setup.sh --check
- 仅用于安装后的快速健康检查时,使用 bash ~/.claude/skills/widget/scripts/doctor.sh
- 安装完成后,使用 ~/.claude/skills/widget/ 下的已安装技能路径
参考文件
- - 可复用的实现模式:patterns.md
- 宿主管理脚本:scripts/ 用于安装、启动 Übersicht、检查环境、安装小组件和列出小组件
硬性约束
1. 布局
- - 所有小组件默认使用 position: fixed
- 任何底部对齐的小组件必须保持 bottom >= 90px
- 默认边缘间距为 40px
- 默认宽度应保持在 140px 到 360px 之间
- 默认高度应保持在 48px 到 220px 之间
- 仅当用户明确要求大型小组件时,才超出这些尺寸
2. 交互
- - 仅显示的小组件默认使用 pointer-events: none
- 仅当小组件确实需要点击、拖拽或文本输入时才启用交互
- 交互控件必须易于点击
- 默认避免复杂的多步骤桌面交互
3. 刷新
- - 命令驱动的小组件通常应在 1000ms 到 600000ms 之间刷新
- 仅对时钟或明显对时间敏感的 UI 使用低于 1000ms 的刷新频率
- 纯前端小组件应使用 refreshFrequency = false
- 避免高频率的网络请求
4. 实现
- - 使用小写短横线命名法(kebab-case)文件名
- 在创建新结构前,优先使用现有模板和 patterns.md
- 优先使用 macOS 内置功能,而非额外依赖
- 不要硬编码密钥
- 默认保持小组件为单文件,除非用户明确要求更复杂
5. 视觉风格
- - 保持风格一致、克制且具有 macOS 风格
- 默认使用深色半透明卡片
- 推荐圆角半径:14px 到 20px
- 优先使用 SF Pro Display 和 SF Mono
- 保持动画简短、轻量且有意义
- 不要为每个小组件创造全新的视觉语言
操作
bash
本仓库内的首次安装
bash scripts/setup.sh
bash scripts/setup.sh --check
安装后的快速健康检查
bash ~/.claude/skills/widget/scripts/doctor.sh
启动 Übersicht
bash ~/.claude/skills/widget/scripts/start-uebersicht.sh
安装或更新模板小组件
bash ~/.claude/skills/widget/scripts/install-widget.sh \
~/.claude/skills/widget/templates/clock.jsx
列出已安装的小组件
bash ~/.claude/skills/widget/scripts/list-widgets.sh
编写全新的自定义小组件
cat > ~/Library/Application\ Support/Übersicht/widgets/{name}.jsx << EOF
{widget_code}
EOF
隐藏小组件而不删除
mv ~/Library/Application\ Support/Übersicht/widgets/{name}.jsx \
~/Library/Application\ Support/Übersicht/widgets/{name}.jsx.disabled
显示已隐藏的小组件
mv ~/Library/Application\ Support/Übersicht/widgets/{name}.jsx.disabled \
~/Library/Application\ Support/Übersicht/widgets/{name}.jsx
删除小组件
rm ~/Library/Application\ Support/Übersicht/widgets/{name}.jsx
优先使用 scripts/ 中的辅助工具进行宿主操作。仅在创建或替换实际的 JSX 内容时,才直接编写原始小组件文件。
当用户要求的标准小组件已作为内置模板存在时,不要从头重写。如有需要,先运行 scripts/setup.sh,然后安装匹配的模板。
在 scripts/setup.sh 成功完成且宿主应用可用之前,不要安装或复制任何小组件文件。
小组件格式
jsx
// 可选的 shell 命令。stdout 作为 output 传入 render。
export const command = date +%H:%M:%S
// 刷新频率(毫秒)。纯前端小组件应使用 false。
export const refreshFrequency = 1000
// CSS 定位。使用 position: fixed。
export const className =
position: fixed;
bottom: 90px;
right: 40px;
// render 接收 { output, error }
export const render = ({ output }) => {
return
{output?.trim()}
}
必需规则
规则 1:不要从 react 导入 React
jsx
// 错误
import { useState } from react
// 正确
import { React } from uebersicht
规则 2:不要在 render 内部直接调用 hooks
jsx
// 错误
export const render = () => {
const [n, setN] = React.useState(0)
}
// 正确
const Widget = () => {
const { useState } = React
const [n, setN] = useState(0)
return
{n}
}
export const render = () =>
规则 3:不要从状态更新函数中返回函数
jsx
// 错误
setRemaining(r => {
if (r <= 1) return p => p === work ? BREAK : WORK
})
// 正确
useEffect(() => {
if (remaining !== 0) return
setPhase(p => p === work ? break : work)
setRemaining(p => p === work ? BREAK : WORK)
}, [remaining])
位置速查表
| 位置 | CSS |
|---|
| 右下角 | bottom: 90px; right: 40px; |
| 左下角 |
bottom: 90px; left: 40px; |
| 右上角 | top: 40px; right: 40px; |
| 左上角 | top: 40px; left: 40px; |
内置模板
| 文件 | 用途 | 默认位置 |
|---|
| clock.jsx | 时钟和日期 | 右下角 |
| horizon-clock.jsx |
替代水平时钟 | 右下角 |
| pomodoro.jsx | 番茄钟计时器 | 左下角 |
| now-playing.jsx | Apple Music 当前播放 | 底部居中 |
| system-stats.jsx | CPU、内存、电池 | 右上角 |
| weather-canvas.jsx | 动画天气卡片 | 左上角 |
| git-pulse.jsx | 本地 Git 活动热力图 | 右上角 |
| memo-capsule.jsx | 本地快速笔记胶囊 | 顶部居中 |
| volume-knob.jsx | 系统音量控制旋钮 | 右侧 |
| tap-counter.jsx | 带持久化本地状态的简单交互计数器 | 右下角 |
当模板已匹配请求时直接复制,或将其作为自定义小组件的起点。
样式基准
css
background: rgba(8, 12, 20, 0.72);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35);
font-family: -apple-system, BlinkMacSystemFont, SF Pro Display, sans-serif;
color: rgba(255, 255, 255, 0.92);
为仅显示的小组件添加以下内容:
css
pointer-events: none;
有用的 macOS Shell 命令
bash