@gifflet/ccmd 1.0.0 → 1.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/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # ccmd - Claude Command Manager
2
+
3
+ [![Go Version](https://img.shields.io/badge/Go-1.23+-00ADD8.svg)](https://go.dev)
4
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
5
+ [![Go Report Card](https://goreportcard.com/badge/github.com/gifflet/ccmd)](https://goreportcard.com/report/github.com/gifflet/ccmd)
6
+ [![NPM](https://nodei.co/npm/@gifflet/ccmd.svg?style=mini)](https://www.npmjs.com/package/@gifflet/ccmd)
7
+ [![Sponsor](https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors&color=5c5c5c)](https://github.com/sponsors/gifflet)
8
+
9
+ Simple command-line tool for managing custom commands in Claude Code. Install and share commands from Git repositories with the ease of a package manager.
10
+
11
+ ## Why ccmd?
12
+
13
+ Managing custom Claude Code commands across multiple projects can be challenging. ccmd solves this by treating commands as versioned, reusable packages:
14
+
15
+ - **Keep commands out of your codebase**: Store command definitions (.md files and AI context) in separate repositories, keeping your project repositories clean
16
+ - **Version control**: Each command has its own version, allowing you to use different versions in different projects
17
+ - **Reusability**: Install the same command in multiple projects without duplication
18
+ - **Easy sharing**: Share commands with your team or the community through Git repositories
19
+ - **Simple management**: Install, update, and remove commands with familiar package manager semantics
20
+
21
+ Think of ccmd as "npm for Claude Code commands" - centralize your AI tooling configurations and use them anywhere.
22
+
23
+ ## Installation
24
+
25
+ ### Via NPM (Recommended)
26
+
27
+ ```bash
28
+ npm install -g @gifflet/ccmd
29
+ ```
30
+
31
+ ### Via Go
32
+
33
+ ```bash
34
+ go install github.com/gifflet/ccmd/cmd/ccmd@latest
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### 1. Initialize your project
40
+ ```bash
41
+ cd your-project
42
+ ccmd init
43
+ ```
44
+
45
+ ### 2. Install a demo command
46
+ ```bash
47
+ ccmd install gifflet/hello-world
48
+ ```
49
+
50
+ ### 3. Use it in Claude Code
51
+ ```
52
+ /hello-world
53
+ ```
54
+
55
+ That's it! You've just installed and used your first ccmd command.
56
+
57
+ ## Commands
58
+
59
+ | Command | Description |
60
+ |---------|-------------|
61
+ | `ccmd init` | Initialize a new command project |
62
+ | `ccmd install <repo>` | Install a command from a Git repository |
63
+ | `ccmd install` | Install all commands from ccmd.yaml |
64
+ | `ccmd list` | List installed commands |
65
+ | `ccmd update <command>` | Update a specific command |
66
+ | `ccmd remove <command>` | Remove an installed command |
67
+ | `ccmd search <keyword>` | Search for commands in the registry |
68
+ | `ccmd info <command>` | Show detailed command information |
69
+
70
+ > For detailed usage and options, see [commands reference](docs/commands.md)
71
+
72
+ ## Creating Your Own Commands
73
+
74
+ Creating a command for ccmd is simple. Your repository needs:
75
+
76
+ 1. **ccmd.yaml** - Command metadata (created by `ccmd init`)
77
+ 2. **index.md** - Command instructions for Claude
78
+
79
+ ### Quick Start
80
+
81
+ ```bash
82
+ mkdir my-command && cd my-command
83
+ ccmd init # Creates ccmd.yaml interactively
84
+ ```
85
+
86
+ ### Example Structure
87
+
88
+ ```
89
+ my-command/
90
+ ├── ccmd.yaml # Command metadata (required)
91
+ └── index.md # Command for Claude (required)
92
+ ```
93
+
94
+ ### Example ccmd.yaml
95
+
96
+ ```yaml
97
+ name: my-command
98
+ version: 1.0.0
99
+ description: Automates tasks in Claude Code
100
+ author: Your Name
101
+ repository: https://github.com/username/my-command
102
+ entry: index.md # Optional, defaults to index.md
103
+ ```
104
+
105
+ > For complete guide with examples, see [Creating Commands](docs/creating-commands.md)
106
+
107
+ ## Example Commands
108
+
109
+ Here are some commands you can install and try:
110
+
111
+ - **hello-world**: Simple demo command
112
+ ```bash
113
+ ccmd install https://github.com/gifflet/hello-world
114
+ ```
115
+
116
+ ## Documentation
117
+
118
+ - **[Full Documentation](docs/)** - Complete guides and references
119
+ - **[Command Creation Guide](docs/creating-commands.md)** - Create your own commands
120
+
121
+ ## Community
122
+
123
+ - **Issues**: [GitHub Issues](https://github.com/gifflet/ccmd/issues)
124
+ - **Discussions**: [GitHub Discussions](https://github.com/gifflet/ccmd/discussions)
125
+ - **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md)
126
+
127
+ ## License
128
+
129
+ MIT License - see [LICENSE](LICENSE) for details
package/index.js CHANGED
@@ -22,7 +22,7 @@ let fullPath = null;
22
22
  /**
23
23
  * @return {Promise<string>}
24
24
  */
25
- export async function findCcmdBinary() {
25
+ async function findCcmdBinary() {
26
26
  if (fullPath) {
27
27
  // return the previously cached value
28
28
  return fullPath;
@@ -66,6 +66,8 @@ async function main() {
66
66
  }
67
67
 
68
68
 
69
+ module.exports = { findCcmdBinary };
70
+
69
71
  if (require.main === module) {
70
72
  (async () => await main())();
71
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gifflet/ccmd",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Simple command-line tool for managing custom commands in Claude Code. Install and share commands from Git repositories with the ease of a package manager.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/postinstall.js CHANGED
@@ -45,8 +45,6 @@ async function getInstallationPath() {
45
45
  } else {
46
46
  dir = value.trim();
47
47
  }
48
- //throw (dir)
49
- ///Users/danielpaulus/.nvm/versions/node/v19.7.0/lib/node_modules/go-ios/node_modules/.bin
50
48
  await mkdirp(dir);
51
49
  return dir;
52
50
  }
@@ -152,12 +150,11 @@ async function install(callback) {
152
150
  src = `./dist/ccmd-${PLATFORM_MAPPING[process.platform]}-amd64_${PLATFORM_MAPPING[process.platform]}_amd64/${opts.binName}`;
153
151
  }
154
152
 
155
- if (PLATFORM_MAPPING[process.platform] === "windows") {
156
- let cmd = `copy ${src} ${opts.binPath}/${opts.binName}`
157
- cmd = cmd.replace(/\//g, "\\")
158
- await execShellCommand(cmd);
159
- } else {
160
- await execShellCommand(`cp ${src} ${opts.binPath}/${opts.binName}`);
153
+ const dest = path.join(opts.binPath, opts.binName);
154
+ try {
155
+ await fs.promises.copyFile(src, dest);
156
+ } catch (err) {
157
+ return callback(`Failed to copy binary: ${err.message}`);
161
158
  }
162
159
 
163
160
  await verifyAndPlaceBinary(opts.binName, opts.binPath, callback);
@@ -185,22 +182,6 @@ var actions = {
185
182
  "install": install,
186
183
  "uninstall": uninstall
187
184
  };
188
- /**
189
- * Executes a shell command and return it as a Promise.
190
- * @param cmd {string}
191
- * @return {Promise<string>}
192
- */
193
- function execShellCommand(cmd) {
194
- const exec = require('child_process').exec;
195
- return new Promise((resolve, reject) => {
196
- exec(cmd, (error, stdout, stderr) => {
197
- if (error) {
198
- console.warn(error);
199
- }
200
- resolve(stdout ? stdout : stderr);
201
- });
202
- });
203
- }
204
185
 
205
186
  var argv = process.argv;
206
187
  if (argv && argv.length > 2) {