tools-cc 1.0.3 → 1.0.5

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,31 @@
1
+ import { SourceSelection } from '../types/config';
2
+ /**
3
+ * 解析后的源路径
4
+ */
5
+ export interface ParsedSourcePath {
6
+ sourceName: string;
7
+ type?: 'skills' | 'commands' | 'agents';
8
+ itemName?: string;
9
+ }
10
+ /**
11
+ * 解析源路径字符串
12
+ *
13
+ * 支持的格式:
14
+ * - 'my-skills' → { sourceName: 'my-skills' } (整个源)
15
+ * - 'my-skills/skills/a-skill' → { sourceName: 'my-skills', type: 'skills', itemName: 'a-skill' }
16
+ * - 'my-skills/commands/test' → { sourceName: 'my-skills', type: 'commands', itemName: 'test' }
17
+ * - 'other/agents/reviewer' → { sourceName: 'other', type: 'agents', itemName: 'reviewer' }
18
+ *
19
+ * 无效路径只返回 sourceName
20
+ */
21
+ export declare function parseSourcePath(input: string): ParsedSourcePath;
22
+ /**
23
+ * 从路径数组构建选择配置
24
+ *
25
+ * 将多个路径转换为 Record<string, SourceSelection> 格式
26
+ *
27
+ * 示例:
28
+ * ['my-skills/skills/a', 'my-skills/skills/b', 'my-skills/commands/test']
29
+ * → { 'my-skills': { skills: ['a', 'b'], commands: ['test'], agents: [] } }
30
+ */
31
+ export declare function buildSelectionFromPaths(paths: string[]): Record<string, SourceSelection>;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSourcePath = parseSourcePath;
4
+ exports.buildSelectionFromPaths = buildSelectionFromPaths;
5
+ /**
6
+ * 解析源路径字符串
7
+ *
8
+ * 支持的格式:
9
+ * - 'my-skills' → { sourceName: 'my-skills' } (整个源)
10
+ * - 'my-skills/skills/a-skill' → { sourceName: 'my-skills', type: 'skills', itemName: 'a-skill' }
11
+ * - 'my-skills/commands/test' → { sourceName: 'my-skills', type: 'commands', itemName: 'test' }
12
+ * - 'other/agents/reviewer' → { sourceName: 'other', type: 'agents', itemName: 'reviewer' }
13
+ *
14
+ * 无效路径只返回 sourceName
15
+ */
16
+ function parseSourcePath(input) {
17
+ const parts = input.split('/');
18
+ // 至少需要源名称
19
+ if (parts.length === 0 || input === '') {
20
+ return { sourceName: '' };
21
+ }
22
+ const sourceName = parts[0];
23
+ // 只有源名称,返回整个源
24
+ if (parts.length === 1) {
25
+ return { sourceName };
26
+ }
27
+ // 检查第二部分是否为有效类型
28
+ const validTypes = ['skills', 'commands', 'agents'];
29
+ const type = parts[1];
30
+ if (!validTypes.includes(type)) {
31
+ return { sourceName };
32
+ }
33
+ // 检查第三部分(项目名称)
34
+ if (parts.length < 3 || !parts[2]) {
35
+ return { sourceName };
36
+ }
37
+ return {
38
+ sourceName,
39
+ type,
40
+ itemName: parts[2]
41
+ };
42
+ }
43
+ /**
44
+ * 从路径数组构建选择配置
45
+ *
46
+ * 将多个路径转换为 Record<string, SourceSelection> 格式
47
+ *
48
+ * 示例:
49
+ * ['my-skills/skills/a', 'my-skills/skills/b', 'my-skills/commands/test']
50
+ * → { 'my-skills': { skills: ['a', 'b'], commands: ['test'], agents: [] } }
51
+ */
52
+ function buildSelectionFromPaths(paths) {
53
+ const result = {};
54
+ for (const path of paths) {
55
+ const parsed = parseSourcePath(path);
56
+ const { sourceName, type, itemName } = parsed;
57
+ // 跳过空源名称
58
+ if (!sourceName) {
59
+ continue;
60
+ }
61
+ // 初始化源选择(如果不存在)
62
+ if (!result[sourceName]) {
63
+ result[sourceName] = {
64
+ skills: [],
65
+ commands: [],
66
+ agents: []
67
+ };
68
+ }
69
+ // 如果没有指定类型和项目名称,表示整个源
70
+ if (!type || !itemName) {
71
+ result[sourceName] = {
72
+ skills: ['*'],
73
+ commands: ['*'],
74
+ agents: ['*']
75
+ };
76
+ continue;
77
+ }
78
+ // 添加项目到对应的类型数组(去重)
79
+ const selection = result[sourceName];
80
+ const targetArray = selection[type];
81
+ if (!targetArray.includes(itemName)) {
82
+ targetArray.push(itemName);
83
+ }
84
+ }
85
+ return result;
86
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tools-cc",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "tools-cc [options] <command> [args]",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -11,7 +11,11 @@
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
+ "tag:create": "git tag v%npm_package_version% && git push github v%npm_package_version%",
16
+ "publish:npm": "npm publish",
17
+ "release:gh": "gh release create v%npm_package_version% --title v%npm_package_version% --generate-notes",
18
+ "release": "npm run tag:create && npm run publish:npm && npm run release:gh"
15
19
  },
16
20
  "bin": {
17
21
  "tools-cc": "./dist/index.js"
@@ -0,0 +1,60 @@
1
+ import chalk from 'chalk';
2
+ import path from 'path';
3
+ import fs from 'fs-extra';
4
+ import { exportProjectConfig } from '../core/project';
5
+ import { loadGlobalConfig } from '../core/config';
6
+ import { GLOBAL_CONFIG_DIR } from '../utils/path';
7
+ import { GlobalExportConfig } from '../types/config';
8
+
9
+ /**
10
+ * 导出项目或全局配置
11
+ */
12
+ export async function handleExport(options: {
13
+ output?: string;
14
+ global?: boolean;
15
+ }): Promise<void> {
16
+ try {
17
+ if (options.global) {
18
+ // 导出全局配置
19
+ await exportGlobalConfig(options.output);
20
+ } else {
21
+ // 导出项目配置
22
+ await exportProjectConfigCmd(options.output);
23
+ }
24
+ } catch (error) {
25
+ const message = error instanceof Error ? error.message : String(error);
26
+ console.log(chalk.red(`✗ Export failed: ${message}`));
27
+ throw error;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * 导出项目配置
33
+ */
34
+ async function exportProjectConfigCmd(outputPath?: string): Promise<void> {
35
+ const projectDir = process.cwd();
36
+ const outputFile = outputPath ?? path.join(projectDir, '.toolscc-export.json');
37
+
38
+ await exportProjectConfig(projectDir, outputFile);
39
+ console.log(chalk.green(`✓ Project config exported to: ${outputFile}`));
40
+ }
41
+
42
+ /**
43
+ * 导出全局配置
44
+ */
45
+ async function exportGlobalConfig(outputPath?: string): Promise<void> {
46
+ const projectDir = process.cwd();
47
+ const outputFile = outputPath ?? path.join(projectDir, '.toolscc-global-export.json');
48
+
49
+ const config = await loadGlobalConfig(GLOBAL_CONFIG_DIR);
50
+
51
+ const exportConfig: GlobalExportConfig = {
52
+ version: '1.0',
53
+ type: 'global',
54
+ config,
55
+ exportedAt: new Date().toISOString()
56
+ };
57
+
58
+ await fs.writeJson(outputFile, exportConfig, { spaces: 2 });
59
+ console.log(chalk.green(`✓ Global config exported to: ${outputFile}`));
60
+ }