agentic-skill-mill 1.0.3 → 1.0.4

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,265 @@
1
+ #!/usr/bin/env bash
2
+ # install-local.sh -- Local project setup: build companion CLI + install skills for AI coding tools
3
+ # Run from the project root: bash install-local.sh [--claude] [--cursor] [--windsurf] [--opencode] [--codex] [--all]
4
+ # No flags = auto-detect installed tools
5
+
6
+ set -e
7
+
8
+ # ===========================================================================
9
+ # CONFIGURE: Change these values for your project
10
+ # ===========================================================================
11
+
12
+ PROJECT_NAME="agentic-skill-mill" # Used in log messages
13
+ CLI_BIN_NAME="skillmill" # The bin name from package.json
14
+ MANAGED_MARKER="managed_by: agentic-skill-mill" # Must match compile.mjs MANAGED_BY
15
+ SKILLS=("agentic-skill-mill") # All skill names from manifest.json
16
+
17
+ # ===========================================================================
18
+ # End configuration
19
+ # ===========================================================================
20
+
21
+ SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
22
+
23
+ # --- Target directories ---
24
+ CLAUDE_SKILLS_DIR="$HOME/.claude/skills"
25
+ CURSOR_RULES_DIR="$HOME/.cursor/rules"
26
+ CURSOR_SKILLS_DIR="$HOME/.cursor/skills"
27
+ WINDSURF_RULES_DIR="$HOME/.windsurf/rules"
28
+ WINDSURF_SKILLS_DIR="$HOME/.codeium/windsurf/skills"
29
+ OPENCODE_AGENTS_DIR="$HOME/.config/opencode/agents"
30
+ CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
31
+ CODEX_SKILLS_DIR="$CODEX_HOME_DIR/skills"
32
+
33
+ # --- Stale file cleanup (marker-based) ---
34
+
35
+ cleanup_managed() {
36
+ local dir="$1"
37
+ [[ -d "$dir" ]] || return 0
38
+ grep -rl "$MANAGED_MARKER" "$dir" 2>/dev/null | while read -r f; do
39
+ rm -f "$f"
40
+ local parent; parent="$(dirname "$f")"
41
+ [[ "$parent" != "$dir" ]] && rmdir "$parent" 2>/dev/null || true
42
+ echo " Removed: $f"
43
+ done
44
+ }
45
+
46
+ # --- Install functions (copy from compiled/ output) ---
47
+
48
+ COMPILED_DIR="$SKILL_DIR/compiled"
49
+
50
+ install_claude() {
51
+ local skill_name="$1"
52
+ local src="$COMPILED_DIR/claude/${skill_name}/SKILL.md"
53
+ local dest_dir="$CLAUDE_SKILLS_DIR/${skill_name}"
54
+ mkdir -p "$dest_dir"
55
+ cp "$src" "$dest_dir/SKILL.md"
56
+ echo " Claude: $dest_dir/SKILL.md"
57
+ }
58
+
59
+ install_cursor() {
60
+ local skill_name="$1"
61
+ local src="$COMPILED_DIR/cursor/rules/${skill_name}.mdc"
62
+ mkdir -p "$CURSOR_RULES_DIR"
63
+ cp "$src" "$CURSOR_RULES_DIR/${skill_name}.mdc"
64
+ echo " Cursor (rule): $CURSOR_RULES_DIR/${skill_name}.mdc"
65
+ local src2="$COMPILED_DIR/cursor/skills/${skill_name}/SKILL.md"
66
+ local dest_dir="$CURSOR_SKILLS_DIR/${skill_name}"
67
+ mkdir -p "$dest_dir"
68
+ cp "$src2" "$dest_dir/SKILL.md"
69
+ echo " Cursor (skill): $dest_dir/SKILL.md"
70
+ }
71
+
72
+ install_windsurf() {
73
+ local skill_name="$1"
74
+ local src="$COMPILED_DIR/windsurf/rules/${skill_name}.md"
75
+ mkdir -p "$WINDSURF_RULES_DIR"
76
+ cp "$src" "$WINDSURF_RULES_DIR/${skill_name}.md"
77
+ echo " Windsurf (rule): $WINDSURF_RULES_DIR/${skill_name}.md"
78
+ local src2="$COMPILED_DIR/windsurf/skills/${skill_name}/SKILL.md"
79
+ local dest_dir="$WINDSURF_SKILLS_DIR/${skill_name}"
80
+ mkdir -p "$dest_dir"
81
+ cp "$src2" "$dest_dir/SKILL.md"
82
+ echo " Windsurf (skill): $dest_dir/SKILL.md"
83
+ }
84
+
85
+ install_opencode() {
86
+ local skill_name="$1"
87
+ local src="$COMPILED_DIR/opencode/${skill_name}.md"
88
+ mkdir -p "$OPENCODE_AGENTS_DIR"
89
+ cp "$src" "$OPENCODE_AGENTS_DIR/${skill_name}.md"
90
+ echo " OpenCode: $OPENCODE_AGENTS_DIR/${skill_name}.md"
91
+ }
92
+
93
+ install_codex() {
94
+ local skill_name="$1"
95
+ local src="$COMPILED_DIR/codex/${skill_name}/SKILL.md"
96
+ local dest_dir="$CODEX_SKILLS_DIR/${skill_name}"
97
+ mkdir -p "$dest_dir"
98
+ cp "$src" "$dest_dir/SKILL.md"
99
+ echo " Codex: $dest_dir/SKILL.md"
100
+ }
101
+
102
+ # --- Uninstall ---
103
+
104
+ uninstall_claude() { for skill in "${SKILLS[@]}"; do rm -rf "$CLAUDE_SKILLS_DIR/$skill"; done; echo " Claude: removed"; }
105
+ uninstall_cursor() { for skill in "${SKILLS[@]}"; do rm -f "$CURSOR_RULES_DIR/${skill}.mdc"; rm -rf "$CURSOR_SKILLS_DIR/$skill"; done; echo " Cursor: removed"; }
106
+ uninstall_windsurf() { for skill in "${SKILLS[@]}"; do rm -f "$WINDSURF_RULES_DIR/${skill}.md"; rm -rf "$WINDSURF_SKILLS_DIR/$skill"; done; echo " Windsurf: removed"; }
107
+ uninstall_opencode() { for skill in "${SKILLS[@]}"; do rm -f "$OPENCODE_AGENTS_DIR/${skill}.md"; done; echo " OpenCode: removed"; }
108
+ uninstall_codex() { for skill in "${SKILLS[@]}"; do rm -rf "$CODEX_SKILLS_DIR/$skill"; done; echo " Codex: removed"; }
109
+
110
+ # --- Auto-detection ---
111
+
112
+ detect_editors() {
113
+ local detected=()
114
+ [[ -d "$HOME/.claude" ]] && detected+=("claude")
115
+ [[ -d "$HOME/.cursor" ]] && detected+=("cursor")
116
+ [[ -d "$HOME/.windsurf" || -d "$HOME/.codeium/windsurf" ]] && detected+=("windsurf")
117
+ [[ -d "$HOME/.config/opencode" || -d "$HOME/.opencode" ]] && detected+=("opencode")
118
+ [[ -n "${CODEX_HOME:-}" || -d "$CODEX_HOME_DIR" ]] && detected+=("codex")
119
+ echo "${detected[@]}"
120
+ }
121
+
122
+ # --- CLI parsing ---
123
+
124
+ TARGETS=()
125
+ DO_BUILD=true
126
+ DO_UNINSTALL=false
127
+ DO_COMPILE_ONLY=false
128
+
129
+ while [[ $# -gt 0 ]]; do
130
+ case "$1" in
131
+ --claude) TARGETS+=("claude"); shift ;;
132
+ --cursor) TARGETS+=("cursor"); shift ;;
133
+ --windsurf) TARGETS+=("windsurf"); shift ;;
134
+ --opencode) TARGETS+=("opencode"); shift ;;
135
+ --codex) TARGETS+=("codex"); shift ;;
136
+ --all) TARGETS=("claude" "cursor" "windsurf" "opencode" "codex"); shift ;;
137
+ --skills-only) DO_BUILD=false; shift ;;
138
+ --uninstall) DO_UNINSTALL=true; shift ;;
139
+ --compile-only) DO_COMPILE_ONLY=true; shift ;;
140
+ --help|-h)
141
+ echo "Usage: bash install-local.sh [options]"
142
+ echo ""
143
+ echo "Options:"
144
+ echo " --claude Install skills for Claude Code"
145
+ echo " --cursor Install skills for Cursor"
146
+ echo " --windsurf Install skills for Windsurf"
147
+ echo " --opencode Install skills for OpenCode"
148
+ echo " --codex Install skills for Codex"
149
+ echo " --all Install for all five tools"
150
+ echo " --skills-only Skip npm install/build/link (just copy skills)"
151
+ echo " --uninstall Remove installed skills from target tools"
152
+ echo " --compile-only Generate compiled/ output directory (no install)"
153
+ echo " -h, --help Show this help"
154
+ echo ""
155
+ echo "No flags = auto-detect installed tools."
156
+ exit 0
157
+ ;;
158
+ *)
159
+ echo "Unknown option: $1"
160
+ echo "Run: bash install-local.sh --help"
161
+ exit 1
162
+ ;;
163
+ esac
164
+ done
165
+
166
+ # --- Compile-only path ---
167
+
168
+ if [[ "$DO_COMPILE_ONLY" == true ]]; then
169
+ echo "==> Delegating to compile.mjs..."
170
+ node "$SKILL_DIR/skill/build/compile.mjs"
171
+ exit $?
172
+ fi
173
+
174
+ # Auto-detect if no targets specified
175
+ if [[ ${#TARGETS[@]} -eq 0 ]]; then
176
+ read -ra TARGETS <<< "$(detect_editors)"
177
+ fi
178
+
179
+ if [[ ${#TARGETS[@]} -eq 0 ]]; then
180
+ echo "ERROR: No supported tools detected. Use --claude, --cursor, --windsurf, --opencode, or --codex."
181
+ exit 1
182
+ fi
183
+
184
+ # --- Uninstall path ---
185
+
186
+ if [[ "$DO_UNINSTALL" == true ]]; then
187
+ echo "==> Uninstalling $PROJECT_NAME"
188
+ echo " Targets: ${TARGETS[*]}"
189
+ echo ""
190
+ for target in "${TARGETS[@]}"; do
191
+ "uninstall_${target}"
192
+ done
193
+
194
+ echo "--> Removing $CLI_BIN_NAME CLI..."
195
+ npm unlink "$PROJECT_NAME" 2>/dev/null || true
196
+ hash -r 2>/dev/null || true
197
+ if command -v "$CLI_BIN_NAME" &>/dev/null; then
198
+ echo " WARNING: $CLI_BIN_NAME still in PATH at $(which "$CLI_BIN_NAME")"
199
+ else
200
+ echo " $CLI_BIN_NAME removed"
201
+ fi
202
+
203
+ echo ""
204
+ echo "==> Done. Skills and CLI removed."
205
+ exit 0
206
+ fi
207
+
208
+ # --- Install path ---
209
+
210
+ echo "==> $PROJECT_NAME setup"
211
+ echo " Project: $SKILL_DIR"
212
+ echo " Targets: ${TARGETS[*]}"
213
+ echo ""
214
+
215
+ if [[ "$DO_BUILD" == true ]]; then
216
+ echo "--> Installing dependencies..."
217
+ npm install
218
+
219
+ echo "--> Cleaning previous build..."
220
+ rm -rf "$SKILL_DIR/dist"
221
+
222
+ echo "--> Building TypeScript..."
223
+ npm run build
224
+ chmod +x "$SKILL_DIR/dist/cli/index.js"
225
+
226
+ echo "--> Compiling skills..."
227
+ npm run compile
228
+
229
+ echo "--> Installing $CLI_BIN_NAME CLI globally..."
230
+ npm link
231
+
232
+ NPM_BIN="$(npm prefix -g)/bin"
233
+ if [[ -x "$NPM_BIN/$CLI_BIN_NAME" ]]; then
234
+ echo " $CLI_BIN_NAME: $NPM_BIN/$CLI_BIN_NAME"
235
+ echo " version: $("$NPM_BIN/$CLI_BIN_NAME" --version 2>/dev/null || echo 'unknown')"
236
+ else
237
+ echo " WARNING: $CLI_BIN_NAME not found in $NPM_BIN after npm link."
238
+ echo " Try running: npm link"
239
+ fi
240
+ fi
241
+
242
+ echo "--> Cleaning stale $PROJECT_NAME files..."
243
+ for target in "${TARGETS[@]}"; do
244
+ case "$target" in
245
+ claude) cleanup_managed "$CLAUDE_SKILLS_DIR" ;;
246
+ cursor) cleanup_managed "$CURSOR_RULES_DIR"; cleanup_managed "$CURSOR_SKILLS_DIR" ;;
247
+ windsurf) cleanup_managed "$WINDSURF_RULES_DIR"; cleanup_managed "$WINDSURF_SKILLS_DIR" ;;
248
+ opencode) cleanup_managed "$OPENCODE_AGENTS_DIR" ;;
249
+ codex) cleanup_managed "$CODEX_SKILLS_DIR" ;;
250
+ esac
251
+ done
252
+
253
+ echo "--> Installing skills..."
254
+ for skill in "${SKILLS[@]}"; do
255
+ echo " ${skill}:"
256
+ for target in "${TARGETS[@]}"; do
257
+ "install_${target}" "$skill"
258
+ done
259
+ done
260
+
261
+ echo ""
262
+ echo "==> Done."
263
+ echo ""
264
+ echo "Skills installed for: ${TARGETS[*]}"
265
+ echo "CLI available as: $CLI_BIN_NAME"
package/install.sh ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # install.sh -- Remote-friendly bootstrap installer (for curl|bash use)
3
+ # Installs the npm package globally, then runs install-local.sh in skills-only mode.
4
+
5
+ set -euo pipefail
6
+
7
+ PACKAGE_NAME="${SKILLMILL_PACKAGE_NAME:-agentic-skill-mill}"
8
+ PACKAGE_VERSION="${SKILLMILL_PACKAGE_VERSION:-latest}"
9
+
10
+ if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
11
+ echo "Usage: bash install.sh [tool flags]"
12
+ echo ""
13
+ echo "This script installs ${PACKAGE_NAME}@${PACKAGE_VERSION} globally and then"
14
+ echo "runs install-local.sh --skills-only with the flags you provide."
15
+ echo ""
16
+ echo "Examples:"
17
+ echo " bash install.sh --all"
18
+ echo " bash install.sh --cursor"
19
+ echo ""
20
+ echo "Environment overrides:"
21
+ echo " SKILLMILL_PACKAGE_NAME Package to install (default: agentic-skill-mill)"
22
+ echo " SKILLMILL_PACKAGE_VERSION Version tag (default: latest)"
23
+ exit 0
24
+ fi
25
+
26
+ echo "==> Installing utility library: ${PACKAGE_NAME}@${PACKAGE_VERSION}"
27
+ npm install -g "${PACKAGE_NAME}@${PACKAGE_VERSION}"
28
+
29
+ GLOBAL_NODE_MODULES="$(npm root -g)"
30
+ PACKAGE_DIR="${GLOBAL_NODE_MODULES}/${PACKAGE_NAME}"
31
+ LOCAL_INSTALLER="${PACKAGE_DIR}/install-local.sh"
32
+
33
+ if [[ ! -f "$LOCAL_INSTALLER" ]]; then
34
+ echo "ERROR: Could not find install-local.sh at: $LOCAL_INSTALLER"
35
+ echo "Check the package 'files' list to ensure install-local.sh is published."
36
+ exit 1
37
+ fi
38
+
39
+ echo "==> Installing skills via local installer (skills-only mode)"
40
+ bash "$LOCAL_INSTALLER" --skills-only "$@"
41
+
42
+ echo ""
43
+ echo "==> Done."
44
+ echo "Utility and skills installed."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-skill-mill",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Forge and refine agent skill projects -- fragment-composed skills compiled to 7 IDE targets with a companion CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,8 +16,11 @@
16
16
  },
17
17
  "files": [
18
18
  "dist",
19
+ "compiled",
19
20
  "skill",
20
- "README.md"
21
+ "README.md",
22
+ "install.sh",
23
+ "install-local.sh"
21
24
  ],
22
25
  "scripts": {
23
26
  "build": "tsc -p tsconfig.build.json",
@@ -26,10 +29,10 @@
26
29
  "test:coverage": "vitest run --coverage",
27
30
  "lint": "eslint src",
28
31
  "typecheck": "tsc --noEmit",
29
- "setup": "bash install.sh",
30
- "setup:all": "bash install.sh --all",
31
- "install-skills": "bash install.sh --skills-only",
32
- "uninstall-skills": "bash install.sh --uninstall",
32
+ "setup": "bash install-local.sh",
33
+ "setup:all": "bash install-local.sh --all",
34
+ "install-skills": "bash install-local.sh --skills-only",
35
+ "uninstall-skills": "bash install-local.sh --uninstall",
33
36
  "compile": "node skill/build/compile.mjs",
34
37
  "compile:validate": "node skill/build/compile.mjs --validate",
35
38
  "compile:watch": "node skill/build/compile.mjs --watch"
@@ -25,7 +25,7 @@ Skills (what to do) CLI Companion (tools to do it with)
25
25
  - `src/errors/types.ts` — Typed error hierarchy (AppError, NotFoundError, etc.)
26
26
  - `src/cache/cache-manager.ts` — Two-tier cache (memory + disk) with TTL
27
27
 
28
- **The installer** (`install.sh`) builds the CLI, compiles skills, and copies compiled outputs to IDE-specific directories (~/.claude/skills, ~/.cursor/rules, etc.) with marker-based stale file cleanup. The installer uses `set -e` for fail-fast behavior. Any function that uses an early-exit guard (`[[ -d ... ]] || return`, `[[ -z ... ]] && return`) **must** use `return 0`, never bare `return`. Bare `return` inherits the exit code of the last command, which for a failed conditional test is 1 -- and `set -e` treats that as a script-terminating failure with no error message.
28
+ **The local installer** (`install-local.sh`) builds the CLI, compiles skills, and copies compiled outputs to IDE-specific directories (~/.claude/skills, ~/.cursor/rules, etc.) with marker-based stale file cleanup. The bootstrap installer (`install.sh`) is remote-friendly and installs the npm utility first, then delegates to `install-local.sh --skills-only`. Local installer functions use `set -e` for fail-fast behavior. Any function that uses an early-exit guard (`[[ -d ... ]] || return`, `[[ -z ... ]] && return`) **must** use `return 0`, never bare `return`. Bare `return` inherits the exit code of the last command, which for a failed conditional test is 1 -- and `set -e` treats that as a script-terminating failure with no error message.
29
29
 
30
30
  ### Key files to modify when augmenting a project
31
31
 
@@ -33,5 +33,5 @@ Skills (what to do) CLI Companion (tools to do it with)
33
33
  |------|---------|
34
34
  | Add a CLI command | `src/core/<name>.ts`, `src/cli/commands/<name>.ts`, `src/cli/index.ts`, `src/index.ts` |
35
35
  | Add a fragment | `skill/fragments/<category>/<name>.md`, `skill/build/manifest.json`, skill source |
36
- | Add a skill | `skill/skills/<name>/<name>.md`, `skill/build/manifest.json`, `install.sh` SKILLS array |
36
+ | Add a skill | `skill/skills/<name>/<name>.md`, `skill/build/manifest.json`, `install-local.sh` SKILLS array |
37
37
  | Rename the project | See the rename workflow |
@@ -22,7 +22,7 @@ When the project, skill, or CLI needs a new name, update all touchpoints in one
22
22
 
23
23
  4. **Compiler marker** (`skill/build/compile.mjs`) -- update the `MANAGED_BY` constant
24
24
 
25
- 5. **Installer** (`install.sh`) -- update `PROJECT_NAME`, `CLI_BIN_NAME`, `MANAGED_MARKER`, `SKILLS` array
25
+ 5. **Installer** (`install-local.sh`) -- update `PROJECT_NAME`, `CLI_BIN_NAME`, `MANAGED_MARKER`, `SKILLS` array
26
26
 
27
27
  6. **Package metadata** (`package.json`) -- update `name` and `bin` key
28
28
 
@@ -5,7 +5,7 @@ description: "Build, augment, and maintain skill projects that follow the skill-
5
5
 
6
6
  # Agentic Skill Mill
7
7
 
8
- Forge and refine skill projects that follow the skill-system-template architecture: fragment-composed skills compiled to multiple IDE targets, paired with a TypeScript companion CLI (`skillmill`) that provides structured commands for agents and humans.
8
+ Forge and refine skill projects that follow the skill-system-template architecture: fragment-composed skills compiled to multiple IDE targets, paired with a TypeScript companion CLI (`skillmill`) that provides structured commands for agents and humans. Prefer `npx --yes agentic-skill-mill@latest <command>` when the utility is not globally installed.
9
9
 
10
10
  ---
11
11
 
@@ -83,7 +83,7 @@ Direct content or more includes.
83
83
  Then register it:
84
84
 
85
85
  1. Add the skill entry to `skill/build/manifest.json` with its source path and fragment dependencies
86
- 2. Add the skill name to the `SKILLS` array in `install.sh`
86
+ 2. Add the skill name to the `SKILLS` array in `install-local.sh`
87
87
  3. Compile: `npm run compile`
88
88
 
89
89
  ### Step 8: If Renaming the Project
@@ -98,15 +98,15 @@ After any change, run the full verification sequence:
98
98
  npm run build # TypeScript CLI compiles cleanly
99
99
  npm run compile # Skills compile to all 7 IDE targets
100
100
  npm run compile:validate # Cross-validates manifest vs source includes
101
- node dist/cli/index.js --help # CLI shows expected commands
101
+ npx --yes agentic-skill-mill@latest --help # CLI command surface works via npx
102
102
  ```
103
103
 
104
104
  If adding a new CLI command, also verify it runs:
105
105
 
106
106
  ```bash
107
- node dist/cli/index.js <command> --help # Options are correct
108
- node dist/cli/index.js <command> <args> # Human output works
109
- node dist/cli/index.js <command> --json # JSON output works
107
+ npx --yes agentic-skill-mill@latest <command> --help # Options are correct
108
+ npx --yes agentic-skill-mill@latest <command> <args> # Human output works
109
+ npx --yes agentic-skill-mill@latest <command> --json # JSON output works
110
110
  ```
111
111
 
112
112
  ### Step 10: Commit
@@ -130,4 +130,4 @@ The commit body should list every file category changed (core modules, CLI wrapp
130
130
  - **Stale compiled outputs.** Always recompile after changing skills or fragments. Run `npm run compile:validate` to detect staleness.
131
131
  - **Partial renames.** When renaming, update every touchpoint in one pass (see rename workflow). A grep sweep with zero results confirms completeness.
132
132
  - **Missing --json support.** Every CLI command must support `--json` for structured agent consumption. Agents cannot parse chalk-colored terminal output.
133
- - **Bare `return` in `set -e` scripts.** In `install.sh`, never write `[[ condition ]] || return` or `grep ... || return`. Bare `return` inherits the exit code of the failed test (1), which `set -e` treats as fatal -- killing the script silently. Always use `return 0` for early-exit guards: `[[ -d "$dir" ]] || return 0`, `[[ -z "$var" ]] && return 0`.
133
+ - **Bare `return` in `set -e` scripts.** In `install-local.sh`, never write `[[ condition ]] || return` or `grep ... || return`. Bare `return` inherits the exit code of the failed test (1), which `set -e` treats as fatal -- killing the script silently. Always use `return 0` for early-exit guards: `[[ -d "$dir" ]] || return 0`, `[[ -z "$var" ]] && return 0`.