@gifflet/ccmd 1.0.0 → 1.1.1

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,131 @@
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
+ <img src="./docs/demo.gif" />
12
+
13
+ ## Why ccmd?
14
+
15
+ Managing custom Claude Code commands across multiple projects can be challenging. ccmd solves this by treating commands as versioned, reusable packages:
16
+
17
+ - **Keep commands out of your codebase**: Store command definitions (.md files and AI context) in separate repositories, keeping your project repositories clean
18
+ - **Version control**: Each command has its own version, allowing you to use different versions in different projects
19
+ - **Reusability**: Install the same command in multiple projects without duplication
20
+ - **Easy sharing**: Share commands with your team or the community through Git repositories
21
+ - **Simple management**: Install, update, and remove commands with familiar package manager semantics
22
+
23
+ Think of ccmd as "npm for Claude Code commands" - centralize your AI tooling configurations and use them anywhere.
24
+
25
+ ## Installation
26
+
27
+ ### Via NPM (Recommended)
28
+
29
+ ```bash
30
+ npm install -g @gifflet/ccmd
31
+ ```
32
+
33
+ ### Via Go
34
+
35
+ ```bash
36
+ go install github.com/gifflet/ccmd/cmd/ccmd@latest
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ### 1. Initialize your project
42
+ ```bash
43
+ cd your-project
44
+ ccmd init
45
+ ```
46
+
47
+ ### 2. Install a demo command
48
+ ```bash
49
+ ccmd install gifflet/hello-world
50
+ ```
51
+
52
+ ### 3. Use it in Claude Code
53
+ ```
54
+ /hello-world
55
+ ```
56
+
57
+ That's it! You've just installed and used your first ccmd command.
58
+
59
+ ## Commands
60
+
61
+ | Command | Description |
62
+ |---------|-------------|
63
+ | `ccmd init` | Initialize a new command project |
64
+ | `ccmd install <repo>` | Install a command from a Git repository |
65
+ | `ccmd install` | Install all commands from ccmd.yaml |
66
+ | `ccmd list` | List installed commands |
67
+ | `ccmd update <command>` | Update a specific command |
68
+ | `ccmd remove <command>` | Remove an installed command |
69
+ | `ccmd search <keyword>` | Search for commands in the registry |
70
+ | `ccmd info <command>` | Show detailed command information |
71
+
72
+ > For detailed usage and options, see [commands reference](docs/commands.md)
73
+
74
+ ## Creating Your Own Commands
75
+
76
+ Creating a command for ccmd is simple. Your repository needs:
77
+
78
+ 1. **ccmd.yaml** - Command metadata (created by `ccmd init`)
79
+ 2. **index.md** - Command instructions for Claude
80
+
81
+ ### Quick Start
82
+
83
+ ```bash
84
+ mkdir my-command && cd my-command
85
+ ccmd init # Creates ccmd.yaml interactively
86
+ ```
87
+
88
+ ### Example Structure
89
+
90
+ ```
91
+ my-command/
92
+ ├── ccmd.yaml # Command metadata (required)
93
+ └── index.md # Command for Claude (required)
94
+ ```
95
+
96
+ ### Example ccmd.yaml
97
+
98
+ ```yaml
99
+ name: my-command
100
+ version: 1.0.0
101
+ description: Automates tasks in Claude Code
102
+ author: Your Name
103
+ repository: https://github.com/username/my-command
104
+ entry: index.md # Optional, defaults to index.md
105
+ ```
106
+
107
+ > For complete guide with examples, see [Creating Commands](docs/creating-commands.md)
108
+
109
+ ## Example Commands
110
+
111
+ Here are some commands you can install and try:
112
+
113
+ - **hello-world**: Simple demo command
114
+ ```bash
115
+ ccmd install https://github.com/gifflet/hello-world
116
+ ```
117
+
118
+ ## Documentation
119
+
120
+ - **[Full Documentation](docs/)** - Complete guides and references
121
+ - **[Command Creation Guide](docs/creating-commands.md)** - Create your own commands
122
+
123
+ ## Community
124
+
125
+ - **Issues**: [GitHub Issues](https://github.com/gifflet/ccmd/issues)
126
+ - **Discussions**: [GitHub Discussions](https://github.com/gifflet/ccmd/discussions)
127
+ - **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md)
128
+
129
+ ## License
130
+
131
+ 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.1",
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) {