skill-harbor 0.2.0

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.
@@ -0,0 +1,24 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: oven-sh/setup-bun@v1
13
+ with:
14
+ bun-version: latest
15
+ - name: Install dependencies
16
+ run: bun install
17
+ - name: Build
18
+ run: bun run build
19
+ - name: Publish to npm
20
+ run: |
21
+ echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
22
+ npm publish --access public
23
+ env:
24
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 John Bailey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ <p align="center">
2
+ <img src="assets/header.png" alt="Skill Harbor Header" width="100%">
3
+ </p>
4
+
5
+ <h1 align="center">⚓ Skill Harbor</h1>
6
+
7
+ <p align="center">
8
+ <strong>The Workspace Sync Engine for AI Agents — Standardize skills and context across your entire team.</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/skill-harbor"><img src="https://img.shields.io/npm/v/skill-harbor.svg?style=flat-square" alt="NPM Version"></a>
13
+ <a href="https://github.com/johntimothybailey/skill-harbor/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License"></a>
14
+ <a href="https://github.com/johntimothybailey/skill-harbor"><img src="https://img.shields.io/github/stars/johntimothybailey/skill-harbor.svg?style=flat-square&color=gold" alt="GitHub Stars"></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ ## 🌊 Overview
20
+
21
+ **Skill Harbor** is a lightweight "Package Manager for Agent Context"—a powerful **Workspace Sync Engine** built for AI agent developers.
22
+
23
+ Instead of installing skills globally on a single machine or forcing developers to configure MCP servers, Skill Harbor manages a project-level `harbor-manifest.json`. When a developer clones your repo, they simply run `skill-harbor up`, and your specifically chosen skills are instantly fetched, transpiled, and injected natively into their local agent's configuration folders.
24
+
25
+ **It solves the massive problem of standardizing AI context across enterprise teams.**
26
+
27
+ ## 🛠️ The Architecture: How It Works
28
+
29
+ Skill Harbor is designed as the **Commander** of your Workspace Sync Engine. Instead of reinventing the wheel, it acts as a high-level orchestrator that tightly integrates two incredibly powerful underlying tools from the agent ecosystem.
30
+
31
+ Here is exactly how the three tools relate to each other:
32
+
33
+ - ⚓ **Skill Harbor (The General Contractor)**: The workspace package manager. It manages your project's `harbor-manifest.json`, tracks which skills belong where, and coordinates the synchronization loop when you run `skill-harbor up`.
34
+ - 🐬 **[skillfish](https://www.skill.fish) (The Delivery Truck)**: When Harbor reads your manifest, it calls upon `skillfish` under the hood to locate the correct repository, download the raw markdown files, and bring them to your local temporary folder.
35
+ - 📦 **[skill-porter](https://mcpmarket.com/tools/skills/skill-porter-cross-platform-ai-converter) (The Carpenter)**: Raw markdown files from GitHub aren't always perfectly formatted for specific agents. Harbor passes the downloaded files to `skill-porter`, which handles the complex transpilation (e.g., formatting them strictly for Claude Code's prompt expectations or Cursor's rules system).
36
+
37
+ > **In summary**: Skill Harbor holds the blueprints. It uses `skillfish` to deliver the raw lumber, and `skill-porter` to cut that lumber so it perfectly fits your local `.claude` or `.cursor` directories.
38
+
39
+ ## 🚀 Usage
40
+
41
+ ### Installation
42
+
43
+ Install globally or as a project dependency using Bun:
44
+
45
+ ```bash
46
+ bun add -g skill-harbor
47
+ ```
48
+
49
+ ### Basic Commands
50
+
51
+ Once installed, use `skill-harbor` to standardize your project's AI capabilities:
52
+
53
+ ```bash
54
+ # Add a skill to the current project's manifest (like standardizing your team's React rules)
55
+ skill-harbor dock <skill-url-or-name>
56
+
57
+ # List all skills required by the current project workspace
58
+ skill-harbor list
59
+
60
+ # The Magic Command: Sync the workspace.
61
+ # Fetches all manifested skills, transpiles them, and injects them seamlessly into .claude/skills and .cursor/rules.
62
+ skill-harbor up
63
+ ```
64
+
65
+ ## ✨ Features
66
+
67
+ - 🚢 **Workspace Sync Engine**: Standardize AI context rules for your entire repo.
68
+ - 🏗️ **Cross-Platform Transpilation**: Powered by `skill-porter` to convert Claude Code skills to Cursor rules seamlessly.
69
+ - ⚡ **Zero Friction**: Keeps skills as highly effective raw markdown (injected instantly into the agent's brain), without the overhead of MCP servers.
70
+ - 🔌 **Idempotent**: Run `skill-harbor up` repeatedly to pull down the latest transpiled skill updates safely.
71
+
72
+ ## ⚖️ Alternatives
73
+
74
+ While Skill Harbor is built specifically for **team-wide context standardization** via our manifest system, there are other fantastic tools in the ecosystem you might prefer depending on your workflow:
75
+
76
+ - 🚀 **[agent-skill-porter](https://www.npmjs.com/package/agent-skill-porter)**: A powerful, zero-config lifecycle management CLI for AI agent skills.
77
+ - **How it differs**: Focuses on an all-in-one standalone user experience that doesn't require project-level manifests.
78
+ - **Why use it**: Choose this if you are an individual developer who wants a single, unified tool to handle skill porting without managing a `harbor-manifest.json`.
79
+ - 👉 **[uberskills.dev](https://uberskills.dev/)**: The enterprise-grade standard for managed AI capabilities.
80
+ - **How it differs**: Provides a full-managed cloud platform with advanced synchronization, automation, and organizational controls.
81
+ - **Why use it**: Choose this if you are a large team or organization that requires centralized, cloud-synced context rules with enterprise-level security and management features.
82
+
83
+ ---
84
+
85
+ ## 📄 License
86
+
87
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
88
+
89
+ <p align="center">
90
+ Built with ❤️ for the AI Agent Ecosystem
91
+ </p>
Binary file
package/bun.lock ADDED
@@ -0,0 +1,248 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 0,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "skill-harbor",
7
+ "dependencies": {
8
+ "commander": "^11.1.0",
9
+ "fast-glob": "^3.3.2",
10
+ "kleur": "^4.1.5",
11
+ "ora": "^7.0.1",
12
+ "skill-porter": "github:jduncan-rva/skill-porter",
13
+ "skillfish": "1.0.30",
14
+ },
15
+ "devDependencies": {
16
+ "bun-types": "latest",
17
+ "typescript": "^5.3.3",
18
+ },
19
+ },
20
+ },
21
+ "packages": {
22
+ "@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="],
23
+
24
+ "@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="],
25
+
26
+ "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
27
+
28
+ "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
29
+
30
+ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
31
+
32
+ "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="],
33
+
34
+ "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="],
35
+
36
+ "@pnpm/npm-conf": ["@pnpm/npm-conf@3.0.2", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA=="],
37
+
38
+ "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
39
+
40
+ "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
41
+
42
+ "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
43
+
44
+ "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
45
+
46
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
47
+
48
+ "atomically": ["atomically@2.1.1", "", { "dependencies": { "stubborn-fs": "^2.0.0", "when-exit": "^2.1.4" } }, "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ=="],
49
+
50
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
51
+
52
+ "bl": ["bl@5.1.0", "", { "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ=="],
53
+
54
+ "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="],
55
+
56
+ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
57
+
58
+ "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
59
+
60
+ "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
61
+
62
+ "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
63
+
64
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
65
+
66
+ "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
67
+
68
+ "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
69
+
70
+ "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
71
+
72
+ "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
73
+
74
+ "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="],
75
+
76
+ "configstore": ["configstore@7.1.0", "", { "dependencies": { "atomically": "^2.0.3", "dot-prop": "^9.0.0", "graceful-fs": "^4.2.11", "xdg-basedir": "^5.1.0" } }, "sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg=="],
77
+
78
+ "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
79
+
80
+ "dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="],
81
+
82
+ "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
83
+
84
+ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
85
+
86
+ "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="],
87
+
88
+ "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
89
+
90
+ "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
91
+
92
+ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
93
+
94
+ "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="],
95
+
96
+ "giget": ["giget@3.1.2", "", { "bin": { "giget": "dist/cli.mjs" } }, "sha512-T2qUpKBHeUTwHcIhydgnJzhL0Hj785ms+JkxaaWQH9SDM/llXeewnOkfJcFShAHjWI+26hOChwUfCoupaXLm8g=="],
97
+
98
+ "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
99
+
100
+ "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="],
101
+
102
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
103
+
104
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
105
+
106
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
107
+
108
+ "ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="],
109
+
110
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
111
+
112
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
113
+
114
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
115
+
116
+ "is-in-ci": ["is-in-ci@1.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg=="],
117
+
118
+ "is-installed-globally": ["is-installed-globally@1.0.0", "", { "dependencies": { "global-directory": "^4.0.1", "is-path-inside": "^4.0.0" } }, "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ=="],
119
+
120
+ "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
121
+
122
+ "is-npm": ["is-npm@6.1.0", "", {}, "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA=="],
123
+
124
+ "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
125
+
126
+ "is-path-inside": ["is-path-inside@4.0.0", "", {}, "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA=="],
127
+
128
+ "is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
129
+
130
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
131
+
132
+ "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
133
+
134
+ "ky": ["ky@1.14.3", "", {}, "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw=="],
135
+
136
+ "latest-version": ["latest-version@9.0.0", "", { "dependencies": { "package-json": "^10.0.0" } }, "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA=="],
137
+
138
+ "log-symbols": ["log-symbols@5.1.0", "", { "dependencies": { "chalk": "^5.0.0", "is-unicode-supported": "^1.1.0" } }, "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA=="],
139
+
140
+ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
141
+
142
+ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
143
+
144
+ "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
145
+
146
+ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
147
+
148
+ "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
149
+
150
+ "ora": ["ora@7.0.1", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^4.0.0", "cli-spinners": "^2.9.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^1.3.0", "log-symbols": "^5.1.0", "stdin-discarder": "^0.1.0", "string-width": "^6.1.0", "strip-ansi": "^7.1.0" } }, "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw=="],
151
+
152
+ "package-json": ["package-json@10.0.1", "", { "dependencies": { "ky": "^1.2.0", "registry-auth-token": "^5.0.2", "registry-url": "^6.0.1", "semver": "^7.6.0" } }, "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg=="],
153
+
154
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
155
+
156
+ "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
157
+
158
+ "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="],
159
+
160
+ "pupa": ["pupa@3.3.0", "", { "dependencies": { "escape-goat": "^4.0.0" } }, "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA=="],
161
+
162
+ "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
163
+
164
+ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
165
+
166
+ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
167
+
168
+ "registry-auth-token": ["registry-auth-token@5.1.1", "", { "dependencies": { "@pnpm/npm-conf": "^3.0.2" } }, "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q=="],
169
+
170
+ "registry-url": ["registry-url@6.0.1", "", { "dependencies": { "rc": "1.2.8" } }, "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q=="],
171
+
172
+ "restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
173
+
174
+ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
175
+
176
+ "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
177
+
178
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
179
+
180
+ "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
181
+
182
+ "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
183
+
184
+ "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
185
+
186
+ "skill-porter": ["skill-porter@github:jduncan-rva/skill-porter#7ad93ec", { "dependencies": { "chalk": "^5.3.0", "commander": "^12.0.0", "js-yaml": "^4.1.0" }, "bin": { "skill-porter": "./src/cli.js" } }, "jduncan-rva-skill-porter-7ad93ec", "sha512-B6aA6n4R7Fv75H6vF//9CuNAij7M7xbpJYMFlzu7z5YBOJGpY/W7KIvQB3i4KIQTSNEEwMZG3VyNIXdMhthIEg=="],
187
+
188
+ "skillfish": ["skillfish@1.0.30", "", { "dependencies": { "@clack/prompts": "^0.11.0", "commander": "^14.0.2", "giget": "^3.1.1", "picocolors": "^1.1.1", "update-notifier": "^7.3.1" }, "bin": { "skillfish": "dist/index.js" } }, "sha512-31NkmISg34CDg/hrFksX1wMxuSkw56uFuw5r6W6ua9FrzCK54rLzxuURBo8EhjTT72RixTm9UCeDnPAWK1vZ+g=="],
189
+
190
+ "stdin-discarder": ["stdin-discarder@0.1.0", "", { "dependencies": { "bl": "^5.0.0" } }, "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ=="],
191
+
192
+ "string-width": ["string-width@6.1.0", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^10.2.1", "strip-ansi": "^7.0.1" } }, "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ=="],
193
+
194
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
195
+
196
+ "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
197
+
198
+ "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
199
+
200
+ "stubborn-fs": ["stubborn-fs@2.0.0", "", { "dependencies": { "stubborn-utils": "^1.0.1" } }, "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA=="],
201
+
202
+ "stubborn-utils": ["stubborn-utils@1.0.2", "", {}, "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg=="],
203
+
204
+ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
205
+
206
+ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
207
+
208
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
209
+
210
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
211
+
212
+ "update-notifier": ["update-notifier@7.3.1", "", { "dependencies": { "boxen": "^8.0.1", "chalk": "^5.3.0", "configstore": "^7.0.0", "is-in-ci": "^1.0.0", "is-installed-globally": "^1.0.0", "is-npm": "^6.0.0", "latest-version": "^9.0.0", "pupa": "^3.1.0", "semver": "^7.6.3", "xdg-basedir": "^5.1.0" } }, "sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA=="],
213
+
214
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
215
+
216
+ "when-exit": ["when-exit@2.1.5", "", {}, "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg=="],
217
+
218
+ "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
219
+
220
+ "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
221
+
222
+ "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="],
223
+
224
+ "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="],
225
+
226
+ "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
227
+
228
+ "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
229
+
230
+ "config-chain/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
231
+
232
+ "rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
233
+
234
+ "skill-porter/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
235
+
236
+ "skillfish/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
237
+
238
+ "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
239
+
240
+ "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
241
+
242
+ "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
243
+
244
+ "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
245
+
246
+ "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
247
+ }
248
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "skill-harbor",
3
+ "version": "0.2.0",
4
+ "description": "The Workspace Sync Engine for AI Agents — Standardize skills and context across your entire team.",
5
+ "author": "John Bailey",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/johntimothybailey/skill-harbor.git"
10
+ },
11
+ "homepage": "https://github.com/johntimothybailey/skill-harbor#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/johntimothybailey/skill-harbor/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "src/index.ts",
17
+ "module": "src/index.ts",
18
+ "bin": {
19
+ "skill-harbor": "src/index.ts"
20
+ },
21
+ "scripts": {
22
+ "start": "bun src/index.ts",
23
+ "test": "bun test",
24
+ "build": "bun build ./src/index.ts --target bun --outfile dist/skill-harbor"
25
+ },
26
+ "dependencies": {
27
+ "commander": "^11.1.0",
28
+ "fast-glob": "^3.3.2",
29
+ "kleur": "^4.1.5",
30
+ "ora": "^7.0.1",
31
+ "skill-porter": "github:jduncan-rva/skill-porter",
32
+ "skillfish": "1.0.30"
33
+ },
34
+ "devDependencies": {
35
+ "bun-types": "latest",
36
+ "typescript": "^5.3.3"
37
+ }
38
+ }
package/src/index.ts ADDED
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from "commander";
3
+ import kleur from "kleur";
4
+ import { Orchestrator } from "./orchestrator";
5
+ import { ManifestManager } from "./manifest";
6
+ import path from "node:path";
7
+
8
+ const program = new Command();
9
+
10
+ program
11
+ .name("skill-harbor")
12
+ .version("0.2.0")
13
+ .description(kleur.blue("The Workspace Sync Engine for AI Agents — Standardize skills and context across your entire team."));
14
+
15
+ program
16
+ .command("dock")
17
+ .argument("<url>", "Skill URL to fetch (URL or git repository)")
18
+ .description("Dock a new skill into the local harbor manifest.")
19
+ .action(async (url) => {
20
+ const manifestManager = new ManifestManager();
21
+
22
+ try {
23
+ console.log(kleur.bold().blue("\n⚓ SkillHarbor: Docking Operations Initiated ⚓\n"));
24
+
25
+ await manifestManager.init();
26
+
27
+ const urlParts = url.split("/");
28
+ let skillName = urlParts[urlParts.length - 1].replace(".git", "");
29
+ if (!skillName) skillName = `skill-${Date.now()}`;
30
+
31
+ // 3. Update Manifest
32
+ await manifestManager.addSkill({
33
+ name: skillName,
34
+ source: url,
35
+ localPath: "", // Will be populated by the 'up' command
36
+ });
37
+
38
+ console.log(kleur.bold().green(`\n🎉 Skill successfully manifested! Added ${skillName} to harbor-manifest.json.`));
39
+ console.log(kleur.italic().gray(`Run 'skill-harbor up' to sync and activate this skill in your workspace.\n`));
40
+ } catch (error: any) {
41
+ console.error(kleur.red(`\n🛳️ SkillHarbor Alert: Major malfunction in harbor operations: ${error.message}\n`));
42
+ process.exit(1);
43
+ }
44
+ });
45
+
46
+ program
47
+ .command("list")
48
+ .description("List all skills currently tracked in the local harbor manifest.")
49
+ .action(async () => {
50
+ const manifestManager = new ManifestManager();
51
+ try {
52
+ const manifest = await manifestManager.read();
53
+ const skills = Object.values(manifest.skills);
54
+
55
+ console.log(kleur.bold().blue("\n⚓ SkillHarbor: Local Fleet Manifest ⚓\n"));
56
+ if (skills.length === 0) {
57
+ console.log(kleur.yellow("No skills are currently docked in this workspace.\n"));
58
+ } else {
59
+ for (const skill of skills) {
60
+ console.log(`${kleur.green("✓")} ${kleur.bold(skill.name)} - ${kleur.gray(skill.source)}`);
61
+ }
62
+ console.log();
63
+ }
64
+ } catch (error: any) {
65
+ console.error(kleur.red(`\n🛳️ SkillHarbor Alert: Cannot read manifest. Run 'dock' first to initialize.\n`));
66
+ }
67
+ });
68
+
69
+ program
70
+ .command("up")
71
+ .description("Sync the workspace by fetching and transpiling all skills from harbor-manifest.json into local agent folders.")
72
+ .action(async () => {
73
+ const orchestrator = new Orchestrator();
74
+ const manifestManager = new ManifestManager();
75
+ try {
76
+ console.log(kleur.bold().blue("\n⚓ SkillHarbor: Workspace Synchronization Initiated ⚓\n"));
77
+ const manifest = await manifestManager.read();
78
+ const skills = Object.values(manifest.skills);
79
+
80
+ if (skills.length === 0) {
81
+ console.log(kleur.yellow("No skills found in harbor-manifest.json. Run 'dock' to add some.\n"));
82
+ return;
83
+ }
84
+
85
+ for (const skill of skills) {
86
+ console.log(kleur.magenta(`\nProcessing cargo: ${skill.name}`));
87
+ // 1. Fetch cargo to temp space
88
+ const cargoPath = await orchestrator.moor(skill.source);
89
+
90
+ // 2. Transpile for modern Agentic Editors (Claude)
91
+ const claudeProcessed = await orchestrator.processCargo(cargoPath, "claude");
92
+
93
+ // 3. Inject directly into local workspace configuration contexts
94
+ const claudeDest = path.join(process.cwd(), ".claude", "skills", skill.name);
95
+ await orchestrator.berth(claudeProcessed, claudeDest);
96
+
97
+ const cursorDest = path.join(process.cwd(), ".cursor", "rules", skill.name);
98
+ await orchestrator.berth(claudeProcessed, cursorDest);
99
+
100
+ // 4. Update the Harbor's local cache registry
101
+ const harborDir = manifestManager.getHarborDir();
102
+ const localPath = path.join(harborDir, skill.name);
103
+ await orchestrator.berth(cargoPath, localPath);
104
+
105
+ // Mark success in manifest
106
+ await manifestManager.addSkill({
107
+ ...skill,
108
+ localPath: localPath
109
+ });
110
+ }
111
+
112
+ console.log(kleur.bold().green(`\n🎉 Workspace Sync complete. The fleet is fully loaded with Agent skills.\n`));
113
+ } catch (error: any) {
114
+ console.error(kleur.red(`\n🛳️ SkillHarbor Alert: Synchronization failed: ${error.message}\n`));
115
+ process.exit(1);
116
+ } finally {
117
+ await orchestrator.cleanup();
118
+ }
119
+ });
120
+
121
+ program.parse(process.argv);
@@ -0,0 +1,61 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+
4
+ export interface SkillEntry {
5
+ name: string;
6
+ version?: string;
7
+ description?: string;
8
+ source: string; // URL, git, or local path
9
+ localPath: string; // Path within .harbor
10
+ }
11
+
12
+ export interface HarborManifest {
13
+ version: string;
14
+ dependencies: Record<string, string>; // "skill-name": "version/source"
15
+ skills: Record<string, SkillEntry>;
16
+ }
17
+
18
+ export class ManifestManager {
19
+ private manifestPath: string;
20
+ private harborDir: string;
21
+
22
+ constructor(cwd: string = process.cwd()) {
23
+ this.manifestPath = path.join(cwd, "harbor-manifest.json");
24
+ this.harborDir = path.join(cwd, ".harbor");
25
+ }
26
+
27
+ public async init(): Promise<void> {
28
+ await fs.mkdir(this.harborDir, { recursive: true });
29
+ try {
30
+ await fs.access(this.manifestPath);
31
+ } catch {
32
+ const initialManifest: HarborManifest = {
33
+ version: "1.0",
34
+ dependencies: {},
35
+ skills: {}
36
+ };
37
+ await this.write(initialManifest);
38
+ }
39
+ }
40
+
41
+ public async read(): Promise<HarborManifest> {
42
+ await this.init();
43
+ const data = await fs.readFile(this.manifestPath, "utf-8");
44
+ return JSON.parse(data) as HarborManifest;
45
+ }
46
+
47
+ public async write(manifest: HarborManifest): Promise<void> {
48
+ await fs.writeFile(this.manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
49
+ }
50
+
51
+ public async addSkill(entry: SkillEntry): Promise<void> {
52
+ const manifest = await this.read();
53
+ manifest.dependencies[entry.name] = entry.source;
54
+ manifest.skills[entry.name] = entry;
55
+ await this.write(manifest);
56
+ }
57
+
58
+ public getHarborDir(): string {
59
+ return this.harborDir;
60
+ }
61
+ }
@@ -0,0 +1,89 @@
1
+ import { spawn } from "node:child_process";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ import ora from "ora";
6
+ import kleur from "kleur";
7
+ import { Registry } from "./registry";
8
+
9
+ export class Orchestrator {
10
+ private tempDir: string;
11
+
12
+ constructor() {
13
+ this.tempDir = path.join(os.tmpdir(), `skill-harbor-${Date.now()}`);
14
+ }
15
+
16
+ async moor(url: string): Promise<string> {
17
+ const spinner = ora(kleur.cyan(`Mooring skill from ${url}...`)).start();
18
+ try {
19
+ await fs.mkdir(this.tempDir, { recursive: true });
20
+
21
+ // We assume skillfish is available as a binary or via npx
22
+ const process = Bun.spawn(["bunx", "skillfish", "fetch", url, "--out", this.tempDir]);
23
+ const output = await new Response(process.stdout).text();
24
+
25
+ if (process.exitCode !== 0) {
26
+ throw new Error(`Mooring failed: ${output}`);
27
+ }
28
+
29
+ spinner.succeed(kleur.green("Skill cargo successfully moored locally."));
30
+ return this.tempDir;
31
+ } catch (error: any) {
32
+ spinner.fail(kleur.red(`Mooring incident: ${error.message}`));
33
+ throw error;
34
+ }
35
+ }
36
+
37
+ async processCargo(cargoPath: string, targetAgent: string): Promise<string> {
38
+ const spinner = ora(kleur.cyan(`Processing cargo via SkillPorter for ${targetAgent}...`)).start();
39
+ try {
40
+ const outputPath = path.join(this.tempDir, "processed", targetAgent);
41
+ await fs.mkdir(outputPath, { recursive: true });
42
+
43
+ const process = Bun.spawn(["bunx", "skill-porter", "transpile", cargoPath, "--target", targetAgent, "--out", outputPath]);
44
+ const output = await new Response(process.stdout).text();
45
+
46
+ if (process.exitCode !== 0) {
47
+ throw new Error(`Cargo processing failed: ${output}`);
48
+ }
49
+
50
+ spinner.succeed(kleur.green(`Cargo processed for ${targetAgent} berth.`));
51
+ return outputPath;
52
+ } catch (error: any) {
53
+ spinner.fail(kleur.red(`Processing incident: ${error.message}`));
54
+ throw error;
55
+ }
56
+ }
57
+
58
+ async berth(cargoPath: string, targetPath: string): Promise<void> {
59
+ const spinner = ora(kleur.cyan(`Transporting cargo to berth: ${targetPath}`)).start();
60
+ try {
61
+ // Ensure target directory exists
62
+ await fs.mkdir(targetPath, { recursive: true });
63
+
64
+ // Atomic move or copy (since it might be across different filesystems)
65
+ const files = await fs.readdir(cargoPath);
66
+ for (const file of files) {
67
+ const source = path.join(cargoPath, file);
68
+ const destination = path.join(targetPath, file);
69
+
70
+ // Use symlink or copy? User's "Vision" mentioned "Atomic move or Symlink".
71
+ // Let's copy the processed files to the global berth.
72
+ await fs.cp(source, destination, { recursive: true });
73
+ }
74
+
75
+ spinner.succeed(kleur.green(`Skill successfully berthed at ${targetPath}`));
76
+ } catch (error: any) {
77
+ spinner.fail(kleur.red(`Berthing incident: ${error.message}`));
78
+ throw error;
79
+ }
80
+ }
81
+
82
+ async cleanup(): Promise<void> {
83
+ try {
84
+ await fs.rm(this.tempDir, { recursive: true, force: true });
85
+ } catch {
86
+ // Ignore cleanup errors
87
+ }
88
+ }
89
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "ESNext"
5
+ ],
6
+ "module": "esnext",
7
+ "target": "esnext",
8
+ "moduleResolution": "bundler",
9
+ "moduleDetection": "force",
10
+ "allowImportingTsExtensions": true,
11
+ "noEmit": true,
12
+ "composite": true,
13
+ "strict": true,
14
+ "downlevelIteration": true,
15
+ "skipLibCheck": true,
16
+ "jsx": "react-jsx",
17
+ "allowSyntheticDefaultImports": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "allowJs": true,
20
+ "types": [
21
+ "bun-types"
22
+ ]
23
+ }
24
+ }