@johpaz/hive-skills 0.1.1

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/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@johpaz/hive-skills",
3
+ "version": "0.1.1",
4
+ "description": "Hive Skills — Official bundled skills for Hive",
5
+ "main": "./src/index.ts",
6
+ "license": "MIT",
7
+ "files": [
8
+ "src/"
9
+ ],
10
+ "scripts": {
11
+ "test": "bun test"
12
+ },
13
+ "dependencies": {
14
+ "@johpaz/hive-core": "workspace:*",
15
+ "zod": "latest"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "latest",
19
+ "@types/bun": "latest"
20
+ }
21
+ }
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: browser_automation
3
+ description: "Control a web browser for automation tasks"
4
+ metadata:
5
+ hive:
6
+ emoji: "🌐"
7
+ bins: ["chromium", "chrome"]
8
+ userInvocable: true
9
+ requires:
10
+ config: []
11
+ ---
12
+
13
+ # Browser Automation Skill
14
+
15
+ This skill enables the agent to control a web browser for automation tasks.
16
+
17
+ ## Capabilities
18
+
19
+ - Navigate to URLs
20
+ - Click elements
21
+ - Fill forms
22
+ - Extract content
23
+ - Take screenshots
24
+ - Handle multiple tabs
25
+
26
+ ## Configuration
27
+
28
+ Enable in CONFIG.yaml:
29
+
30
+ ```yaml
31
+ tools:
32
+ browser:
33
+ enabled: true
34
+ headless: true
35
+ timeoutSeconds: 30
36
+ ```
37
+
38
+ ## Usage Examples
39
+
40
+ ### Navigate and Extract
41
+
42
+ ```
43
+ browser_navigate(url: "https://example.com")
44
+ browser_extract(selector: ".content")
45
+ ```
46
+
47
+ ### Fill Form
48
+
49
+ ```
50
+ browser_fill(selector: "#email", value: "user@example.com")
51
+ browser_click(selector: "#submit")
52
+ ```
53
+
54
+ ## Best Practices
55
+
56
+ - Use headless mode for background tasks
57
+ - Set appropriate timeouts
58
+ - Close browser when done
59
+ - Handle dynamic content with waits
60
+
61
+ ## Limitations
62
+
63
+ - Requires Chromium/Chrome installed
64
+ - Some sites may block automation
65
+ - Captchas cannot be bypassed
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: context_compact
3
+ description: "Manually trigger context compaction when conversation gets long"
4
+ metadata:
5
+ hive:
6
+ emoji: "📦"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # Context Compact Skill
12
+
13
+ This skill allows manual triggering of context compaction.
14
+
15
+ ## Usage
16
+
17
+ ### Via Slash Command
18
+
19
+ ```
20
+ /compact
21
+ ```
22
+
23
+ ### When to Use
24
+
25
+ - When you notice the agent is forgetting earlier context
26
+ - When responses become slower
27
+ - Before starting a new major topic
28
+
29
+ ## How It Works
30
+
31
+ 1. The agent summarizes the conversation history
32
+ 2. Recent messages are preserved
33
+ 3. A summary replaces older messages
34
+ 4. Important information from memory is retained
35
+
36
+ ## What Gets Preserved
37
+
38
+ - Last N messages (configurable)
39
+ - Pending tool calls
40
+ - Important facts saved to memory
41
+
42
+ ## Automatic Compaction
43
+
44
+ The system automatically compacts when:
45
+ - Context reaches 80% of model's limit (configurable)
46
+ - Before critical operations
47
+
48
+ Use `/compact` for manual control when needed.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: cron_manager
3
+ description: "Schedule and manage automated tasks"
4
+ metadata:
5
+ hive:
6
+ emoji: "⏰"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # Cron Manager Skill
12
+
13
+ This skill enables the agent to schedule and manage automated tasks.
14
+
15
+ ## Available Tools
16
+
17
+ - `cron_add`: Add a new scheduled task
18
+ - `cron_list`: List all scheduled tasks
19
+ - `cron_edit`: Edit an existing task
20
+ - `cron_remove`: Remove a scheduled task
21
+
22
+ ## Usage
23
+
24
+ ### Add a Daily Task
25
+
26
+ ```
27
+ cron_add(expression: "0 9 * * *", task: "Send daily report")
28
+ ```
29
+
30
+ ### List All Tasks
31
+
32
+ ```
33
+ cron_list()
34
+ ```
35
+
36
+ ### Remove a Task
37
+
38
+ ```
39
+ cron_remove(jobId: "cron-1")
40
+ ```
41
+
42
+ ## Cron Expression Format
43
+
44
+ ```
45
+ ┌───────────── minute (0 - 59)
46
+ │ ┌───────────── hour (0 - 23)
47
+ │ │ ┌───────────── day of month (1 - 31)
48
+ │ │ │ ┌───────────── month (1 - 12)
49
+ │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday = 0)
50
+ │ │ │ │ │
51
+ * * * * *
52
+ ```
53
+
54
+ ### Examples
55
+
56
+ - `0 9 * * *` - Every day at 9:00 AM
57
+ - `*/15 * * * *` - Every 15 minutes
58
+ - `0 9 * * 1` - Every Monday at 9:00 AM
59
+ - `0 0 1 * *` - First day of every month at midnight
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: file_manager
3
+ description: "Read, write, and manage files in the workspace"
4
+ metadata:
5
+ hive:
6
+ emoji: "📁"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # File Manager Skill
12
+
13
+ This skill enables the agent to manage files in the workspace.
14
+
15
+ ## Available Tools
16
+
17
+ - `read`: Read file contents
18
+ - `write`: Create or overwrite files
19
+ - `edit`: Make targeted edits to existing files
20
+ - `apply_patch`: Apply diff/patch format changes
21
+
22
+ ## Usage
23
+
24
+ ### Reading Files
25
+
26
+ ```
27
+ read(path: "/path/to/file.txt")
28
+ read(path: "/path/to/file.txt", offset: 10, limit: 50)
29
+ ```
30
+
31
+ ### Writing Files
32
+
33
+ ```
34
+ write(path: "/path/to/file.txt", content: "Hello, World!")
35
+ ```
36
+
37
+ ### Editing Files
38
+
39
+ ```
40
+ edit(path: "/path/to/file.txt", oldString: "old text", newString: "new text")
41
+ ```
42
+
43
+ ## Best Practices
44
+
45
+ - Always read a file before editing to understand its structure
46
+ - Use `offset` and `limit` for large files
47
+ - Create backups before major changes
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: http_client
3
+ description: "Make HTTP requests with custom headers and authentication"
4
+ metadata:
5
+ hive:
6
+ emoji: "🌐"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # HTTP Client Skill
12
+
13
+ This skill enables the agent to make HTTP requests to external APIs and services.
14
+
15
+ ## Available Tools
16
+
17
+ - `web_fetch`: Fetch content from URLs
18
+
19
+ ## Usage
20
+
21
+ ### Basic GET Request
22
+
23
+ ```
24
+ web_fetch(url: "https://api.example.com/data")
25
+ ```
26
+
27
+ ### With Custom Parameters
28
+
29
+ ```
30
+ web_fetch(url: "https://api.example.com/data", maxLength: 5000)
31
+ ```
32
+
33
+ ## Best Practices
34
+
35
+ - Always handle potential errors
36
+ - Respect rate limits
37
+ - Use appropriate timeouts
38
+ - Validate response data before processing
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: memory
3
+ description: "Store and retrieve persistent notes across sessions"
4
+ metadata:
5
+ hive:
6
+ emoji: "🧠"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # Memory Skill
12
+
13
+ This skill enables the agent to maintain persistent memory across sessions.
14
+
15
+ ## Usage
16
+
17
+ Use memory to store important information that should persist between conversations.
18
+
19
+ ## Available Operations
20
+
21
+ - `memory_write`: Save a note to memory
22
+ - `memory_read`: Retrieve a note from memory
23
+ - `memory_list`: List all saved notes
24
+
25
+ ## Examples
26
+
27
+ 1. Save a note:
28
+ ```
29
+ memory_write(title: "User preferences", content: "Prefers brief responses, TypeScript developer")
30
+ ```
31
+
32
+ 2. Read a note:
33
+ ```
34
+ memory_read(title: "User preferences")
35
+ ```
36
+
37
+ 3. List all notes:
38
+ ```
39
+ memory_list()
40
+ ```
41
+
42
+ ## Best Practices
43
+
44
+ - Use descriptive titles for easy retrieval
45
+ - Update notes when information changes
46
+ - Don't store sensitive information in memory
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: shell
3
+ description: "Execute shell commands safely with allowlist control"
4
+ metadata:
5
+ hive:
6
+ emoji: "💻"
7
+ bins: [bash, sh]
8
+ userInvocable: true
9
+ requires:
10
+ config: []
11
+ ---
12
+
13
+ # Shell Skill
14
+
15
+ This skill enables the agent to execute shell commands.
16
+
17
+ ## Usage
18
+
19
+ Use the `exec` tool to run shell commands. Commands are subject to allowlist/denylist restrictions.
20
+
21
+ ## Safety
22
+
23
+ - Only commands in the allowlist can be executed
24
+ - Commands matching denylist patterns are always blocked
25
+ - Commands run with a configurable timeout
26
+
27
+ ## Parameters
28
+
29
+ - `command` (required): The command to execute
30
+ - `timeout` (optional): Timeout in seconds (default: 30)
31
+
32
+ ## Examples
33
+
34
+ 1. List files:
35
+ ```
36
+ exec(command: "ls -la")
37
+ ```
38
+
39
+ 2. Check git status:
40
+ ```
41
+ exec(command: "git status")
42
+ ```
43
+
44
+ ## Best Practices
45
+
46
+ - Prefer read-only commands when possible
47
+ - Always check command output for errors
48
+ - Use absolute paths for reliability
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: system_notify
3
+ description: "Send system desktop notifications"
4
+ metadata:
5
+ hive:
6
+ emoji: "🔔"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # System Notify Skill
12
+
13
+ This skill enables the agent to send desktop notifications.
14
+
15
+ ## Available Tools
16
+
17
+ - `notify`: Send a system notification
18
+
19
+ ## Usage
20
+
21
+ ### Basic Notification
22
+
23
+ ```
24
+ notify(title: "Task Complete", message: "Your file has been processed")
25
+ ```
26
+
27
+ ### With Urgency Level
28
+
29
+ ```
30
+ notify(title: "Important", message: "Server is down", urgency: "critical")
31
+ ```
32
+
33
+ ## Urgency Levels
34
+
35
+ - `low`: Low priority notification
36
+ - `normal`: Standard notification (default)
37
+ - `critical`: High priority, may stay on screen
38
+
39
+ ## Platform Support
40
+
41
+ - **Linux**: Uses `notify-send` (libnotify)
42
+ - **macOS**: Uses AppleScript
43
+ - **Windows**: Not currently supported
44
+
45
+ ## Best Practices
46
+
47
+ - Use appropriate urgency levels
48
+ - Keep messages concise
49
+ - Don't send too many notifications
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: web_search
3
+ description: "Search the web for current information using search engines"
4
+ metadata:
5
+ hive:
6
+ emoji: "🔍"
7
+ bins: []
8
+ userInvocable: true
9
+ ---
10
+
11
+ # Web Search Skill
12
+
13
+ This skill enables the agent to search the web for current information.
14
+
15
+ ## Usage
16
+
17
+ Use the `web_search` tool to search for information on the internet. The search will return relevant results with titles, URLs, and snippets.
18
+
19
+ ## Parameters
20
+
21
+ - `query` (required): The search query string
22
+ - `numResults` (optional): Number of results to return (default: 5)
23
+
24
+ ## Examples
25
+
26
+ 1. Search for recent news:
27
+ ```
28
+ web_search(query: "latest AI developments 2024")
29
+ ```
30
+
31
+ 2. Search for documentation:
32
+ ```
33
+ web_search(query: "TypeScript generic constraints examples")
34
+ ```
35
+
36
+ ## Best Practices
37
+
38
+ - Be specific with your search queries
39
+ - Use quotes for exact phrases
40
+ - Combine with `web_fetch` to get full content from results
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./loader.ts";
package/src/loader.ts ADDED
@@ -0,0 +1,143 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import * as yaml from "js-yaml";
4
+ import type { Config } from "../config/loader.ts";
5
+ import { logger } from "../utils/logger.ts";
6
+
7
+ export interface SkillMetadata {
8
+ name: string;
9
+ description: string;
10
+ metadata?: {
11
+ hive?: {
12
+ emoji?: string;
13
+ bins?: string[];
14
+ userInvocable?: boolean;
15
+ requires?: {
16
+ config?: string[];
17
+ env?: string[];
18
+ };
19
+ install?: {
20
+ brew?: string;
21
+ apt?: string;
22
+ npm?: string;
23
+ };
24
+ os?: string[];
25
+ };
26
+ };
27
+ }
28
+
29
+ export interface Skill {
30
+ name: string;
31
+ description: string;
32
+ content: string;
33
+ metadata: SkillMetadata["metadata"];
34
+ source: "bundled" | "managed" | "workspace";
35
+ path: string;
36
+ }
37
+
38
+ function parseFrontmatter(content: string): { frontmatter: Record<string, unknown>; body: string } {
39
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
40
+
41
+ if (!match) {
42
+ return { frontmatter: {}, body: content };
43
+ }
44
+
45
+ try {
46
+ const frontmatter = yaml.load(match[1]!) as Record<string, unknown>;
47
+ const body = match[2]!;
48
+ return { frontmatter, body };
49
+ } catch {
50
+ return { frontmatter: {}, body: content };
51
+ }
52
+ }
53
+
54
+ export class SkillLoader {
55
+ private config: Config;
56
+ private log = logger.child("skills");
57
+ private cache: Map<string, Skill> = new Map();
58
+
59
+ constructor(config: Config) {
60
+ this.config = config;
61
+ }
62
+
63
+ private expandPath(p: string): string {
64
+ if (p.startsWith("~")) {
65
+ return path.join(process.env.HOME ?? "", p.slice(1));
66
+ }
67
+ return p;
68
+ }
69
+
70
+ loadSkill(skillPath: string, source: Skill["source"]): Skill | null {
71
+ try {
72
+ const skillMdPath = path.join(skillPath, "SKILL.md");
73
+
74
+ if (!fs.existsSync(skillMdPath)) {
75
+ return null;
76
+ }
77
+
78
+ const content = fs.readFileSync(skillMdPath, "utf-8");
79
+ const { frontmatter, body } = parseFrontmatter(content);
80
+
81
+ const metadata = frontmatter.metadata as SkillMetadata["metadata"];
82
+ const name = (frontmatter.name as string) ?? path.basename(skillPath);
83
+ const description = (frontmatter.description as string) ?? "";
84
+
85
+ const skill: Skill = {
86
+ name,
87
+ description,
88
+ content: body,
89
+ metadata,
90
+ source,
91
+ path: skillPath,
92
+ };
93
+
94
+ this.cache.set(name, skill);
95
+ return skill;
96
+ } catch (error) {
97
+ this.log.error(`Failed to load skill: ${skillPath}`, { error: (error as Error).message });
98
+ return null;
99
+ }
100
+ }
101
+
102
+ loadAllSkills(): Skill[] {
103
+ const skills: Map<string, Skill> = new Map();
104
+
105
+ const managedDir = this.expandPath(this.config.skills?.managedDir ?? "~/.hive/skills");
106
+ if (fs.existsSync(managedDir)) {
107
+ for (const entry of fs.readdirSync(managedDir, { withFileTypes: true })) {
108
+ if (entry.isDirectory()) {
109
+ const skill = this.loadSkill(path.join(managedDir, entry.name), "managed");
110
+ if (skill) {
111
+ skills.set(skill.name, skill);
112
+ }
113
+ }
114
+ }
115
+ }
116
+
117
+ const workspaceDir = "workspace/skills";
118
+ if (fs.existsSync(workspaceDir)) {
119
+ for (const entry of fs.readdirSync(workspaceDir, { withFileTypes: true })) {
120
+ if (entry.isDirectory()) {
121
+ const skill = this.loadSkill(path.join(workspaceDir, entry.name), "workspace");
122
+ if (skill) {
123
+ skills.set(skill.name, skill);
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ return Array.from(skills.values());
130
+ }
131
+
132
+ getSkill(name: string): Skill | undefined {
133
+ return this.cache.get(name);
134
+ }
135
+
136
+ clearCache(): void {
137
+ this.cache.clear();
138
+ }
139
+ }
140
+
141
+ export function createSkillLoader(config: Config): SkillLoader {
142
+ return new SkillLoader(config);
143
+ }