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.
- package/.github/workflows/publish.yml +24 -0
- package/LICENSE +21 -0
- package/README.md +91 -0
- package/assets/header.png +0 -0
- package/bun.lock +248 -0
- package/package.json +38 -0
- package/src/index.ts +121 -0
- package/src/manifest.ts +61 -0
- package/src/orchestrator.ts +89 -0
- package/tsconfig.json +24 -0
|
@@ -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);
|
package/src/manifest.ts
ADDED
|
@@ -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
|
+
}
|