@aholbreich/agent-skills 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 - 2026-05-06
4
+
5
+ Initial public package structure.
6
+
7
+ Added:
8
+
9
+ - `jira-browser-fetch` skill for browser-authenticated Jira issue/JQL/linked-ticket fetches.
10
+ - `confluence-browser-fetch` skill for browser-authenticated Confluence page/CQL/descendant fetches.
11
+ - Default 5 MiB attachment download cap with skipped-file references in `attachments.json`.
12
+ - Confluence skip-unchanged behavior based on page version metadata.
13
+ - Retry and timeout options for Confluence fetches.
14
+ - Pi package metadata, README, security policy, and CI syntax checks.
15
+ - Node built-in unit tests for helper logic and CLI smoke/error paths.
16
+ - `agent-skills` installer CLI for `npx @aholbreich/agent-skills` one-shot installs.
17
+ - Default npx target is the generic Agent Skills location `~/.agents/skills`.
@@ -0,0 +1,134 @@
1
+ # Compatibility
2
+
3
+ This package is designed as a pure [Agent Skills](https://agentskills.io/) package.
4
+
5
+ Each bundled skill is a directory containing `SKILL.md` plus scripts and references. The frontmatter follows the Agent Skills conventions: required `name` and `description`, directory name matching the skill name, lowercase hyphenated names, and optional `license`/`compatibility` metadata.
6
+
7
+ ## Compatibility matrix
8
+
9
+ | Tool / Harness | Status | Install method |
10
+ |---|---:|---|
11
+ | Pi | Supported and tested | `pi install npm:@aholbreich/agent-skills` or `npx @aholbreich/agent-skills --target pi` |
12
+ | Claude Code | Compatible Agent Skills layout | `npx @aholbreich/agent-skills --target claude` or copy `skills/*` into Claude's skills directory |
13
+ | OpenAI Codex | Compatible Agent Skills layout | `npx @aholbreich/agent-skills --target codex` or copy `skills/*` into Codex's skills directory |
14
+ | OpenClaw / generic Agent Skills harnesses | Compatible Agent Skills layout | `npx @aholbreich/agent-skills --target agents` or copy `skills/*` into `.agents/skills` / configured skills directory |
15
+ | Any Agent Skills-compatible tool | Compatible layout | Copy each folder under `skills/` into the tool's configured skills directory |
16
+
17
+ ## Install commands
18
+
19
+ ### Generic Agent Skills default
20
+
21
+ ```bash
22
+ npx @aholbreich/agent-skills
23
+ ```
24
+
25
+ This installs to `~/.agents/skills` and is equivalent to:
26
+
27
+ ```bash
28
+ npx @aholbreich/agent-skills --target agents
29
+ ```
30
+
31
+ ### Pi global
32
+
33
+ ```bash
34
+ pi install npm:@aholbreich/agent-skills
35
+ ```
36
+
37
+ or:
38
+
39
+ ```bash
40
+ npx @aholbreich/agent-skills --target pi
41
+ ```
42
+
43
+ ### Pi project-local
44
+
45
+ ```bash
46
+ pi install -l npm:@aholbreich/agent-skills
47
+ ```
48
+
49
+ or:
50
+
51
+ ```bash
52
+ npx @aholbreich/agent-skills --target project
53
+ ```
54
+
55
+ ### Claude Code
56
+
57
+ ```bash
58
+ npx @aholbreich/agent-skills --target claude
59
+ ```
60
+
61
+ Project-local Claude-style install:
62
+
63
+ ```bash
64
+ npx @aholbreich/agent-skills --target project-claude
65
+ ```
66
+
67
+ ### Codex
68
+
69
+ ```bash
70
+ npx @aholbreich/agent-skills --target codex
71
+ ```
72
+
73
+ Project-local Codex-style install:
74
+
75
+ ```bash
76
+ npx @aholbreich/agent-skills --target project-codex
77
+ ```
78
+
79
+ ### Generic `.agents/skills`
80
+
81
+ ```bash
82
+ npx @aholbreich/agent-skills --target agents
83
+ ```
84
+
85
+ Project-local generic install:
86
+
87
+ ```bash
88
+ npx @aholbreich/agent-skills --target project-agents
89
+ ```
90
+
91
+ ### Custom skills directory
92
+
93
+ ```bash
94
+ npx @aholbreich/agent-skills install --dir /path/to/skills
95
+ ```
96
+
97
+ ## Discoverability
98
+
99
+ The package is tagged for discovery with npm keywords including:
100
+
101
+ - `pi-package`
102
+ - `agent-skills`
103
+ - `agent-skill`
104
+ - `agentskills`
105
+ - `skills.sh`
106
+ - `claude-code`
107
+ - `codex`
108
+
109
+ After publishing to npm, tools and indexes that crawl npm packages for Agent Skills-compatible packages, such as skills registries, should be able to discover the package from its package metadata and conventional `skills/` directory.
110
+
111
+ If a registry requires manual submission, use:
112
+
113
+ ```text
114
+ Package: @aholbreich/agent-skills
115
+ Repository: https://github.com/aholbreich/agent-skills
116
+ Skills directory: skills/
117
+ ```
118
+
119
+ ## Compliance checks in this repo
120
+
121
+ CI runs:
122
+
123
+ ```bash
124
+ pnpm run ci
125
+ ```
126
+
127
+ That includes:
128
+
129
+ - JavaScript syntax checks.
130
+ - Unit tests.
131
+ - Skill frontmatter compliance checks.
132
+ - `pnpm pack --dry-run` package content check.
133
+
134
+ The compliance tests are intentionally local and dependency-free; they validate the parts of the Agent Skills structure that matter for broad tool compatibility.
@@ -0,0 +1,53 @@
1
+ # Contributing
2
+
3
+ Thanks for improving this skill collection.
4
+
5
+ ## Development setup
6
+
7
+ Requirements:
8
+
9
+ - Node.js 22+
10
+ - Chrome/Chromium for manual end-to-end testing
11
+ - Pi if you want to test skill discovery
12
+
13
+ Run checks and tests:
14
+
15
+ ```bash
16
+ pnpm run check
17
+ pnpm test
18
+ pnpm run ci
19
+ ```
20
+
21
+ ## Skill guidelines
22
+
23
+ - Keep skills self-contained under `skills/<skill-name>/`.
24
+ - `SKILL.md` frontmatter `name` must match the directory name.
25
+ - Prefer no runtime dependencies. If dependencies are needed, add them to `package.json`.
26
+ - Do not commit fetched `raw/` data, browser profiles, cookies, tokens, customer data, or logs.
27
+ - Keep scripts read-only unless the skill is explicitly meant to modify external systems.
28
+ - Document safety assumptions in the skill and in `SECURITY.md` if relevant.
29
+
30
+ ## Testing browser fetchers
31
+
32
+ Use a test Atlassian site or non-confidential page/issue when possible.
33
+
34
+ ```bash
35
+ ./skills/jira-browser-fetch/scripts/jira-browser-fetch.js PROJ-123 \
36
+ --server https://example.atlassian.net \
37
+ --raw-dir ./raw-test
38
+
39
+ ./skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js 123456 \
40
+ --site https://example.atlassian.net \
41
+ --raw-dir ./raw-test
42
+ ```
43
+
44
+ Then delete local test exports before committing.
45
+
46
+ ## Release checklist
47
+
48
+ 1. `pnpm run ci`
49
+ 2. update `CHANGELOG.md`
50
+ 3. bump `package.json` version
51
+ 4. commit changes
52
+ 5. tag release, e.g. `v0.1.0`
53
+ 6. push tag
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alexander Holbreich
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,244 @@
1
+ # Agent Skills
2
+
3
+ Handcrafted [Agent Skills](https://agentskills.io/) for developer and LLM-wiki workflows. The package is intentionally a pure skills package with broad compatibility across Pi, Claude Code, Codex, OpenClaw/generic `.agents` setups, and other Agent Skills-compatible harnesses.
4
+
5
+ This repository is a pure skills package. It currently contains browser-authenticated Atlassian fetchers that work well when Jira/Confluence API-token authentication is unavailable because an organization uses Microsoft/SSO.
6
+
7
+ ## Skills
8
+
9
+ | Skill | Purpose |
10
+ |---|---|
11
+ | [`jira-browser-fetch`](skills/jira-browser-fetch/) | Fetch Jira issue JSON, rendered HTML/XML, linked/referenced issues, JQL result sets, and attachments through an authenticated Chrome session. |
12
+ | [`confluence-browser-fetch`](skills/confluence-browser-fetch/) | Fetch Confluence page JSON, storage/view HTML, browser HTML, descendants, CQL result sets, and attachments through an authenticated Chrome session. |
13
+
14
+ ## Compatibility
15
+
16
+ This repository follows the Agent Skills directory convention: each skill lives under `skills/<skill-name>/SKILL.md` with matching frontmatter.
17
+
18
+ Supported install targets:
19
+
20
+ | Target | Command |
21
+ |---|---|
22
+ | Pi | `pi install npm:@aholbreich/agent-skills` |
23
+ | Pi via npx | `npx @aholbreich/agent-skills --target pi` |
24
+ | Claude Code-style global skills | `npx @aholbreich/agent-skills --target claude` |
25
+ | Codex-style global skills | `npx @aholbreich/agent-skills --target codex` |
26
+ | OpenClaw / generic `.agents/skills` | `npx @aholbreich/agent-skills --target agents` |
27
+ | Project-local generic skills | `npx @aholbreich/agent-skills --target project-agents` |
28
+
29
+ See [`COMPATIBILITY.md`](COMPATIBILITY.md) for details.
30
+
31
+ ## Requirements
32
+
33
+ - Node.js `>=22`.
34
+ - Google Chrome or Chromium.
35
+ - Access to the Jira/Confluence site in the browser account you use.
36
+ - Pi, or any Agent Skills-compatible harness, if you want skill discovery.
37
+
38
+ No npm runtime dependencies are required.
39
+
40
+ ## Install with Pi
41
+
42
+ From GitHub:
43
+
44
+ ```bash
45
+ pi install git:github.com/aholbreich/agent-skills
46
+ ```
47
+
48
+ Project-local install, useful for teams:
49
+
50
+ ```bash
51
+ pi install -l git:github.com/aholbreich/agent-skills
52
+ ```
53
+
54
+ Try without installing:
55
+
56
+ ```bash
57
+ pi -e git:github.com/aholbreich/agent-skills
58
+ ```
59
+
60
+ ## One-shot install with npx
61
+
62
+ Install bundled skills into the generic Agent Skills directory `~/.agents/skills`:
63
+
64
+ ```bash
65
+ npx @aholbreich/agent-skills
66
+ ```
67
+
68
+ This is equivalent to:
69
+
70
+ ```bash
71
+ npx @aholbreich/agent-skills --target agents
72
+ ```
73
+
74
+ Install into a project-local `.pi/skills` directory:
75
+
76
+ ```bash
77
+ npx @aholbreich/agent-skills install --target project
78
+ ```
79
+
80
+ Install for Claude Code, Codex, or generic Agent Skills harnesses:
81
+
82
+ ```bash
83
+ npx @aholbreich/agent-skills install --target claude
84
+ npx @aholbreich/agent-skills install --target codex
85
+ npx @aholbreich/agent-skills install --target agents
86
+ ```
87
+
88
+ Overwrite existing installed skill directories:
89
+
90
+ ```bash
91
+ npx @aholbreich/agent-skills install --target agents --force
92
+ ```
93
+
94
+ List bundled skills:
95
+
96
+ ```bash
97
+ npx @aholbreich/agent-skills list
98
+ ```
99
+
100
+ ## Manual install
101
+
102
+ ```bash
103
+ git clone https://github.com/aholbreich/agent-skills.git
104
+ mkdir -p ~/.pi/agent/skills
105
+ cp -a agent-skills/skills/* ~/.pi/agent/skills/
106
+ ```
107
+
108
+ Optional command symlinks:
109
+
110
+ ```bash
111
+ mkdir -p ~/.local/bin
112
+ ln -sf ~/.pi/agent/skills/jira-browser-fetch/scripts/jira-browser-fetch.js ~/.local/bin/jira-browser-fetch
113
+ ln -sf ~/.pi/agent/skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js ~/.local/bin/confluence-browser-fetch
114
+ ```
115
+
116
+ ## npm-style command use from checkout
117
+
118
+ From this repository:
119
+
120
+ ```bash
121
+ pnpm run check
122
+ ./skills/jira-browser-fetch/scripts/jira-browser-fetch.js --help
123
+ ./skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js --help
124
+ ```
125
+
126
+ If installed globally via npm, the package exposes:
127
+
128
+ ```bash
129
+ agent-skills
130
+ jira-browser-fetch
131
+ confluence-browser-fetch
132
+ ```
133
+
134
+ ## Jira examples
135
+
136
+ Fetch one issue:
137
+
138
+ ```bash
139
+ jira-browser-fetch PROJ-123 \
140
+ --server https://example.atlassian.net \
141
+ --raw-dir ./raw
142
+ ```
143
+
144
+ Fetch linked/referenced tickets too:
145
+
146
+ ```bash
147
+ jira-browser-fetch PROJ-123 \
148
+ --server https://example.atlassian.net \
149
+ --raw-dir ./raw \
150
+ --connected \
151
+ --scan-text \
152
+ --depth 1
153
+ ```
154
+
155
+ Fetch all issues assigned to the current Jira user:
156
+
157
+ ```bash
158
+ jira-browser-fetch \
159
+ --server https://example.atlassian.net \
160
+ --raw-dir ./raw \
161
+ --assignee-me
162
+ ```
163
+
164
+ Fetch a JQL result set:
165
+
166
+ ```bash
167
+ jira-browser-fetch \
168
+ --server https://example.atlassian.net \
169
+ --raw-dir ./raw \
170
+ --jql 'assignee = currentUser() ORDER BY updated DESC'
171
+ ```
172
+
173
+ ## Confluence examples
174
+
175
+ Fetch one page by URL:
176
+
177
+ ```bash
178
+ confluence-browser-fetch \
179
+ 'https://example.atlassian.net/wiki/spaces/ABC/pages/123456/Page+Title' \
180
+ --site https://example.atlassian.net \
181
+ --raw-dir ./raw
182
+ ```
183
+
184
+ Fetch a page and all descendants:
185
+
186
+ ```bash
187
+ confluence-browser-fetch 123456 \
188
+ --site https://example.atlassian.net \
189
+ --raw-dir ./raw \
190
+ --descendants
191
+ ```
192
+
193
+ Fetch by CQL:
194
+
195
+ ```bash
196
+ confluence-browser-fetch \
197
+ --site https://example.atlassian.net \
198
+ --raw-dir ./raw \
199
+ --cql 'space = ABC and type = page and text ~ "billing"'
200
+ ```
201
+
202
+ ## Attachment size limits
203
+
204
+ Both fetchers default to skipping attachment downloads larger than `5mb`. Skipped files are still referenced in `attachments.json` with filename, URL, size, and reason.
205
+
206
+ ```bash
207
+ jira-browser-fetch PROJ-123 --server https://example.atlassian.net --max-attachment-size 1mb
208
+ confluence-browser-fetch 123456 --site https://example.atlassian.net --max-attachment-size 10mb
209
+ ```
210
+
211
+ Disable the limit:
212
+
213
+ ```bash
214
+ --max-attachment-size unlimited
215
+ ```
216
+
217
+ ## Output and LLM wiki use
218
+
219
+ The tools are designed to populate a wiki `raw/` folder. They do not synthesize pages themselves. A typical LLM wiki workflow is:
220
+
221
+ 1. fetch Jira/Confluence sources into `raw/`,
222
+ 2. treat `raw/` as immutable evidence,
223
+ 3. synthesize durable notes into `wiki/`,
224
+ 4. cite raw paths from wiki pages.
225
+
226
+ ## Security
227
+
228
+ Read [`SECURITY.md`](SECURITY.md). Do not commit fetched `raw/` exports or browser profiles.
229
+
230
+ ## Development
231
+
232
+ Run syntax checks and tests:
233
+
234
+ ```bash
235
+ pnpm run check
236
+ pnpm test
237
+ pnpm run ci
238
+ ```
239
+
240
+ Tests use Node's built-in test runner and cover pure helper logic plus CLI smoke/error paths. Package validation is intentionally lightweight because the scripts have no runtime npm dependencies.
241
+
242
+ ## License
243
+
244
+ MIT. See [`LICENSE`](LICENSE).
package/SECURITY.md ADDED
@@ -0,0 +1,42 @@
1
+ # Security Policy
2
+
3
+ ## Read this before installing or running
4
+
5
+ These skills are local automation tools. They can fetch potentially sensitive Jira and Confluence data into your filesystem.
6
+
7
+ ## Browser authentication model
8
+
9
+ The Jira and Confluence fetchers:
10
+
11
+ 1. launch or reuse Chrome/Chromium with a dedicated local profile,
12
+ 2. let you complete normal Atlassian SSO in the browser,
13
+ 3. read Atlassian cookies through the local Chrome DevTools protocol,
14
+ 4. call Atlassian REST endpoints with those cookies.
15
+
16
+ They do **not** require you to paste API tokens or cookies into chat.
17
+
18
+ ## Important precautions
19
+
20
+ - Do not paste Atlassian cookies, API tokens, passwords, or session headers into prompts, issues, logs, or commits.
21
+ - Treat everything under `raw/` as confidential unless you know it is public.
22
+ - Do not commit fetched Jira/Confluence exports or attachments to a public repository.
23
+ - Review generated `attachments.json` manifests before sharing; they may contain private URLs and filenames.
24
+ - Chrome remote debugging is configured for `127.0.0.1`; do not expose it to a network interface.
25
+ - Use dedicated browser profiles for fetch automation.
26
+ - The default attachment download cap is `5mb`; skipped large attachments are still referenced in `attachments.json`.
27
+
28
+ ## Attachment size limits
29
+
30
+ Both fetchers support:
31
+
32
+ ```bash
33
+ --max-attachment-size 5mb
34
+ --max-attachment-size 500kb
35
+ --max-attachment-size unlimited
36
+ ```
37
+
38
+ Large skipped files remain documented in `attachments.json` with filename, URL, size, and skip reason.
39
+
40
+ ## Reporting security issues
41
+
42
+ If you find a vulnerability, please open a private security advisory on GitHub if available, or contact the repository owner directly. Do not publish exploit details before there is a fix or mitigation.
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const fsp = require('fs/promises');
6
+ const os = require('os');
7
+ const path = require('path');
8
+
9
+ const packageRoot = path.resolve(__dirname, '..');
10
+ const sourceSkillsDir = path.join(packageRoot, 'skills');
11
+
12
+ const TARGETS = {
13
+ pi: path.join(os.homedir(), '.pi/agent/skills'),
14
+ agents: path.join(os.homedir(), '.agents/skills'),
15
+ claude: path.join(os.homedir(), '.claude/skills'),
16
+ codex: path.join(os.homedir(), '.codex/skills'),
17
+ openclaw: path.join(os.homedir(), '.agents/skills'),
18
+ project: path.join(process.cwd(), '.pi/skills'),
19
+ 'project-pi': path.join(process.cwd(), '.pi/skills'),
20
+ 'project-agents': path.join(process.cwd(), '.agents/skills'),
21
+ 'project-claude': path.join(process.cwd(), '.claude/skills'),
22
+ 'project-codex': path.join(process.cwd(), '.codex/skills'),
23
+ };
24
+
25
+ function usage() {
26
+ console.log(`Usage: agent-skills [command] [options]
27
+
28
+ Install this package's Agent Skills into a local skills directory.
29
+
30
+ Commands:
31
+ install Install skills (default command)
32
+ list List bundled skills
33
+ paths Show target install paths
34
+ help Show this help
35
+
36
+ Options for install:
37
+ --target NAME pi | agents | claude | codex | openclaw | project | project-agents | project-claude | project-codex (default: agents)
38
+ --dir PATH Custom skills directory, overrides --target
39
+ --force Overwrite existing skill directories
40
+ --dry-run Show what would be copied without writing
41
+
42
+ Examples:
43
+ npx @aholbreich/agent-skills
44
+ npx @aholbreich/agent-skills install --target agents --force
45
+ npx @aholbreich/agent-skills install --target pi --force
46
+ npx @aholbreich/agent-skills install --target project
47
+ npx @aholbreich/agent-skills install --target claude
48
+ npx @aholbreich/agent-skills install --target codex
49
+ npx @aholbreich/agent-skills install --target agents
50
+ npx @aholbreich/agent-skills install --dir ~/.pi/agent/skills
51
+ npx @aholbreich/agent-skills list
52
+
53
+ Pi-native install is also supported:
54
+ pi install npm:@aholbreich/agent-skills
55
+ `);
56
+ }
57
+
58
+ async function listSkills() {
59
+ const entries = await fsp.readdir(sourceSkillsDir, { withFileTypes: true });
60
+ return entries
61
+ .filter(e => e.isDirectory() && fs.existsSync(path.join(sourceSkillsDir, e.name, 'SKILL.md')))
62
+ .map(e => e.name)
63
+ .sort();
64
+ }
65
+
66
+ function expandHome(p) {
67
+ if (!p) return p;
68
+ if (p === '~') return os.homedir();
69
+ if (p.startsWith('~/')) return path.join(os.homedir(), p.slice(2));
70
+ return p;
71
+ }
72
+
73
+ async function copyDir(src, dest) {
74
+ await fsp.cp(src, dest, { recursive: true, force: true, errorOnExist: false });
75
+ }
76
+
77
+ async function install(args) {
78
+ let target = 'agents';
79
+ let customDir = '';
80
+ let force = false;
81
+ let dryRun = false;
82
+
83
+ for (let i = 0; i < args.length; i++) {
84
+ const a = args[i];
85
+ if (a === '--target') target = args[++i];
86
+ else if (a === '--dir') customDir = args[++i];
87
+ else if (a === '--force') force = true;
88
+ else if (a === '--dry-run') dryRun = true;
89
+ else if (a === '-h' || a === '--help') { usage(); return; }
90
+ else throw new Error(`Unknown install option: ${a}`);
91
+ }
92
+
93
+ if (!customDir && !TARGETS[target]) {
94
+ throw new Error(`Unknown target '${target}'. Valid targets: ${Object.keys(TARGETS).join(', ')}`);
95
+ }
96
+
97
+ const destRoot = path.resolve(expandHome(customDir || TARGETS[target]));
98
+ const skills = await listSkills();
99
+
100
+ console.log(`Installing ${skills.length} skill(s) to ${destRoot}`);
101
+ if (dryRun) console.log('Dry run: no files will be written.');
102
+
103
+ if (!dryRun) await fsp.mkdir(destRoot, { recursive: true });
104
+
105
+ let installed = 0;
106
+ let skipped = 0;
107
+ for (const skill of skills) {
108
+ const src = path.join(sourceSkillsDir, skill);
109
+ const dest = path.join(destRoot, skill);
110
+ const exists = fs.existsSync(dest);
111
+ if (exists && !force) {
112
+ console.log(`SKIP ${skill} (already exists; use --force to overwrite)`);
113
+ skipped++;
114
+ continue;
115
+ }
116
+ console.log(`${exists ? 'OVERWRITE' : 'INSTALL'} ${skill}`);
117
+ if (!dryRun) {
118
+ if (exists) await fsp.rm(dest, { recursive: true, force: true });
119
+ await copyDir(src, dest);
120
+ }
121
+ installed++;
122
+ }
123
+
124
+ console.log(`Done. Installed: ${installed}. Skipped: ${skipped}.`);
125
+ if (target.startsWith('project') && !customDir) {
126
+ console.log('Project-local skills are available when running an Agent Skills-compatible tool inside this project.');
127
+ } else if (target === 'pi' && !customDir) {
128
+ console.log('Restart Pi or start a new session to discover newly installed skills.');
129
+ }
130
+ }
131
+
132
+ async function showPaths() {
133
+ for (const [name, p] of Object.entries(TARGETS)) console.log(`${name.padEnd(8)} ${p}`);
134
+ }
135
+
136
+ async function main() {
137
+ const [cmdRaw, ...rest] = process.argv.slice(2);
138
+ const cmd = cmdRaw || 'install';
139
+
140
+ if (cmd === 'help' || cmd === '-h' || cmd === '--help') return usage();
141
+ if (cmd === 'install') return install(rest);
142
+ if (cmd === 'list') {
143
+ for (const skill of await listSkills()) console.log(skill);
144
+ return;
145
+ }
146
+ if (cmd === 'paths') return showPaths();
147
+
148
+ // Support `npx @aholbreich/agent-skills --target project` as shorthand for install.
149
+ if (cmd.startsWith('-')) return install([cmd, ...rest]);
150
+
151
+ throw new Error(`Unknown command: ${cmd}`);
152
+ }
153
+
154
+ main().catch(err => {
155
+ console.error(`ERROR: ${err.message}`);
156
+ process.exit(1);
157
+ });