tools-cc 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.
- package/CHANGELOG.md +8 -0
- package/CHANGELOG_en.md +71 -0
- package/README_en.md +218 -0
- package/dist/core/project.js +2 -1
- package/package.json +3 -2
- package/src/core/project.ts +21 -20
package/CHANGELOG.md
CHANGED
package/CHANGELOG_en.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.4] - 2026-02-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Added English version of project documentation README_en.md
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Optimized project initialization and source synchronization logic
|
|
12
|
+
|
|
13
|
+
## [1.0.3] - 2026-02-26
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Changed project configuration file location from `tools-cc.json` to `.toolscc/config.json`
|
|
17
|
+
- Improved documentation command descriptions, clearly distinguishing global and project commands
|
|
18
|
+
|
|
19
|
+
## [1.0.2] - 2026-02-26
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- Added `tools-cc -s scan` command: scan sourcesDir directory to auto-discover and add configuration sources
|
|
23
|
+
- Added `tools-cc -s upgrade [name]` command alias: execute git pull to update configuration source code
|
|
24
|
+
- Added `tools-cc update [sources...]` command: sync configuration source content to project .toolscc directory
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Improved help documentation, added workflow guide and command comparison table
|
|
28
|
+
|
|
29
|
+
## [1.0.1] - 2026-02-25
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- Added package.json repository metadata (repository, bugs, homepage)
|
|
33
|
+
|
|
34
|
+
## [1.0.0] - 2026-02-25
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- Project initialization, built CLI framework based on TypeScript + Commander
|
|
38
|
+
- Global configuration management module
|
|
39
|
+
- `tools-cc -c set <key> <value>` set configuration
|
|
40
|
+
- `tools-cc -c get <key>` get configuration
|
|
41
|
+
- `tools-cc config list` view complete configuration
|
|
42
|
+
- Configuration source management module
|
|
43
|
+
- `tools-cc -s add <name> <path-or-url>` add configuration source (supports Git URL and local path)
|
|
44
|
+
- `tools-cc -s list` list all configuration sources
|
|
45
|
+
- `tools-cc -s remove <name>` remove configuration source
|
|
46
|
+
- `tools-cc -s update [name]` update configuration source (git pull)
|
|
47
|
+
- Project management module
|
|
48
|
+
- `tools-cc use [sources...]` enable configuration sources and create symbolic links
|
|
49
|
+
- `tools-cc list` list enabled configuration sources
|
|
50
|
+
- `tools-cc rm <source>` disable configuration source
|
|
51
|
+
- `tools-cc status` view project status
|
|
52
|
+
- Symbolic link management module (supports Windows Junction)
|
|
53
|
+
- Manifest loading and scanning module
|
|
54
|
+
- Bilingual help information (Chinese/English) (`tools-cc help`)
|
|
55
|
+
- Unit test coverage (vitest)
|
|
56
|
+
|
|
57
|
+
### Supported Tools
|
|
58
|
+
| Tool | Link Name |
|
|
59
|
+
|------|-----------|
|
|
60
|
+
| iflow | `.iflow` |
|
|
61
|
+
| claude | `.claude` |
|
|
62
|
+
| codebuddy | `.codebuddy` |
|
|
63
|
+
| opencode | `.opencode` |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Versioning
|
|
68
|
+
|
|
69
|
+
- **Major version**: Incompatible API changes
|
|
70
|
+
- **Minor version**: Backwards-compatible functionality additions
|
|
71
|
+
- **Patch version**: Backwards-compatible bug fixes
|
package/README_en.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# tools-cc
|
|
2
|
+
|
|
3
|
+
A CLI tool for unified management of skills/commands/agents configurations across multiple AI programming tools (iflow, claude, codebuddy, opencode, etc.). Uses symbolic links to avoid duplicate configurations across tools.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install from npm
|
|
9
|
+
npm install -g tools-cc
|
|
10
|
+
|
|
11
|
+
# Or build from source
|
|
12
|
+
git clone https://github.com/q759410559/tools-cc.git
|
|
13
|
+
cd tools-cc
|
|
14
|
+
npm install
|
|
15
|
+
npm run build
|
|
16
|
+
npm link
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# 1. Set configuration source storage location (optional, default is ~/.tools-cc/sources)
|
|
23
|
+
tools-cc -c set sourcesDir D:/skills-hub-sources
|
|
24
|
+
|
|
25
|
+
# 2. Add configuration sources (supports Git URL or local path)
|
|
26
|
+
tools-cc -s add my-skills https://github.com/user/my-skills.git
|
|
27
|
+
tools-cc -s add local-skills D:/path/to/local-skills
|
|
28
|
+
|
|
29
|
+
# Or scan source directory to auto-discover and add configurations
|
|
30
|
+
tools-cc -s scan
|
|
31
|
+
|
|
32
|
+
# 3. View added configuration sources
|
|
33
|
+
tools-cc -s list
|
|
34
|
+
|
|
35
|
+
# 4. Enable configuration sources in a project and create links
|
|
36
|
+
cd my-project
|
|
37
|
+
tools-cc use my-skills -p iflow claude
|
|
38
|
+
|
|
39
|
+
# 5. View project status
|
|
40
|
+
tools-cc status
|
|
41
|
+
|
|
42
|
+
# 6. View enabled configuration sources
|
|
43
|
+
tools-cc list
|
|
44
|
+
|
|
45
|
+
# 7. Update configuration sources (sync latest content from source directory to project)
|
|
46
|
+
tools-cc update my-skills
|
|
47
|
+
tools-cc update # Update all
|
|
48
|
+
|
|
49
|
+
# 8. Remove configuration source
|
|
50
|
+
tools-cc rm my-skills
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Workflow Guide
|
|
54
|
+
|
|
55
|
+
### Global Source Management vs Project Configuration
|
|
56
|
+
|
|
57
|
+
| Command | Scope | Description |
|
|
58
|
+
|---------|-------|-------------|
|
|
59
|
+
| `tools-cc -s add/remove/list` | Global | Manage global configuration sources |
|
|
60
|
+
| `tools-cc -s update/upgrade` | Global | git pull to update source code |
|
|
61
|
+
| `tools-cc -s scan` | Global | Scan directory to discover new sources |
|
|
62
|
+
| `tools-cc use/rm` | Project | Enable/disable sources in project |
|
|
63
|
+
| `tools-cc update` | Project | Sync source content to project |
|
|
64
|
+
|
|
65
|
+
### Typical Workflow
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Scenario 1: Configuration source has updates, need to sync to project
|
|
69
|
+
tools-cc -s upgrade my-skills # 1. git pull to update source code
|
|
70
|
+
cd my-project
|
|
71
|
+
tools-cc update my-skills # 2. Sync to project .toolscc directory
|
|
72
|
+
|
|
73
|
+
# Scenario 2: Batch update all sources
|
|
74
|
+
tools-cc -s upgrade # 1. Update all git sources
|
|
75
|
+
cd my-project
|
|
76
|
+
tools-cc update # 2. Sync all sources to project
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Command Reference
|
|
80
|
+
|
|
81
|
+
### Source Management
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Shortcuts (-s)
|
|
85
|
+
tools-cc -s add <name> <path-or-url> # Add configuration source (Git URL or local path)
|
|
86
|
+
tools-cc -s list # List all configuration sources (alias: -s ls)
|
|
87
|
+
tools-cc -s remove <name> # Remove configuration source (alias: -s rm)
|
|
88
|
+
tools-cc -s update [name] # git pull to update source code (alias: -s up, -s upgrade)
|
|
89
|
+
tools-cc -s scan # Scan sourcesDir to auto-discover and add configuration sources
|
|
90
|
+
|
|
91
|
+
# Full commands (sources)
|
|
92
|
+
tools-cc sources add <name> <path-or-url> # Add configuration source
|
|
93
|
+
tools-cc sources list # List all configuration sources (alias: sources ls)
|
|
94
|
+
tools-cc sources remove <name> # Remove configuration source (alias: sources rm)
|
|
95
|
+
tools-cc sources update [name] # git pull to update source code (alias: sources up, sources upgrade)
|
|
96
|
+
tools-cc sources scan # Scan sourcesDir to auto-discover and add configuration sources
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Project Configuration
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
tools-cc use [sources...] [-p tools...] # Enable configuration sources and create symbolic links
|
|
103
|
+
tools-cc update [sources...] # Sync configuration source content to project .toolscc directory
|
|
104
|
+
tools-cc list # List enabled configuration sources
|
|
105
|
+
tools-cc rm <source> # Disable configuration source
|
|
106
|
+
tools-cc status # View project status
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Config Management
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Shortcuts (-c)
|
|
113
|
+
tools-cc -c set <key> <value> # Set configuration
|
|
114
|
+
tools-cc -c get <key> # Get configuration
|
|
115
|
+
|
|
116
|
+
# Full commands (config)
|
|
117
|
+
tools-cc config set <key> <value> # Set configuration
|
|
118
|
+
tools-cc config get <key> # Get configuration
|
|
119
|
+
tools-cc config list # View complete global configuration
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Help
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
tools-cc help # Display bilingual help (Chinese/English)
|
|
126
|
+
tools-cc --help # Display command line help
|
|
127
|
+
tools-cc --version # Display version number
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Supported Tools
|
|
131
|
+
|
|
132
|
+
| Tool | Link Name |
|
|
133
|
+
|------|-----------|
|
|
134
|
+
| iflow | `.iflow` |
|
|
135
|
+
| claude | `.claude` |
|
|
136
|
+
| codebuddy | `.codebuddy` |
|
|
137
|
+
| opencode | `.opencode` |
|
|
138
|
+
|
|
139
|
+
## Configuration Source Structure
|
|
140
|
+
|
|
141
|
+
A configuration source directory should contain the following structure:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
my-skills/
|
|
145
|
+
├── manifest.json # Optional, describes component information
|
|
146
|
+
├── skills/
|
|
147
|
+
│ └── my-skill/
|
|
148
|
+
│ └── SKILL.md
|
|
149
|
+
├── commands/
|
|
150
|
+
│ └── my-command.md
|
|
151
|
+
└── agents/
|
|
152
|
+
└── my-agent.md
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### manifest.json Format
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"name": "my-skills",
|
|
160
|
+
"version": "1.0.0",
|
|
161
|
+
"skills": ["my-skill"],
|
|
162
|
+
"commands": ["my-command"],
|
|
163
|
+
"agents": ["my-agent"]
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
If `manifest.json` is not present, the CLI will automatically scan the directory structure to generate one.
|
|
168
|
+
|
|
169
|
+
## Project Structure
|
|
170
|
+
|
|
171
|
+
After using `tools-cc use`, the project directory structure:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
my-project/
|
|
175
|
+
├── .toolscc/ # Actual content directory
|
|
176
|
+
│ ├── config.json # Project configuration
|
|
177
|
+
│ ├── skills/ # Flattened, with source prefix
|
|
178
|
+
│ │ └── my-skills-my-skill/
|
|
179
|
+
│ ├── commands/
|
|
180
|
+
│ │ └── my-skills/
|
|
181
|
+
│ └── agents/
|
|
182
|
+
│ └── my-skills/
|
|
183
|
+
├── .iflow -> .toolscc # Symbolic link
|
|
184
|
+
└── .claude -> .toolscc
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Configuration Files
|
|
188
|
+
|
|
189
|
+
### Global Configuration `~/.tools-cc/config.json`
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"sourcesDir": "D:/skills-hub-sources",
|
|
194
|
+
"sources": {
|
|
195
|
+
"my-skills": {
|
|
196
|
+
"type": "git",
|
|
197
|
+
"url": "https://github.com/user/my-skills.git"
|
|
198
|
+
},
|
|
199
|
+
"local-skills": {
|
|
200
|
+
"type": "local",
|
|
201
|
+
"path": "D:/local-skills"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Project Configuration `project/.toolscc/config.json`
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"sources": ["my-skills"],
|
|
212
|
+
"links": ["iflow", "claude"]
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT
|
package/dist/core/project.js
CHANGED
|
@@ -46,7 +46,8 @@ async function useSource(sourceName, sourceDir, projectDir) {
|
|
|
46
46
|
const skills = await fs_extra_1.default.readdir(sourceSkillsDir);
|
|
47
47
|
for (const skill of skills) {
|
|
48
48
|
const srcPath = path_1.default.join(sourceSkillsDir, skill);
|
|
49
|
-
const
|
|
49
|
+
const name = `${sourceName}` == `${skill}` ? skill : `${sourceName}-${skill}`;
|
|
50
|
+
const destPath = path_1.default.join(toolsccDir, 'skills', name);
|
|
50
51
|
// Remove existing if exists
|
|
51
52
|
await fs_extra_1.default.remove(destPath);
|
|
52
53
|
// Copy directory
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tools-cc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "tools-cc [options] <command> [args]",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"dev": "ts-node src/index.ts",
|
|
12
12
|
"start": "node dist/index.js",
|
|
13
13
|
"test": "vitest",
|
|
14
|
-
"test:run": "vitest run"
|
|
14
|
+
"test:run": "vitest run",
|
|
15
|
+
"release": "npm publish && git tag v%npm_package_version% && git push origin v%npm_package_version% && gh release create v%npm_package_version% --title v%npm_package_version% --generate-notes"
|
|
15
16
|
},
|
|
16
17
|
"bin": {
|
|
17
18
|
"tools-cc": "./dist/index.js"
|
package/src/core/project.ts
CHANGED
|
@@ -7,12 +7,12 @@ import { getToolsccDir, getProjectConfigPath } from '../utils/path';
|
|
|
7
7
|
export async function initProject(projectDir: string): Promise<void> {
|
|
8
8
|
const toolsccDir = getToolsccDir(projectDir);
|
|
9
9
|
const configFile = getProjectConfigPath(projectDir);
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
// Create .toolscc directory structure
|
|
12
12
|
await fs.ensureDir(path.join(toolsccDir, 'skills'));
|
|
13
13
|
await fs.ensureDir(path.join(toolsccDir, 'commands'));
|
|
14
14
|
await fs.ensureDir(path.join(toolsccDir, 'agents'));
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Create project config if not exists
|
|
17
17
|
if (!(await fs.pathExists(configFile))) {
|
|
18
18
|
const config: ProjectConfig = {
|
|
@@ -32,34 +32,35 @@ export async function useSource(
|
|
|
32
32
|
if (!sourceName || !sourceName.trim()) {
|
|
33
33
|
throw new Error('Source name is required');
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
// Check source directory existence
|
|
37
37
|
if (!(await fs.pathExists(sourceDir))) {
|
|
38
38
|
throw new Error(`Source directory does not exist: ${sourceDir}`);
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
const toolsccDir = getToolsccDir(projectDir);
|
|
42
42
|
const manifest = await loadManifest(sourceDir);
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
// Ensure project is initialized
|
|
45
45
|
await initProject(projectDir);
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
// Copy/link skills (flattened with prefix)
|
|
48
48
|
const sourceSkillsDir = path.join(sourceDir, 'skills');
|
|
49
49
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
50
50
|
const skills = await fs.readdir(sourceSkillsDir);
|
|
51
51
|
for (const skill of skills) {
|
|
52
52
|
const srcPath = path.join(sourceSkillsDir, skill);
|
|
53
|
-
const
|
|
54
|
-
|
|
53
|
+
const name = `${sourceName}` == `${skill}` ? skill : `${sourceName}-${skill}`;
|
|
54
|
+
const destPath = path.join(toolsccDir, 'skills', name);
|
|
55
|
+
|
|
55
56
|
// Remove existing if exists
|
|
56
57
|
await fs.remove(destPath);
|
|
57
|
-
|
|
58
|
+
|
|
58
59
|
// Copy directory
|
|
59
60
|
await fs.copy(srcPath, destPath);
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
+
|
|
63
64
|
// Copy commands (in subdirectory by source name)
|
|
64
65
|
const sourceCommandsDir = path.join(sourceDir, 'commands');
|
|
65
66
|
if (await fs.pathExists(sourceCommandsDir)) {
|
|
@@ -67,7 +68,7 @@ export async function useSource(
|
|
|
67
68
|
await fs.remove(destDir);
|
|
68
69
|
await fs.copy(sourceCommandsDir, destDir);
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
// Copy agents (in subdirectory by source name)
|
|
72
73
|
const sourceAgentsDir = path.join(sourceDir, 'agents');
|
|
73
74
|
if (await fs.pathExists(sourceAgentsDir)) {
|
|
@@ -75,7 +76,7 @@ export async function useSource(
|
|
|
75
76
|
await fs.remove(destDir);
|
|
76
77
|
await fs.copy(sourceAgentsDir, destDir);
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
+
|
|
79
80
|
// Update project config
|
|
80
81
|
const configFile = getProjectConfigPath(projectDir);
|
|
81
82
|
const config: ProjectConfig = await fs.readJson(configFile);
|
|
@@ -90,10 +91,10 @@ export async function unuseSource(sourceName: string, projectDir: string): Promi
|
|
|
90
91
|
if (!sourceName || !sourceName.trim()) {
|
|
91
92
|
throw new Error('Source name is required');
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
+
|
|
94
95
|
const toolsccDir = getToolsccDir(projectDir);
|
|
95
96
|
const configFile = getProjectConfigPath(projectDir);
|
|
96
|
-
|
|
97
|
+
|
|
97
98
|
// Remove skills with prefix
|
|
98
99
|
const skillsDir = path.join(toolsccDir, 'skills');
|
|
99
100
|
if (await fs.pathExists(skillsDir)) {
|
|
@@ -104,13 +105,13 @@ export async function unuseSource(sourceName: string, projectDir: string): Promi
|
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
// Remove commands subdirectory
|
|
109
110
|
await fs.remove(path.join(toolsccDir, 'commands', sourceName));
|
|
110
|
-
|
|
111
|
+
|
|
111
112
|
// Remove agents subdirectory
|
|
112
113
|
await fs.remove(path.join(toolsccDir, 'agents', sourceName));
|
|
113
|
-
|
|
114
|
+
|
|
114
115
|
// Update project config with error handling
|
|
115
116
|
let config: ProjectConfig;
|
|
116
117
|
try {
|
|
@@ -119,18 +120,18 @@ export async function unuseSource(sourceName: string, projectDir: string): Promi
|
|
|
119
120
|
// If config file doesn't exist or is invalid, nothing to update
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
122
|
-
|
|
123
|
+
|
|
123
124
|
config.sources = config.sources.filter(s => s !== sourceName);
|
|
124
125
|
await fs.writeJson(configFile, config, { spaces: 2 });
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
export async function listUsedSources(projectDir: string): Promise<string[]> {
|
|
128
129
|
const configFile = getProjectConfigPath(projectDir);
|
|
129
|
-
|
|
130
|
+
|
|
130
131
|
if (!(await fs.pathExists(configFile))) {
|
|
131
132
|
return [];
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
+
|
|
134
135
|
const config: ProjectConfig = await fs.readJson(configFile);
|
|
135
136
|
return config.sources;
|
|
136
137
|
}
|