clamper-ai 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PRD.md +416 -0
- package/README.md +156 -0
- package/bin/clamper.mjs +66 -0
- package/dashboard/app.js +287 -0
- package/dashboard/index.html +137 -0
- package/dashboard/style.css +121 -0
- package/package.json +24 -0
- package/skills/clawkit-sync/SKILL.md +160 -0
- package/skills/code-mentor/SKILL.md +85 -0
- package/skills/csv-pipeline/SKILL.md +82 -0
- package/skills/developer/SKILL.md +57 -0
- package/skills/image/SKILL.md +71 -0
- package/skills/json/SKILL.md +59 -0
- package/skills/productivity/SKILL.md +68 -0
- package/skills/quick-reminders/SKILL.md +70 -0
- package/skills/svg-draw/SKILL.md +75 -0
- package/skills/weather/SKILL.md +72 -0
- package/skills/workspace-manager/SKILL.md +69 -0
- package/src/cron.mjs +30 -0
- package/src/dashboard.mjs +69 -0
- package/src/doctor.mjs +69 -0
- package/src/init.mjs +145 -0
- package/src/log-activity.mjs +26 -0
- package/src/scaffold.mjs +57 -0
- package/src/skills.mjs +52 -0
- package/src/status.mjs +43 -0
- package/src/sync.mjs +585 -0
- package/src/update.mjs +100 -0
- package/src/upgrade.mjs +104 -0
- package/src/utils.mjs +67 -0
- package/src/validate.mjs +66 -0
- package/templates/AGENTS.md +77 -0
- package/templates/HEARTBEAT.md +12 -0
- package/templates/IDENTITY.md +7 -0
- package/templates/LEARNINGS.md +14 -0
- package/templates/MEMORY.md +14 -0
- package/templates/PROTOCOL_COST_EFFICIENCY.md +30 -0
- package/templates/SKILLS-INDEX.md +21 -0
- package/templates/SOUL.md +22 -0
- package/templates/TOOLS.md +14 -0
- package/templates/USER.md +5 -0
- package/templates/memory/knowledge/about-me.md +13 -0
- package/templates/scripts/nightly-consolidation.sh +54 -0
- package/templates/tasks/QUEUE.md +10 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clamper-sync
|
|
3
|
+
description: "Sync agent state with Clamper cloud dashboard. Pushes model, cron jobs, connected accounts, activity, and preferences to the Clamper API. Pulls pending changes from dashboard."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Clamper Sync Skill
|
|
7
|
+
|
|
8
|
+
Synchronizes your OpenClaw agent state with the Clamper cloud dashboard at https://clamper.tech. This enables remote monitoring and control of your agent from any browser.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
- A `skills/.clamper/config.json` file with your API key:
|
|
13
|
+
```json
|
|
14
|
+
{ "apiKey": "ck_...", "dashboardUrl": "https://clamper.tech" }
|
|
15
|
+
```
|
|
16
|
+
- If this file doesn't exist, skip sync silently.
|
|
17
|
+
|
|
18
|
+
## Sync Protocol
|
|
19
|
+
|
|
20
|
+
Run this on every heartbeat (or at least every 15 minutes). If any step fails, log the error and continue — never crash or block the heartbeat.
|
|
21
|
+
|
|
22
|
+
### Step 1: Read Config
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cat skills/.clamper/config.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Extract the `apiKey` value. If the file is missing or has no `apiKey`, stop here silently.
|
|
29
|
+
|
|
30
|
+
### Step 2: Gather State
|
|
31
|
+
|
|
32
|
+
Collect the following data. Each piece is optional — if you can't read something, use `null`.
|
|
33
|
+
|
|
34
|
+
#### 2a. Current Model
|
|
35
|
+
|
|
36
|
+
Use the `session_status` tool (no parameters). Extract the `model` field from the response.
|
|
37
|
+
|
|
38
|
+
#### 2b. Connected Accounts
|
|
39
|
+
|
|
40
|
+
Read `TOOLS.md` and scan for sections that contain API keys, tokens, or credentials. For each one, extract:
|
|
41
|
+
- `service`: The section heading (e.g., "Google Workspace", "Stripe", "Twitter/X API")
|
|
42
|
+
- `maskedKey`: Take the credential value, show first 4 and last 4 characters, mask the rest with `***` (e.g., `sk_t***1OkA`)
|
|
43
|
+
- `type`: "api_key", "token", "oauth", or "bearer"
|
|
44
|
+
|
|
45
|
+
Example parsing logic:
|
|
46
|
+
- Look for lines matching patterns like `**API Key:**`, `**Token:**`, `**Bearer Token:**`, `**Secret Key:**`
|
|
47
|
+
- Extract the value after the `:`
|
|
48
|
+
- Mask it: `value.slice(0, 4) + '***' + value.slice(-4)`
|
|
49
|
+
|
|
50
|
+
#### 2c. Cron Jobs
|
|
51
|
+
|
|
52
|
+
Use the cron tool with `action: "list"`. Collect the array of cron jobs (id, schedule, description).
|
|
53
|
+
|
|
54
|
+
#### 2d. Recent Activity
|
|
55
|
+
|
|
56
|
+
Read today's daily note: `memory/daily/YYYY-MM-DD.md` (use today's date). Extract the last 10 bullet points or log entries. If the file doesn't exist, use `[]`.
|
|
57
|
+
|
|
58
|
+
#### 2e. Preferences
|
|
59
|
+
|
|
60
|
+
Read `skills/.clamper/config.json` fully. Include any preferences beyond `apiKey` (e.g., `theme`, `notifications`, `syncInterval`).
|
|
61
|
+
|
|
62
|
+
#### 2f. Memory Stats
|
|
63
|
+
|
|
64
|
+
Run these shell commands:
|
|
65
|
+
```bash
|
|
66
|
+
# Count daily note files
|
|
67
|
+
ls memory/daily/*.md 2>/dev/null | wc -l
|
|
68
|
+
|
|
69
|
+
# Count knowledge files
|
|
70
|
+
ls memory/knowledge/*.md 2>/dev/null | wc -l
|
|
71
|
+
|
|
72
|
+
# MEMORY.md size in bytes
|
|
73
|
+
wc -c < MEMORY.md 2>/dev/null || echo 0
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 2g. Installed Skills
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
ls -d skills/*/ 2>/dev/null | sed 's|skills/||;s|/||'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
List directory names under `skills/`, excluding hidden dirs like `.clamper` and `.clawhub`.
|
|
83
|
+
|
|
84
|
+
### Step 3: Push State to API
|
|
85
|
+
|
|
86
|
+
Execute this curl command (via shell exec):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
curl -s -X POST https://clamper-api.vercel.app/api/dashboard/sync \
|
|
90
|
+
-H "Content-Type: application/json" \
|
|
91
|
+
-d '{
|
|
92
|
+
"apiKey": "<API_KEY_FROM_CONFIG>",
|
|
93
|
+
"state": {
|
|
94
|
+
"model": "<current model string>",
|
|
95
|
+
"accounts": [
|
|
96
|
+
{ "service": "Service Name", "maskedKey": "sk_t***1OkA", "type": "api_key" }
|
|
97
|
+
],
|
|
98
|
+
"cronJobs": [ { "id": "...", "schedule": "...", "description": "..." } ],
|
|
99
|
+
"recentActivity": ["line 1", "line 2"],
|
|
100
|
+
"preferences": { "theme": "dark" },
|
|
101
|
+
"memoryStats": {
|
|
102
|
+
"dailyNotes": 42,
|
|
103
|
+
"knowledgeFiles": 7,
|
|
104
|
+
"memoryMdBytes": 15360
|
|
105
|
+
},
|
|
106
|
+
"installedSkills": ["weather", "productivity", "csv-pipeline"],
|
|
107
|
+
"syncedAt": "<ISO 8601 timestamp>"
|
|
108
|
+
}
|
|
109
|
+
}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Replace all `<...>` placeholders with actual gathered values. The `syncedAt` field should be the current time in ISO 8601 format.
|
|
113
|
+
|
|
114
|
+
### Step 4: Process Pending Changes
|
|
115
|
+
|
|
116
|
+
The sync API response is JSON with this structure:
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"ok": true,
|
|
120
|
+
"pendingChanges": [
|
|
121
|
+
{ "id": "ch_123", "type": "model_switch", "data": { "model": "anthropic/claude-sonnet-4-20250514" } },
|
|
122
|
+
{ "id": "ch_456", "type": "connect_account", "data": { "service": "OpenAI", "section": "## OpenAI\n- **API Key:** sk-..." } },
|
|
123
|
+
{ "id": "ch_789", "type": "disconnect_account", "data": { "service": "Stripe" } },
|
|
124
|
+
{ "id": "ch_012", "type": "preferences", "data": { "theme": "light", "notifications": true } }
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Process each pending change:
|
|
130
|
+
|
|
131
|
+
#### `model_switch`
|
|
132
|
+
Use `session_status` tool with the `model` parameter set to `data.model` to switch the active model.
|
|
133
|
+
|
|
134
|
+
#### `connect_account`
|
|
135
|
+
Append `data.section` to the end of `TOOLS.md` (before the final `---` line if one exists, otherwise at the end). The section content is pre-formatted markdown.
|
|
136
|
+
|
|
137
|
+
#### `disconnect_account`
|
|
138
|
+
Find the section in `TOOLS.md` whose heading matches `data.service` (case-insensitive). Remove that entire section (from `## Service Name` to the next `##` heading or end of file).
|
|
139
|
+
|
|
140
|
+
#### `preferences`
|
|
141
|
+
Read `skills/.clamper/config.json`, merge `data` into the existing object (overwriting matching keys), and write it back.
|
|
142
|
+
|
|
143
|
+
### Step 5: Log Result
|
|
144
|
+
|
|
145
|
+
Append a line to today's `memory/daily/YYYY-MM-DD.md`:
|
|
146
|
+
|
|
147
|
+
```markdown
|
|
148
|
+
- **[Clamper Sync]** Synced at HH:MM. Pushed state (N accounts, M skills, K cron jobs). Processed X pending changes.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
- If `skills/.clamper/config.json` is missing → skip sync entirely, no error
|
|
154
|
+
- If the API returns non-200 or curl fails → log "Clamper sync failed (unreachable)" to daily note, continue
|
|
155
|
+
- If any individual state-gathering step fails → use `null` for that field, still sync the rest
|
|
156
|
+
- Never let sync errors block the heartbeat or crash the agent
|
|
157
|
+
|
|
158
|
+
## Manual Trigger
|
|
159
|
+
|
|
160
|
+
Users can also trigger sync manually by running `clamper sync` from the terminal, which executes the same protocol programmatically.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-mentor
|
|
3
|
+
description: "Interactive programming tutor for all levels. Teaches through lessons, code review, debugging, and project mentoring."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Mentor
|
|
7
|
+
|
|
8
|
+
An AI programming tutor that adapts to the learner's level.
|
|
9
|
+
|
|
10
|
+
## Before Starting
|
|
11
|
+
|
|
12
|
+
Assess the user's level:
|
|
13
|
+
- **Beginner** — New to programming. Clear explanations, foundational concepts, simple examples.
|
|
14
|
+
- **Intermediate** — Knows basics. Best practices, patterns, problem-solving.
|
|
15
|
+
- **Advanced** — Experienced. Architecture, optimization, system design.
|
|
16
|
+
|
|
17
|
+
## Teaching Modes
|
|
18
|
+
|
|
19
|
+
### 1. Concept Learning 📚
|
|
20
|
+
Explain → Show example → Have them practice → Apply to real scenario.
|
|
21
|
+
|
|
22
|
+
### 2. Code Review 🔍
|
|
23
|
+
When user shares code:
|
|
24
|
+
1. Acknowledge what's good first
|
|
25
|
+
2. Identify issues by severity (bugs > performance > style)
|
|
26
|
+
3. Explain WHY each suggestion matters
|
|
27
|
+
4. Show the improved version
|
|
28
|
+
5. Ask if they understand the reasoning
|
|
29
|
+
|
|
30
|
+
### 3. Debugging (Socratic) 🐛
|
|
31
|
+
Don't give the answer immediately. Guide discovery:
|
|
32
|
+
1. "What do you expect this to do?"
|
|
33
|
+
2. "What actually happens?"
|
|
34
|
+
3. "What have you tried?"
|
|
35
|
+
4. Narrow down: "What if you add a print here?"
|
|
36
|
+
5. If stuck after 3 exchanges, explain directly
|
|
37
|
+
|
|
38
|
+
### 4. Algorithm Practice 🧮
|
|
39
|
+
1. Present the problem clearly
|
|
40
|
+
2. Ask for their approach before coding
|
|
41
|
+
3. Discuss time/space complexity
|
|
42
|
+
4. Optimize together
|
|
43
|
+
5. Connect to real-world use cases
|
|
44
|
+
|
|
45
|
+
### 5. Project Mentoring 🏗️
|
|
46
|
+
1. Help define scope (MVP first!)
|
|
47
|
+
2. Break into milestones
|
|
48
|
+
3. Guide architecture decisions
|
|
49
|
+
4. Review progress incrementally
|
|
50
|
+
5. Encourage shipping over perfecting
|
|
51
|
+
|
|
52
|
+
## Key Principles
|
|
53
|
+
- **Never write the whole solution** — teach them to fish
|
|
54
|
+
- **Celebrate progress** — learning is hard, acknowledge effort
|
|
55
|
+
- **Use analogies** — connect new concepts to things they know
|
|
56
|
+
- **One concept at a time** — don't overwhelm
|
|
57
|
+
- **Real examples** — abstract theory doesn't stick; show practical use
|
|
58
|
+
|
|
59
|
+
## Common Beginner Pitfalls
|
|
60
|
+
- Copying code without understanding it
|
|
61
|
+
- Not reading error messages
|
|
62
|
+
- Trying to learn everything at once
|
|
63
|
+
- Not practicing enough (reading ≠ learning)
|
|
64
|
+
- Perfectionism before fundamentals
|
|
65
|
+
|
|
66
|
+
## Language-Specific Quick Starts
|
|
67
|
+
|
|
68
|
+
### Python
|
|
69
|
+
```python
|
|
70
|
+
# Variables, functions, loops — the essentials
|
|
71
|
+
def greet(name):
|
|
72
|
+
return f"Hello, {name}!"
|
|
73
|
+
|
|
74
|
+
for i in range(5):
|
|
75
|
+
print(greet(f"User {i}"))
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### JavaScript
|
|
79
|
+
```javascript
|
|
80
|
+
// Same concepts, different syntax
|
|
81
|
+
const greet = (name) => `Hello, ${name}!`;
|
|
82
|
+
for (let i = 0; i < 5; i++) {
|
|
83
|
+
console.log(greet(`User ${i}`));
|
|
84
|
+
}
|
|
85
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: csv-pipeline
|
|
3
|
+
description: Process, transform, analyze, and report on CSV and JSON data files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CSV Data Pipeline
|
|
7
|
+
|
|
8
|
+
Process tabular data (CSV, TSV, JSON, JSON Lines) using command-line tools and Python.
|
|
9
|
+
|
|
10
|
+
## Quick Operations
|
|
11
|
+
|
|
12
|
+
### Inspect
|
|
13
|
+
```bash
|
|
14
|
+
head -5 data.csv # Preview
|
|
15
|
+
tail -n +2 data.csv | wc -l # Row count
|
|
16
|
+
head -1 data.csv # Column headers
|
|
17
|
+
tail -n +2 data.csv | cut -d',' -f3 | sort -u | wc -l # Unique values in col 3
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Filter with awk
|
|
21
|
+
```bash
|
|
22
|
+
awk -F',' 'NR==1 || $3 > 100' data.csv > filtered.csv
|
|
23
|
+
awk -F',' 'NR==1 || $2 ~ /pattern/' data.csv > matched.csv
|
|
24
|
+
awk -F',' 'NR>1 {sum += $4} END {print sum}' data.csv
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Sort & Deduplicate
|
|
28
|
+
```bash
|
|
29
|
+
head -1 data.csv > sorted.csv && tail -n +2 data.csv | sort -t',' -k2 -n >> sorted.csv
|
|
30
|
+
awk -F',' '!seen[$2]++' data.csv > deduped.csv
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Format Conversion
|
|
34
|
+
```bash
|
|
35
|
+
# CSV → JSON (Python one-liner)
|
|
36
|
+
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(open('data.csv')))))"
|
|
37
|
+
|
|
38
|
+
# JSON → CSV
|
|
39
|
+
python3 -c "
|
|
40
|
+
import csv,json,sys
|
|
41
|
+
data=json.load(open('data.json'))
|
|
42
|
+
w=csv.DictWriter(sys.stdout,fieldnames=data[0].keys())
|
|
43
|
+
w.writeheader(); w.writerows(data)
|
|
44
|
+
" > data.csv
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Python Operations
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import csv, json
|
|
51
|
+
|
|
52
|
+
def read_csv(path, delimiter=','):
|
|
53
|
+
with open(path, newline='', encoding='utf-8') as f:
|
|
54
|
+
return list(csv.DictReader(f, delimiter=delimiter))
|
|
55
|
+
|
|
56
|
+
def write_csv(rows, path, delimiter=','):
|
|
57
|
+
if not rows: return
|
|
58
|
+
with open(path, 'w', newline='', encoding='utf-8') as f:
|
|
59
|
+
w = csv.DictWriter(f, fieldnames=rows[0].keys(), delimiter=delimiter)
|
|
60
|
+
w.writeheader(); w.writerows(rows)
|
|
61
|
+
|
|
62
|
+
def group_by(rows, key):
|
|
63
|
+
groups = {}
|
|
64
|
+
for r in rows:
|
|
65
|
+
groups.setdefault(r[key], []).append(r)
|
|
66
|
+
return groups
|
|
67
|
+
|
|
68
|
+
def aggregate(rows, group_key, agg_key, func='sum'):
|
|
69
|
+
groups = group_by(rows, group_key)
|
|
70
|
+
results = []
|
|
71
|
+
for k, v in groups.items():
|
|
72
|
+
vals = [float(r[agg_key]) for r in v if r[agg_key]]
|
|
73
|
+
agg = sum(vals) if func == 'sum' else sum(vals)/len(vals) if func == 'avg' else max(vals) if func == 'max' else min(vals)
|
|
74
|
+
results.append({group_key: k, f'{func}_{agg_key}': agg, 'count': len(v)})
|
|
75
|
+
return results
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Tips
|
|
79
|
+
- Always check encoding: `file -i data.csv`
|
|
80
|
+
- Handle quoted fields with commas inside them (use `csv` module, not `split`)
|
|
81
|
+
- For large files (>100MB), process line by line instead of loading into memory
|
|
82
|
+
- Validate data types before aggregating — one bad row can ruin calculations
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: developer
|
|
3
|
+
description: Write clean, maintainable code with debugging, testing, and architectural best practices.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Software Development
|
|
7
|
+
|
|
8
|
+
## Code Quality
|
|
9
|
+
- Readable code beats clever code — you'll read it 10x more than write it
|
|
10
|
+
- Functions do one thing — if you need "and" to describe it, split it
|
|
11
|
+
- Name things by what they do, not how
|
|
12
|
+
- Delete dead code — version control remembers
|
|
13
|
+
- Consistent style matters more than which style
|
|
14
|
+
|
|
15
|
+
## Debugging
|
|
16
|
+
- Read the error message completely — the answer is often there
|
|
17
|
+
- Reproduce before fixing — if you can't trigger it, you can't verify the fix
|
|
18
|
+
- Binary search: comment out half the code to find the problem
|
|
19
|
+
- Check the obvious first — typos, wrong file, stale cache, wrong env
|
|
20
|
+
- `console.log` liberally when stuck — assumptions are usually wrong
|
|
21
|
+
|
|
22
|
+
## Testing
|
|
23
|
+
- Test behavior, not implementation
|
|
24
|
+
- One assertion per test when possible
|
|
25
|
+
- Name tests as sentences: `should return empty array when no items match`
|
|
26
|
+
- Mock external dependencies, not internal logic
|
|
27
|
+
- Fast tests run often, slow tests get skipped
|
|
28
|
+
|
|
29
|
+
## Error Handling
|
|
30
|
+
- Fail fast and loud — silent failures create debugging nightmares
|
|
31
|
+
- Catch specific exceptions, not generic
|
|
32
|
+
- Log enough context to debug (error type alone isn't enough)
|
|
33
|
+
- User-facing errors should be helpful
|
|
34
|
+
- Don't catch exceptions you can't handle
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
- Start simple, add complexity when needed
|
|
38
|
+
- Separate concerns — UI, business logic, data access
|
|
39
|
+
- Dependencies flow inward — core logic shouldn't know about frameworks
|
|
40
|
+
- Configuration separate from code
|
|
41
|
+
- Document decisions (ADRs), not just code
|
|
42
|
+
|
|
43
|
+
## Performance
|
|
44
|
+
- Measure before optimizing — intuition is usually wrong
|
|
45
|
+
- Database queries are usually the bottleneck
|
|
46
|
+
- Caching solves many problems but creates invalidation headaches
|
|
47
|
+
- Make it work, make it right, make it fast (in that order)
|
|
48
|
+
|
|
49
|
+
## Dependencies
|
|
50
|
+
- Evaluate before adding — every dependency is code you don't control
|
|
51
|
+
- Pin versions — "latest" breaks builds
|
|
52
|
+
- Fewer dependencies is better — each adds supply chain risk
|
|
53
|
+
|
|
54
|
+
## Working in Existing Codebases
|
|
55
|
+
- Match existing patterns — consistency beats preference
|
|
56
|
+
- Understand before changing — read tests, check git history
|
|
57
|
+
- Don't refactor while fixing bugs — separate commits
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: image
|
|
3
|
+
description: Process, optimize, and manage images with format selection, compression, and platform specs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Image Processing
|
|
7
|
+
|
|
8
|
+
## Format Selection
|
|
9
|
+
|
|
10
|
+
| Content | Format | Reason |
|
|
11
|
+
|---------|--------|--------|
|
|
12
|
+
| Photos | WebP (JPEG fallback) | 25-35% smaller |
|
|
13
|
+
| Icons, logos | SVG | Scalable, tiny |
|
|
14
|
+
| Screenshots | PNG | Sharp edges preserved |
|
|
15
|
+
| Transparency + photo | WebP or PNG-24 | Alpha support |
|
|
16
|
+
| Animation | WebP or MP4 | NOT GIF (5-10x larger) |
|
|
17
|
+
|
|
18
|
+
## File Size Budgets
|
|
19
|
+
- Hero images: MAX 200KB (ideally <150KB)
|
|
20
|
+
- Content images: MAX 100KB
|
|
21
|
+
- Thumbnails: MAX 30KB
|
|
22
|
+
- Icons (raster): MAX 5KB
|
|
23
|
+
|
|
24
|
+
## Quality Levels
|
|
25
|
+
|
|
26
|
+
| Format | Hero | General | Thumbnails |
|
|
27
|
+
|--------|------|---------|------------|
|
|
28
|
+
| JPEG | 80-85% | 70-75% | 60-65% |
|
|
29
|
+
| WebP | 80-82% | 72-78% | 60-70% |
|
|
30
|
+
|
|
31
|
+
## Common Operations
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Resize (ImageMagick)
|
|
35
|
+
convert input.jpg -resize 800x600 output.jpg
|
|
36
|
+
|
|
37
|
+
# Convert format
|
|
38
|
+
convert input.png -quality 80 output.webp
|
|
39
|
+
|
|
40
|
+
# Batch resize
|
|
41
|
+
for f in *.jpg; do convert "$f" -resize 1200x -quality 80 "optimized/$f"; done
|
|
42
|
+
|
|
43
|
+
# Strip metadata (reduce size)
|
|
44
|
+
convert input.jpg -strip output.jpg
|
|
45
|
+
|
|
46
|
+
# Create thumbnail
|
|
47
|
+
convert input.jpg -thumbnail 200x200^ -gravity center -extent 200x200 thumb.jpg
|
|
48
|
+
|
|
49
|
+
# Get image info
|
|
50
|
+
identify -verbose image.jpg | head -20
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Retina/HiDPI
|
|
54
|
+
- 2x required for standard Retina
|
|
55
|
+
- 400px displayed needs 800px source
|
|
56
|
+
- 3x only for iPhone Plus/Max
|
|
57
|
+
|
|
58
|
+
## Social Media Dimensions
|
|
59
|
+
- **Instagram Post:** 1080×1080
|
|
60
|
+
- **Instagram Story:** 1080×1920
|
|
61
|
+
- **Twitter/X Post:** 1200×675
|
|
62
|
+
- **LinkedIn Post:** 1200×627
|
|
63
|
+
- **YouTube Thumbnail:** 1280×720
|
|
64
|
+
- **Facebook Post:** 1200×630
|
|
65
|
+
|
|
66
|
+
## Checklist Before Processing
|
|
67
|
+
- [ ] Target format determined
|
|
68
|
+
- [ ] Color profile: sRGB for web
|
|
69
|
+
- [ ] Dimensions/aspect ratio defined
|
|
70
|
+
- [ ] Compression quality set
|
|
71
|
+
- [ ] Metadata stripped for web use
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: json
|
|
3
|
+
description: Work with JSON data structures, APIs, and serialization effectively.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JSON
|
|
7
|
+
|
|
8
|
+
## Schema & Validation
|
|
9
|
+
- Validate against JSON Schema before processing untrusted input
|
|
10
|
+
- Use `additionalProperties: false` to reject unknown fields in strict contexts
|
|
11
|
+
|
|
12
|
+
## Naming Conventions
|
|
13
|
+
- `camelCase` for JS ecosystems, `snake_case` for Python/Ruby
|
|
14
|
+
- Plural for collections: `"users": []` not `"user": []`
|
|
15
|
+
|
|
16
|
+
## Null Handling
|
|
17
|
+
- Distinguish "field is null" from "field is absent"
|
|
18
|
+
- Omit optional fields rather than sending `null`
|
|
19
|
+
|
|
20
|
+
## Dates & Times
|
|
21
|
+
- Always ISO 8601: `"2024-01-15T14:30:00Z"`
|
|
22
|
+
- Include timezone or use UTC with `Z` suffix
|
|
23
|
+
|
|
24
|
+
## Numbers & IDs
|
|
25
|
+
- Large IDs as strings: `"id": "9007199254740993"` (JS loses precision above 2^53)
|
|
26
|
+
- Money as string or integer cents — never float
|
|
27
|
+
|
|
28
|
+
## Structure
|
|
29
|
+
- Keep nesting shallow — 3 levels max
|
|
30
|
+
- Consistent API envelope: `{"data": ..., "meta": ..., "errors": ...}`
|
|
31
|
+
- Paginate large arrays — never return unbounded lists
|
|
32
|
+
|
|
33
|
+
## API Response Patterns
|
|
34
|
+
- Errors as objects: `{"code": "INVALID_EMAIL", "message": "...", "field": "email"}`
|
|
35
|
+
- Include request ID for debugging
|
|
36
|
+
- Return created/updated resource in response
|
|
37
|
+
|
|
38
|
+
## CLI Operations
|
|
39
|
+
```bash
|
|
40
|
+
# Pretty print
|
|
41
|
+
cat data.json | python3 -m json.tool
|
|
42
|
+
|
|
43
|
+
# Extract field with jq
|
|
44
|
+
cat data.json | jq '.users[0].name'
|
|
45
|
+
|
|
46
|
+
# Filter array
|
|
47
|
+
cat data.json | jq '.items[] | select(.price > 10)'
|
|
48
|
+
|
|
49
|
+
# Transform
|
|
50
|
+
cat data.json | jq '{name: .first, email: .contact.email}'
|
|
51
|
+
|
|
52
|
+
# Validate JSON
|
|
53
|
+
python3 -c "import json; json.load(open('data.json')); print('Valid')"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Parsing Safety
|
|
57
|
+
- `__proto__` key can pollute prototypes — sanitize or use `Object.create(null)`
|
|
58
|
+
- Parse in try/catch — malformed JSON from external sources is common
|
|
59
|
+
- Strip BOM (`\uFEFF`) from file input
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: productivity
|
|
3
|
+
description: "Plan, focus, and complete work with energy management, time blocking, and practical boundaries."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Productivity
|
|
7
|
+
|
|
8
|
+
Help users plan, focus, and complete work effectively.
|
|
9
|
+
|
|
10
|
+
## Energy Management (Not Just Time)
|
|
11
|
+
|
|
12
|
+
People have ~4 hours of peak cognitive work per day. Help them use it wisely.
|
|
13
|
+
|
|
14
|
+
**Energy levels:**
|
|
15
|
+
- 🟢 **Peak** — Deep work, complex problems, creative tasks
|
|
16
|
+
- 🟡 **Medium** — Meetings, communication, routine coding
|
|
17
|
+
- 🔴 **Low** — Admin, email, filing, simple tasks
|
|
18
|
+
|
|
19
|
+
**Ask:** "When do you feel most focused?" then schedule their hardest work there.
|
|
20
|
+
|
|
21
|
+
## Time Blocking
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
09:00–11:00 🟢 Deep Work (no meetings, no Slack)
|
|
25
|
+
11:00–12:00 🟡 Communication (email, messages, reviews)
|
|
26
|
+
12:00–13:00 🔴 Lunch + low-energy tasks
|
|
27
|
+
13:00–14:30 🟡 Collaborative work / meetings
|
|
28
|
+
14:30–16:00 🟢 Second wind — focused work
|
|
29
|
+
16:00–17:00 🔴 Planning tomorrow, admin, wrap-up
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Task Initiation (Getting Started)
|
|
33
|
+
|
|
34
|
+
The hardest part is starting. Use these techniques:
|
|
35
|
+
1. **2-Minute Rule** — If it takes <2 min, do it now
|
|
36
|
+
2. **5-Minute Commit** — "Just work on it for 5 minutes" (momentum kicks in)
|
|
37
|
+
3. **Next Physical Action** — Don't write "work on project", write "open file X and read section Y"
|
|
38
|
+
4. **Pomodoro** — 25 min work + 5 min break. 4 rounds then 15-30 min break.
|
|
39
|
+
|
|
40
|
+
## "Good Enough" Thresholds
|
|
41
|
+
|
|
42
|
+
Help users avoid perfectionism:
|
|
43
|
+
- **First draft:** 60% quality is fine — just get it down
|
|
44
|
+
- **Internal doc:** 80% is enough — don't polish what 3 people will read
|
|
45
|
+
- **Client-facing:** 95% — worth the extra effort
|
|
46
|
+
- **Published/permanent:** 98% — justify the remaining 2%
|
|
47
|
+
|
|
48
|
+
## When Users Are Stuck
|
|
49
|
+
|
|
50
|
+
1. Ask what's blocking them (unclear task? too big? not motivated?)
|
|
51
|
+
2. Break it into the smallest possible next step
|
|
52
|
+
3. Offer to work on it together (rubber duck debugging for productivity)
|
|
53
|
+
4. Suggest a context switch if they've been stuck >30 min
|
|
54
|
+
|
|
55
|
+
## Planning a Day
|
|
56
|
+
|
|
57
|
+
When asked to help plan a day:
|
|
58
|
+
1. List everything they need to do
|
|
59
|
+
2. Estimate time for each (add 50% buffer)
|
|
60
|
+
3. Match tasks to energy levels
|
|
61
|
+
4. Schedule the hardest 1-2 things during peak energy
|
|
62
|
+
5. Leave 20% of the day unscheduled (for surprises)
|
|
63
|
+
|
|
64
|
+
## Common Traps to Avoid
|
|
65
|
+
- ❌ "Organize your task list" as a procrastination tool
|
|
66
|
+
- ❌ Suggesting complex systems (keep it simple)
|
|
67
|
+
- ❌ Guilt-tripping about productivity
|
|
68
|
+
- ❌ Assuming everyone works the same way
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quick-reminders
|
|
3
|
+
description: "One-shot reminders (<48h) via cron or background sleep process."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quick Reminders
|
|
7
|
+
|
|
8
|
+
Set one-shot reminders for up to 48 hours ahead. For longer timelines, use a calendar.
|
|
9
|
+
|
|
10
|
+
## Setting a Reminder
|
|
11
|
+
|
|
12
|
+
Use `at` command (if available) or background sleep:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Using 'at' (preferred)
|
|
16
|
+
echo 'openclaw message send --target CHAT_ID --message "Hey, time for your meeting!"' | at now + 30 minutes
|
|
17
|
+
|
|
18
|
+
# Using nohup + sleep (fallback)
|
|
19
|
+
nohup bash -c 'sleep 1800 && openclaw message send --target CHAT_ID --message "Hey, time for your meeting!"' &>/dev/null &
|
|
20
|
+
echo $! > /tmp/reminder-$(date +%s).pid
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Using OpenClaw Cron
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Remind at specific time today
|
|
27
|
+
openclaw cron add --schedule "30 14 * * *" --once --command 'openclaw message send --target CHAT_ID --message "Meeting in 30 min!"'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Composing Reminder Messages
|
|
31
|
+
|
|
32
|
+
Sound like a friend texting, not a system notification:
|
|
33
|
+
|
|
34
|
+
**Don't:**
|
|
35
|
+
- "Reminder: call John"
|
|
36
|
+
- "This is your reminder to..."
|
|
37
|
+
|
|
38
|
+
**Do:**
|
|
39
|
+
- "Hey, you wanted to call John"
|
|
40
|
+
- "Time to call John back 📞"
|
|
41
|
+
- "So... dishwasher time 🍽️"
|
|
42
|
+
|
|
43
|
+
**Guidelines:**
|
|
44
|
+
- Casual openers: "Hey", "So...", "Heads up"
|
|
45
|
+
- Light humor when it fits
|
|
46
|
+
- Keep it short — one line
|
|
47
|
+
- Must make sense out of context (user reads it hours later)
|
|
48
|
+
|
|
49
|
+
## Listing Active Reminders
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Check at queue
|
|
53
|
+
atq
|
|
54
|
+
|
|
55
|
+
# Check background sleep processes
|
|
56
|
+
ps aux | grep "sleep.*openclaw message" | grep -v grep
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Canceling
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Cancel at job
|
|
63
|
+
atrm JOB_ID
|
|
64
|
+
|
|
65
|
+
# Kill background process
|
|
66
|
+
kill $(cat /tmp/reminder-*.pid)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Guardrail
|
|
70
|
+
If reminder is **2+ days out**, suggest a calendar event instead — sleep processes and `at` jobs don't survive reboots reliably.
|