@sulala/agent-os 0.1.5 → 0.1.7
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/data/agents/briefing_agent.json +12 -0
- package/data/agents/dev_agent.json +10 -0
- package/data/agents/manager_agent.json +11 -0
- package/data/agents/media_agent.json +10 -0
- package/data/agents/personal_agent.json +11 -0
- package/data/agents/research_agent.json +10 -0
- package/data/agents/social_media_agent.json +10 -0
- package/data/agents/writer_agent.json +10 -0
- package/data/skills/bluesky/SKILL.md +63 -0
- package/data/skills/bluesky/config.schema.json +17 -0
- package/data/skills/bluesky/scripts/post.sh +48 -0
- package/data/skills/bluesky/scripts/timeline.sh +37 -0
- package/data/skills/date/SKILL.md +53 -0
- package/data/skills/fetch/SKILL.md +42 -0
- package/data/skills/file-search/SKILL.md +122 -0
- package/data/skills/file-stats/SKILL.md +68 -0
- package/data/skills/git/SKILL.md +60 -0
- package/data/skills/gmail/SKILL.md +55 -0
- package/data/skills/gmail/references/send-email.md +54 -0
- package/data/skills/gmail/scripts/send_email.py +94 -0
- package/data/skills/hash/SKILL.md +56 -0
- package/data/skills/jq/SKILL.md +66 -0
- package/data/skills/markdown-to-html/SKILL.md +47 -0
- package/data/skills/memory/SKILL.md +64 -0
- package/data/skills/qr-code/SKILL.md +65 -0
- package/data/skills/rss/SKILL.md +40 -0
- package/data/skills/sulala-portal/SKILL.md +92 -0
- package/data/skills/translate/SKILL.md +52 -0
- package/data/skills/weather/SKILL.md +59 -0
- package/data/skills/web-search/SKILL.md +55 -0
- package/data/skills/web-search/config.schema.json +12 -0
- package/data/skills/web-search/scripts/search.sh +21 -0
- package/data/skills/webhook/SKILL.md +101 -0
- package/data/skills/webhook/config.schema.json +11 -0
- package/data/skills/webhook/scripts/post.sh +13 -0
- package/data/skills/youtube/SKILL.md +91 -0
- package/data/skills/youtube/config.schema.json +11 -0
- package/data/skills/youtube/package.json +8 -0
- package/data/skills/youtube/references/youtube-upload.md +65 -0
- package/data/skills/youtube/requirements.txt +3 -0
- package/data/skills/youtube/scripts/youtube_upload.js +200 -0
- package/data/skills/youtube/scripts/youtube_upload.py +125 -0
- package/data/templates/BOOT.md +11 -0
- package/data/templates/BOOTSTRAP.md +62 -0
- package/data/templates/HEARTBEAT.md +12 -0
- package/data/templates/IDENTITY.dev.md +62 -0
- package/data/templates/IDENTITY.md +60 -0
- package/data/templates/SYSTEM.dev.md +82 -0
- package/data/templates/SYSTEM.md +65 -0
- package/data/templates/TOOLS.dev.md +24 -0
- package/data/templates/TOOLS.md +47 -0
- package/data/templates/USER.dev.md +18 -0
- package/data/templates/USER.md +23 -0
- package/dist/cli.js +32 -14
- package/dist/index.js +24 -6
- package/package.json +3 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "briefing_agent",
|
|
3
|
+
"name": "Daily Briefing",
|
|
4
|
+
"description": "Morning-style brief: weather and RSS feeds. Use for 'what's the weather' and 'what's new' from configured feeds. Optionally schedule (e.g. 8:00) for a daily brief.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "weather", "rss"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
},
|
|
10
|
+
"schedule": "0 8 * * *",
|
|
11
|
+
"schedule_input": "Give me a short morning brief: weather for my location and top items from my RSS feeds."
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "dev_agent",
|
|
3
|
+
"name": "Dev Assistant",
|
|
4
|
+
"description": "Git status, search the codebase, parse JSON (jq), and fetch APIs. Use when the user asks about git, finding code, or working with JSON/APIs. Operates in the agent workspace.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "git", "file-search", "jq", "fetch"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "manager_agent",
|
|
3
|
+
"name": "Manager Assistant",
|
|
4
|
+
"description": "Coordinates other agents. You don't have social media, email, or search skills yourself—when the user asks to post to Bluesky/social, send an email, search the web, or do something another agent can do, use the run_agent tool to delegate to the right agent (social_media_agent, writer_agent, research_agent, etc.) and then summarize the result for the user.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory"],
|
|
7
|
+
"tools": ["run_agent"],
|
|
8
|
+
"limits": {
|
|
9
|
+
"max_turns": 15
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "media_agent",
|
|
3
|
+
"name": "Media Assistant",
|
|
4
|
+
"description": "Upload to YouTube, generate QR codes, and send webhooks (e.g. Slack, Discord). Configure YouTube credentials and webhook URLs in the respective skills.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "youtube", "qr-code", "webhook"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "personal_agent",
|
|
3
|
+
"name": "Personal Assistant",
|
|
4
|
+
"description": "Personal assistant with long-term memory and tools. Use the memory skill to store explicit user facts (e.g. 'remember that I live in X') and to recall them when the user asks what you remember, where they live, or what they like. Can check weather and search the web.",
|
|
5
|
+
"personality": "Friendly, supportive, and calm. Respond with empathy and a little warmth. When the user shares something personal or asks for help, be encouraging.",
|
|
6
|
+
"model": "gpt-4o-mini",
|
|
7
|
+
"skills": ["memory", "weather", "web-search"],
|
|
8
|
+
"limits": {
|
|
9
|
+
"max_turns": 20
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "research_agent",
|
|
3
|
+
"name": "Research Assistant",
|
|
4
|
+
"description": "Search the web, fetch and summarize URLs, and follow RSS feeds. Use when the user asks to search for something, read a page, or get updates from a feed. Configure web-search API key in the skill if required.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "web-search", "fetch", "rss"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "social_media_agent",
|
|
3
|
+
"name": "Social Media Assistant",
|
|
4
|
+
"description": "Post to social networks (e.g. Bluesky), read your timeline, and reply to posts. Configure credentials in the skill (Agents → Edit → Skills, or Settings). Currently supports Bluesky.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "bluesky"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "writer_agent",
|
|
3
|
+
"name": "Writer Assistant",
|
|
4
|
+
"description": "Draft and send email (Gmail) and translate text. Use when the user wants to send an email or translate content. Gmail requires connection via Portal or skill config.",
|
|
5
|
+
"model": "gpt-4o-mini",
|
|
6
|
+
"skills": ["memory", "gmail", "translate"],
|
|
7
|
+
"limits": {
|
|
8
|
+
"max_turns": 15
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bluesky
|
|
3
|
+
description: Post to Bluesky and read your home timeline (AT Protocol). Use when the user says "post this to Bluesky", "what's on my Bluesky feed", "reply to this post", "post to Bluesky", "my Bluesky timeline".
|
|
4
|
+
credentials:
|
|
5
|
+
- BLUESKY_HANDLE
|
|
6
|
+
- BLUESKY_APP_PASSWORD
|
|
7
|
+
metadata:
|
|
8
|
+
clawdbot:
|
|
9
|
+
emoji: "🦋"
|
|
10
|
+
requires:
|
|
11
|
+
bins:
|
|
12
|
+
- curl
|
|
13
|
+
- jq
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Bluesky
|
|
17
|
+
|
|
18
|
+
Post and read your Bluesky feed via the AT Protocol. Use the **exec** tool with **skill_id: "bluesky"** so `BLUESKY_HANDLE` and `BLUESKY_APP_PASSWORD` are injected from skill config.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
1. Add the **bluesky** skill to the agent.
|
|
23
|
+
2. Set **Bluesky handle** and **Bluesky app password** in Skills → bluesky → Setup (see **Setup** below).
|
|
24
|
+
3. **jq** must be installed (`brew install jq` or `apt install jq`).
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
1. In Bluesky: **Settings** (gear) → **App passwords** → **Add App Password**. Name it (e.g. "Agent OS"), copy the password once (it won’t be shown again).
|
|
29
|
+
2. Your handle is your Bluesky username (e.g. `yourname.bsky.social`).
|
|
30
|
+
3. In the dashboard: **Skills** → **bluesky** → ⋮ → **Setup** → set **Bluesky handle** and **Bluesky app password** → Save.
|
|
31
|
+
|
|
32
|
+
Never use your main account password; use only an app password.
|
|
33
|
+
|
|
34
|
+
### If you get "Invalid identifier or password"
|
|
35
|
+
|
|
36
|
+
- **Handle:** Use your full handle exactly as shown in Bluesky (e.g. `yourname.bsky.social`). Do not include `@`. The script strips a leading `@` and trims spaces automatically.
|
|
37
|
+
- **App password:** You must create one in Bluesky **Settings → App passwords → Add App Password**. Copy it when shown (it’s not shown again). If you lost it, create a new app password and update the skill config.
|
|
38
|
+
- **No account password:** The app password is a separate, long token (e.g. `xxxx-xxxx-xxxx-xxxx`); do not use your normal Bluesky login password.
|
|
39
|
+
|
|
40
|
+
## Post a new post
|
|
41
|
+
|
|
42
|
+
- **skill_id:** `bluesky`
|
|
43
|
+
- **command:** `./scripts/post.sh "Your post text here"`
|
|
44
|
+
|
|
45
|
+
Post text is the first argument. Max 300 graphemes (Bluesky limit). The script creates a session, then creates the record; the response is the created post URI.
|
|
46
|
+
|
|
47
|
+
## Get your home timeline
|
|
48
|
+
|
|
49
|
+
- **skill_id:** `bluesky`
|
|
50
|
+
- **command:** `./scripts/timeline.sh`
|
|
51
|
+
- Optional limit: `./scripts/timeline.sh 30` (default 20)
|
|
52
|
+
|
|
53
|
+
Returns JSON: `feed[]` with `post` (author, record.text, etc.). Summarize or list the most recent posts for the user.
|
|
54
|
+
|
|
55
|
+
## Reply to a post (future)
|
|
56
|
+
|
|
57
|
+
Replies require a `reply` object (parent + root) in the record. The current script only supports top-level posts. For replies, extend the record or add a `reply.sh` script that accepts parent URI and text.
|
|
58
|
+
|
|
59
|
+
## Tips
|
|
60
|
+
|
|
61
|
+
- Quote the post text in the command so spaces and punctuation are preserved: `./scripts/post.sh "Hello from the agent!"`
|
|
62
|
+
- Timeline entries have `post.author.displayName`, `post.record.text`, `post.uri`. Use these to summarize the feed.
|
|
63
|
+
- Optional env **BLUESKY_PDS** overrides the PDS URL (default `https://bsky.social`); only set if you use a custom PDS.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "object",
|
|
3
|
+
"properties": {
|
|
4
|
+
"BLUESKY_HANDLE": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"title": "Bluesky handle",
|
|
7
|
+
"description": "Your Bluesky handle (e.g. yourname.bsky.social). Used with the app password to create a session."
|
|
8
|
+
},
|
|
9
|
+
"BLUESKY_APP_PASSWORD": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"format": "password",
|
|
12
|
+
"title": "Bluesky app password",
|
|
13
|
+
"description": "App password from Bluesky Settings → App passwords. Do not use your main account password."
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": ["BLUESKY_HANDLE", "BLUESKY_APP_PASSWORD"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Post to Bluesky via AT Protocol. BLUESKY_HANDLE and BLUESKY_APP_PASSWORD from skill config.
|
|
3
|
+
# Usage: post.sh "your post text here"
|
|
4
|
+
set -e
|
|
5
|
+
if [ -z "$BLUESKY_HANDLE" ] || [ -z "$BLUESKY_APP_PASSWORD" ]; then
|
|
6
|
+
echo "BLUESKY_HANDLE and BLUESKY_APP_PASSWORD must be set. Configure in Skills → bluesky → Setup." >&2
|
|
7
|
+
exit 1
|
|
8
|
+
fi
|
|
9
|
+
# Trim and normalize: handle without leading @, no leading/trailing whitespace
|
|
10
|
+
BLUESKY_HANDLE=$(echo "$BLUESKY_HANDLE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/^@//')
|
|
11
|
+
BLUESKY_APP_PASSWORD=$(echo "$BLUESKY_APP_PASSWORD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
12
|
+
if [ -z "$BLUESKY_HANDLE" ] || [ -z "$BLUESKY_APP_PASSWORD" ]; then
|
|
13
|
+
echo "BLUESKY_HANDLE and BLUESKY_APP_PASSWORD must be non-empty after trimming." >&2
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
if [ -z "$1" ]; then
|
|
17
|
+
echo "Usage: post.sh \"post text\"" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
21
|
+
echo "jq is required for the Bluesky skill." >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
PDS="${BLUESKY_PDS:-https://bsky.social}"
|
|
25
|
+
# Create session (use jq to build JSON so special chars in password are safe)
|
|
26
|
+
SESSION_BODY=$(jq -n --arg id "$BLUESKY_HANDLE" --arg pw "$BLUESKY_APP_PASSWORD" '{identifier:$id,password:$pw}')
|
|
27
|
+
SESSION=$(curl -sS -X POST "$PDS/xrpc/com.atproto.server.createSession" \
|
|
28
|
+
-H "Content-Type: application/json" \
|
|
29
|
+
-d "$SESSION_BODY")
|
|
30
|
+
if ! echo "$SESSION" | jq -e '.accessJwt' >/dev/null 2>&1; then
|
|
31
|
+
echo "Session failed: $SESSION" >&2
|
|
32
|
+
echo "Check: (1) Handle is your full handle, e.g. yourname.bsky.social (no @). (2) Use an App password from Bluesky Settings → App passwords, not your account password." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
ACCESS_JWT=$(echo "$SESSION" | jq -r '.accessJwt')
|
|
36
|
+
DID=$(echo "$SESSION" | jq -r '.did')
|
|
37
|
+
# createdAt in ISO 8601
|
|
38
|
+
CREATED_AT=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
|
|
39
|
+
# Escape post text for JSON
|
|
40
|
+
TEXT=$(printf '%s' "$1" | jq -Rs .)
|
|
41
|
+
RECORD=$(jq -n --arg text "$1" --arg createdAt "$CREATED_AT" \
|
|
42
|
+
'{ ("$type"): "app.bsky.feed.post", text: $text, createdAt: $createdAt }')
|
|
43
|
+
BODY=$(jq -n --arg repo "$DID" --argjson record "$RECORD" \
|
|
44
|
+
'{ repo: $repo, collection: "app.bsky.feed.post", record: $record }')
|
|
45
|
+
curl -sS -X POST "$PDS/xrpc/com.atproto.repo.createRecord" \
|
|
46
|
+
-H "Authorization: Bearer $ACCESS_JWT" \
|
|
47
|
+
-H "Content-Type: application/json" \
|
|
48
|
+
-d "$BODY"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Get Bluesky home timeline. BLUESKY_HANDLE and BLUESKY_APP_PASSWORD from skill config (injected as env by exec).
|
|
3
|
+
# Usage: timeline.sh [limit]
|
|
4
|
+
# Optional: limit (default 20) - number of posts to return.
|
|
5
|
+
set -e
|
|
6
|
+
if [ -z "$BLUESKY_HANDLE" ] || [ -z "$BLUESKY_APP_PASSWORD" ]; then
|
|
7
|
+
echo "BLUESKY_HANDLE and BLUESKY_APP_PASSWORD must be set. Configure in Skills → bluesky → Setup." >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
# Trim and normalize: handle without leading @
|
|
11
|
+
BLUESKY_HANDLE=$(echo "$BLUESKY_HANDLE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/^@//')
|
|
12
|
+
BLUESKY_APP_PASSWORD=$(echo "$BLUESKY_APP_PASSWORD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
13
|
+
if [ -z "$BLUESKY_HANDLE" ] || [ -z "$BLUESKY_APP_PASSWORD" ]; then
|
|
14
|
+
echo "BLUESKY_HANDLE and BLUESKY_APP_PASSWORD must be non-empty after trimming." >&2
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
18
|
+
echo "jq is required. Install with: brew install jq (macOS) or apt install jq (Linux)." >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
LIMIT="${1:-20}"
|
|
23
|
+
PDS="${BLUESKY_PDS:-https://bsky.social}"
|
|
24
|
+
SESSION_BODY=$(jq -n --arg id "$BLUESKY_HANDLE" --arg pw "$BLUESKY_APP_PASSWORD" '{identifier:$id,password:$pw}')
|
|
25
|
+
SESSION=$(curl -sS -X POST "$PDS/xrpc/com.atproto.server.createSession" \
|
|
26
|
+
-H "Content-Type: application/json" \
|
|
27
|
+
-d "$SESSION_BODY")
|
|
28
|
+
if ! echo "$SESSION" | jq -e '.accessJwt' >/dev/null 2>&1; then
|
|
29
|
+
echo "Session failed: $SESSION" >&2
|
|
30
|
+
echo "Check: (1) Handle is your full handle, e.g. yourname.bsky.social (no @). (2) Use an App password from Bluesky Settings → App passwords, not your account password." >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
ACCESS_JWT=$(echo "$SESSION" | jq -r '.accessJwt')
|
|
34
|
+
|
|
35
|
+
curl -sS -G "$PDS/xrpc/app.bsky.feed.getTimeline" \
|
|
36
|
+
--data-urlencode "limit=$LIMIT" \
|
|
37
|
+
-H "Authorization: Bearer $ACCESS_JWT"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: date
|
|
3
|
+
description: Get current date and time (optionally in a timezone). Use when the user asks "what time is it", "current date", "time in Tokyo", "what's the date today".
|
|
4
|
+
metadata:
|
|
5
|
+
clawdbot:
|
|
6
|
+
emoji: "🕐"
|
|
7
|
+
requires:
|
|
8
|
+
bins:
|
|
9
|
+
- date
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Date and time
|
|
13
|
+
|
|
14
|
+
Use the **exec** tool to run `date` or fetch time from an API. No script required.
|
|
15
|
+
|
|
16
|
+
## Local date and time
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
date
|
|
20
|
+
# e.g. Sat Mar 15 10:30:00 GMT 2025
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Custom format (ISO-like):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
date +"%Y-%m-%d %H:%M:%S %Z"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Time in another timezone
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
TZ=Europe/Paris date
|
|
33
|
+
TZ=America/New_York date
|
|
34
|
+
TZ=Asia/Tokyo date +"%H:%M %Z"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Common TZ values: `Europe/London`, `Europe/Paris`, `America/Los_Angeles`, `America/New_York`, `Asia/Tokyo`, `UTC`.
|
|
38
|
+
|
|
39
|
+
## Unix timestamp
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
date +%s
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## World time (fallback via curl)
|
|
46
|
+
|
|
47
|
+
If the user asks for "time in City" and you need a source:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -s "https://worldtimeapi.org/api/timezone/Europe/Paris" | head -c 500
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Returns JSON with `datetime`, `timezone`, etc. Other zones: `America/New_York`, `Asia/Tokyo`. Docs: https://worldtimeapi.org/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fetch
|
|
3
|
+
description: Fetch content from a URL (GET). Use when the user says "fetch this URL", "read that page", "get content from …", or "what's at this link".
|
|
4
|
+
metadata:
|
|
5
|
+
clawdbot:
|
|
6
|
+
emoji: "🔗"
|
|
7
|
+
requires:
|
|
8
|
+
bins:
|
|
9
|
+
- curl
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Fetch URL
|
|
13
|
+
|
|
14
|
+
Fetch the body of a URL via **curl**. Use the **exec** tool with the commands below. Only use **http** or **https** URLs.
|
|
15
|
+
|
|
16
|
+
## GET body (plain)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
curl -sL "https://example.com/page"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `-s` silent (no progress)
|
|
23
|
+
- `-L` follow redirects
|
|
24
|
+
|
|
25
|
+
## With a user-agent (some sites need it)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
curl -sL -A "Mozilla/5.0 (compatible; Agent/1.0)" "https://example.com/page"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Limit size (avoid huge responses)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl -sL --max-size 1048576 "https://example.com/page"
|
|
35
|
+
# 1 MiB max
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Tips
|
|
39
|
+
|
|
40
|
+
- URL-encode the URL or quote it in the shell.
|
|
41
|
+
- For JSON APIs, pipe to `head -c 50000` or process with `jq` if needed.
|
|
42
|
+
- Do not POST or send secrets in the URL; use this for read-only GET.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: file-search
|
|
3
|
+
description: Search for files and text in the workspace or the user's computer (grep, find). Use when the user asks "find files containing X", "list all .md files", "search my computer", "find file named Y on my machine", "search in my Downloads".
|
|
4
|
+
metadata:
|
|
5
|
+
clawdbot:
|
|
6
|
+
emoji: "🔍"
|
|
7
|
+
requires:
|
|
8
|
+
bins:
|
|
9
|
+
- grep
|
|
10
|
+
- find
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# File search (workspace)
|
|
14
|
+
|
|
15
|
+
Use **grep** and **find** via the **exec** tool to search inside the **workspace**. Commands run in the agent workspace; restrict paths to the workspace (no `../` escape).
|
|
16
|
+
|
|
17
|
+
## Find files by name or pattern
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
find . -name "*.md"
|
|
21
|
+
find . -name "*.json" -type f
|
|
22
|
+
find . -iname "*config*"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Limit depth (e.g. current dir + one level):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
find . -maxdepth 2 -name "*.ts"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Search file contents (grep)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
grep -r "search term" .
|
|
35
|
+
grep -rn "function foo" .
|
|
36
|
+
# -n = line numbers
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Case-insensitive:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
grep -ri "TODO" .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Only list matching files (no line content):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
grep -rl "import React" .
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Combine find + grep
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
find . -name "*.py" -exec grep -l "def main" {} \;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Search the user's computer (home directory)
|
|
58
|
+
|
|
59
|
+
When the user says "on my computer", "in my computer", "on my machine", "in my home", "find file named X" (and not in workspace), or "in my Downloads", search their **home directory** using `~` or `$HOME` so it works on **macOS** (/Users/username) and **Linux** (/home/username):
|
|
60
|
+
|
|
61
|
+
**Find a file by exact name:**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
find ~ -name "saiko_cv" -type f 2>/dev/null
|
|
65
|
+
find ~ -name "gggg.png" -type f 2>/dev/null
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Find in a specific folder (e.g. Downloads, Desktop):**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
find ~/Downloads -name "*.png" -type f
|
|
72
|
+
find ~/Desktop -name "saiko_cv*" -type f 2>/dev/null
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Find by name pattern (partial match):**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
find ~ -iname "*saiko_cv*" -type f 2>/dev/null
|
|
79
|
+
find ~ -iname "*gggg*" -type f 2>/dev/null
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `-iname` for case-insensitive match. Use `2>/dev/null` to hide permission errors.
|
|
83
|
+
|
|
84
|
+
## Search entire system or a specific path
|
|
85
|
+
|
|
86
|
+
When the user asks for "whole system", "entire disk", or an explicit path:
|
|
87
|
+
|
|
88
|
+
**Portable (home):** use `~` or `$HOME` (works on macOS and Linux).
|
|
89
|
+
|
|
90
|
+
**Linux:** `/home` or `/home/$(whoami)`.
|
|
91
|
+
|
|
92
|
+
**macOS:** `/Users` or `~` (e.g. `/Users/saiko`).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
find ~ -name "*.md" -type f 2>/dev/null
|
|
96
|
+
find /home -name "*.conf" -type f 2>/dev/null
|
|
97
|
+
find / -name "*.conf" -type f 2>/dev/null
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Grep in a path:**
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
grep -r "pattern" ~ 2>/dev/null
|
|
104
|
+
grep -rln "TODO" ~/projects 2>/dev/null
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Limit depth for large trees:**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
find ~ -maxdepth 5 -name "*.json" -type f
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Tips:**
|
|
114
|
+
|
|
115
|
+
- **"My computer" or "find file X"** → use `find ~ -name "X"` (or `find ~/Downloads -name "X"` if they say "in Downloads"). Do not search only the workspace.
|
|
116
|
+
- Prefer `~` or `$HOME` so the same command works on macOS and Linux.
|
|
117
|
+
- Add `2>/dev/null` to hide "Permission denied" when searching outside the workspace.
|
|
118
|
+
|
|
119
|
+
## Tips (workspace-only)
|
|
120
|
+
|
|
121
|
+
- Use `.` so search is limited to current directory (workspace root when exec runs there).
|
|
122
|
+
- For large trees, consider `-maxdepth` or file-type filters to keep output small.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: file-stats
|
|
3
|
+
description: Get line count, word count, or first/last lines of a file (wc, head, tail). Use when the user asks "how many lines in this file", "first 20 lines of …", "word count", "last 10 lines", "show the top of the file".
|
|
4
|
+
metadata:
|
|
5
|
+
clawdbot:
|
|
6
|
+
emoji: "📊"
|
|
7
|
+
requires:
|
|
8
|
+
bins:
|
|
9
|
+
- wc
|
|
10
|
+
- head
|
|
11
|
+
- tail
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# File stats (wc, head, tail)
|
|
15
|
+
|
|
16
|
+
Use **wc**, **head**, and **tail** via the **exec** tool. Path can be relative (workspace) or absolute (e.g. `~/file.txt`).
|
|
17
|
+
|
|
18
|
+
## Line count
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
wc -l path/to/file
|
|
22
|
+
wc -l < path/to/file
|
|
23
|
+
# Second form outputs only the number (no filename).
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Word count
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
wc -w path/to/file
|
|
30
|
+
wc -w < path/to/file
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Line, word, and byte count
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
wc path/to/file
|
|
37
|
+
# Output: lines words bytes filename
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## First N lines (head)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
head -n 20 path/to/file
|
|
44
|
+
head -20 path/to/file
|
|
45
|
+
head path/to/file
|
|
46
|
+
# Default is 10 lines.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Last N lines (tail)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
tail -n 10 path/to/file
|
|
53
|
+
tail -10 path/to/file
|
|
54
|
+
tail path/to/file
|
|
55
|
+
# Default is 10 lines.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Skip first N lines (tail)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
tail -n +21 path/to/file
|
|
62
|
+
# Lines 21 to end (skip first 20).
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Tips
|
|
66
|
+
|
|
67
|
+
- Use `head -c 5000` or `tail -c 5000` for first/last N **bytes** if needed.
|
|
68
|
+
- For "preview" or "first part of file", use `head -n 50`.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git
|
|
3
|
+
description: Run read-only git commands in the workspace (status, log, branch, diff). Use when the user asks "what's the git status", "recent commits", "current branch", "show me the diff".
|
|
4
|
+
metadata:
|
|
5
|
+
clawdbot:
|
|
6
|
+
emoji: "📂"
|
|
7
|
+
requires:
|
|
8
|
+
bins:
|
|
9
|
+
- git
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Git (read-only)
|
|
13
|
+
|
|
14
|
+
Run **read-only** git commands in the workspace via the **exec** tool. Do **not** run `git commit`, `git push`, `git reset`, or any command that modifies history or remote. Restrict to status, log, branch, and diff.
|
|
15
|
+
|
|
16
|
+
## Status
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git status
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Working tree state (clean, modified, untracked).
|
|
23
|
+
|
|
24
|
+
## Recent commits
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git log -n 10 --oneline
|
|
28
|
+
git log -n 5 --pretty=format:"%h %s (%an, %ar)"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Current branch and list branches
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git branch --show-current
|
|
35
|
+
git branch -a
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Diff (unstaged changes)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git diff
|
|
42
|
+
git diff --stat
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For a specific file:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git diff -- path/to/file
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Last commit message
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git log -1 --pretty=%B
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Tips
|
|
58
|
+
|
|
59
|
+
- Commands run in the **workspace** (agent workspace or repo root). Do not pass `skill_id` for git unless the skill dir is the repo; use exec with cwd in the workspace.
|
|
60
|
+
- If the user asks "what branch am I on" or "any uncommitted changes?", use the commands above and summarize the output.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gmail
|
|
3
|
+
description: Send email via Gmail using your connected account. Uses Sulala Portal for the access token; includes a script to send email from the command line or automation. Requires the Sulala Portal skill for token. Use when the user wants to send email, compose mail, or automate Gmail sending.
|
|
4
|
+
metadata:
|
|
5
|
+
sulala:
|
|
6
|
+
requires:
|
|
7
|
+
skills:
|
|
8
|
+
- sulala-portal
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Gmail (Sulala Portal)
|
|
12
|
+
|
|
13
|
+
Send email using your **Gmail account connected in the Sulala Portal**. This skill provides a **script**; use the **exec** tool to run it. No static send-email code in the loader; the skill is script + docs like YouTube Shorts automation.
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
1. **Get an access token** from the Portal (list connections, then `POST connections/{connection_id}/use` for Gmail).
|
|
18
|
+
2. **Send email** by running the script via **exec** (see below).
|
|
19
|
+
|
|
20
|
+
## Getting the token (Portal)
|
|
21
|
+
|
|
22
|
+
- **Tool**: `sulala-portal_request`
|
|
23
|
+
- **List connections**: `GET` path `connections` (filter by `provider === "gmail"` in the response).
|
|
24
|
+
- **Get token**: `POST` path `connections/{id}/use`. Use the connection’s `connection_id` from the list (e.g. `conn_gmail_...`). If you get 404, use `connection_id` in the path instead of `id`. Response: `{ connectionId, provider, accessToken, scopes }`.
|
|
25
|
+
|
|
26
|
+
## Sending email (use exec tool + script — preferred)
|
|
27
|
+
|
|
28
|
+
Use the **exec** tool to run the skill script. No need to build RFC 2822 or base64url by hand.
|
|
29
|
+
|
|
30
|
+
1. Get **accessToken** from the Portal (`sulala-portal_request`: list connections, then `POST connections/{connection_id}/use` with the Gmail connection’s `connection_id`).
|
|
31
|
+
2. Call **exec** with:
|
|
32
|
+
- **skill_id**: `"gmail"` (so the command runs in this skill’s directory).
|
|
33
|
+
- **command**: `python3 scripts/send_email.py --token "<accessToken>" --to "recipient@example.com" --subject "Subject line" --body "Email body text."`
|
|
34
|
+
|
|
35
|
+
Example exec call:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"skill_id": "gmail",
|
|
40
|
+
"command": "python3 scripts/send_email.py --token \"<paste accessToken from Portal>\" --to \"sai.ko@mothernode.com\" --subject \"test title\" --body \"test body\""
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- **Token**: from `POST connections/{connection_id}/use` (see above).
|
|
45
|
+
- **To**, **Subject**, **Body**: recipient email, subject line, and body text. Escape quotes inside the command string as needed.
|
|
46
|
+
|
|
47
|
+
Full script options: [references/send-email.md](references/send-email.md).
|
|
48
|
+
|
|
49
|
+
## Skill layout (like YouTube Shorts automation)
|
|
50
|
+
|
|
51
|
+
- **scripts/send_email.py** — runnable script: `--token`, `--to`, `--subject`, `--body` or `--body-file`.
|
|
52
|
+
- **references/send-email.md** — how to run the script and get the token.
|
|
53
|
+
- **SKILL.md** — this file: overview, get token, send via exec + script.
|
|
54
|
+
|
|
55
|
+
No separate config: the Sulala Portal skill provides the gateway and token; this skill adds the script and docs.
|