listen-agent 1.0.2

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.
Files changed (51) hide show
  1. package/README.md +132 -0
  2. package/dist/commands/create.d.ts +3 -0
  3. package/dist/commands/create.d.ts.map +1 -0
  4. package/dist/commands/create.js +157 -0
  5. package/dist/commands/create.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +210 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/list.d.ts +2 -0
  11. package/dist/commands/list.d.ts.map +1 -0
  12. package/dist/commands/list.js +65 -0
  13. package/dist/commands/list.js.map +1 -0
  14. package/dist/commands/setup.d.ts +2 -0
  15. package/dist/commands/setup.d.ts.map +1 -0
  16. package/dist/commands/setup.js +50 -0
  17. package/dist/commands/setup.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +53 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/types/index.d.ts +25 -0
  23. package/dist/types/index.d.ts.map +1 -0
  24. package/dist/types/index.js +26 -0
  25. package/dist/types/index.js.map +1 -0
  26. package/dist/utils/detect.d.ts +4 -0
  27. package/dist/utils/detect.d.ts.map +1 -0
  28. package/dist/utils/detect.js +52 -0
  29. package/dist/utils/detect.js.map +1 -0
  30. package/dist/utils/files.d.ts +7 -0
  31. package/dist/utils/files.d.ts.map +1 -0
  32. package/dist/utils/files.js +70 -0
  33. package/dist/utils/files.js.map +1 -0
  34. package/dist/utils/logger.d.ts +9 -0
  35. package/dist/utils/logger.d.ts.map +1 -0
  36. package/dist/utils/logger.js +10 -0
  37. package/dist/utils/logger.js.map +1 -0
  38. package/package.json +66 -0
  39. package/skills/mac-m4-lora-training/README.md +152 -0
  40. package/skills/mac-m4-lora-training/SKILL.md +181 -0
  41. package/skills/mac-m4-lora-training/scripts/auto_lora_train_mps.py +474 -0
  42. package/skills/mac-m4-lora-training/scripts/install_dependencies.sh +226 -0
  43. package/skills/mac-m4-lora-training/scripts/quick_train.sh +88 -0
  44. package/skills/wechat-work-notification/README.md +88 -0
  45. package/skills/wechat-work-notification/SKILL.md +187 -0
  46. package/templates/advanced/README.md +45 -0
  47. package/templates/advanced/SKILL.md +149 -0
  48. package/templates/advanced/scripts/install_dependencies.sh +14 -0
  49. package/templates/advanced/scripts/run_task.sh +48 -0
  50. package/templates/basic/README.md +17 -0
  51. package/templates/basic/SKILL.md +72 -0
@@ -0,0 +1,50 @@
1
+ import { join } from 'node:path';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import chalk from 'chalk';
4
+ import { logger } from '../utils/logger.js';
5
+ import { createDirectory } from '../utils/files.js';
6
+ export async function setupCommand() {
7
+ logger.title('Listen Agent Skills Framework Setup');
8
+ const cwd = process.cwd();
9
+ try {
10
+ // 创建基础目录结构
11
+ await createDirectory(join(cwd, 'skills'));
12
+ await createDirectory(join(cwd, 'templates'));
13
+ // 创建配置文件
14
+ await createConfigFiles(cwd);
15
+ console.log();
16
+ logger.info('Created structure:');
17
+ console.log(` ${chalk.green('+')} skills/`);
18
+ console.log(` ${chalk.green('+')} templates/`);
19
+ console.log(` ${chalk.green('+')} listen-agent.config.json`);
20
+ console.log();
21
+ logger.success('Listen Agent Skills Framework setup complete!');
22
+ // 显示后续步骤
23
+ console.log();
24
+ console.log(chalk.bold('Next steps:'));
25
+ console.log(chalk.dim(' 1. Create your first skill: listen-agent create my-skill'));
26
+ console.log(chalk.dim(' 2. List available skills: listen-agent list'));
27
+ console.log(chalk.dim(' 3. Install skills to AI projects: listen-agent init'));
28
+ console.log();
29
+ }
30
+ catch (error) {
31
+ logger.error('Setup failed');
32
+ if (error instanceof Error) {
33
+ logger.error(error.message);
34
+ }
35
+ process.exit(1);
36
+ }
37
+ }
38
+ async function createConfigFiles(cwd) {
39
+ const configPath = join(cwd, 'listen-agent.config.json');
40
+ const config = {
41
+ version: '1.0.0',
42
+ skillsDir: 'skills',
43
+ templatesDir: 'templates',
44
+ defaultTemplate: 'basic',
45
+ aiTypes: ['claude', 'cursor', 'windsurf', 'kiro'],
46
+ createdAt: new Date().toISOString()
47
+ };
48
+ await writeFile(configPath, JSON.stringify(config, null, 2));
49
+ }
50
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEpD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,WAAW;QACX,MAAM,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3C,MAAM,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;QAE9C,SAAS;QACT,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAE7B,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAE9D,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;QAEhE,SAAS;QACT,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,EAAE,CAAC;IAEhB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC7B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,QAAQ;QACnB,YAAY,EAAE,WAAW;QACzB,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC;QACjD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { initCommand } from './commands/init.js';
4
+ import { setupCommand } from './commands/setup.js';
5
+ import { listCommand } from './commands/list.js';
6
+ import { createCommand } from './commands/create.js';
7
+ import { AI_TYPES } from './types/index.js';
8
+ const program = new Command();
9
+ program
10
+ .name('listen-agent')
11
+ .description('CLI to manage and install agent skills for AI coding assistants')
12
+ .version('1.0.0');
13
+ // Setup command - 初始化项目结构
14
+ program
15
+ .command('setup')
16
+ .description('Setup agent skills framework in current directory')
17
+ .action(async () => {
18
+ await setupCommand();
19
+ });
20
+ // Init command - 安装skills到AI助手项目
21
+ program
22
+ .command('init')
23
+ .description('Install existing skills to AI assistant projects')
24
+ .option('-a, --ai <type>', `AI assistant type (${AI_TYPES.join(', ')})`)
25
+ .option('-f, --force', 'Overwrite existing files')
26
+ .action(async (options) => {
27
+ if (options.ai && !AI_TYPES.includes(options.ai)) {
28
+ console.error(`Invalid AI type: ${options.ai}`);
29
+ console.error(`Valid types: ${AI_TYPES.join(', ')}`);
30
+ process.exit(1);
31
+ }
32
+ await initCommand({
33
+ ai: options.ai,
34
+ force: options.force,
35
+ });
36
+ });
37
+ // List command - 列出已安装的skills
38
+ program
39
+ .command('list')
40
+ .description('List all available agent skills')
41
+ .action(async () => {
42
+ await listCommand();
43
+ });
44
+ // Create command - 创建新的skill
45
+ program
46
+ .command('create <name>')
47
+ .description('Create a new agent skill')
48
+ .option('-t, --template <type>', 'Skill template type', 'basic')
49
+ .action(async (name, options) => {
50
+ await createCommand(name, options);
51
+ });
52
+ program.parse();
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,iEAAiE,CAAC;KAC9E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,YAAY,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,iCAAiC;AACjC,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;KACvE,MAAM,CAAC,aAAa,EAAE,0BAA0B,CAAC;KACjD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,8BAA8B;AAC9B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,WAAW,EAAE,CAAC;AACtB,CAAC,CAAC,CAAC;AAEL,6BAA6B;AAC7B,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,uBAAuB,EAAE,qBAAqB,EAAE,OAAO,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAC9B,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ export type AIType = 'claude' | 'cursor' | 'windsurf' | 'antigravity' | 'copilot' | 'kiro' | 'roocode' | 'codex' | 'qoder' | 'gemini' | 'all';
2
+ export declare const AI_TYPES: AIType[];
3
+ export declare const AI_FOLDERS: Record<Exclude<AIType, 'all'>, string[]>;
4
+ export interface InitOptions {
5
+ ai?: AIType;
6
+ force?: boolean;
7
+ }
8
+ export interface CreateOptions {
9
+ template?: string;
10
+ }
11
+ export interface DetectionResult {
12
+ detected: AIType[];
13
+ suggested: AIType | null;
14
+ }
15
+ export interface SkillMetadata {
16
+ name: string;
17
+ version: string;
18
+ description: string;
19
+ author?: string;
20
+ tags?: string[];
21
+ aiTypes: AIType[];
22
+ createdAt: string;
23
+ updatedAt: string;
24
+ }
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GACd,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,aAAa,GACb,SAAS,GACT,MAAM,GACN,SAAS,GACT,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,CAAC;AAEV,eAAO,MAAM,QAAQ,EAAE,MAAM,EAY5B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAW/D,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,26 @@
1
+ export const AI_TYPES = [
2
+ 'claude',
3
+ 'cursor',
4
+ 'windsurf',
5
+ 'antigravity',
6
+ 'copilot',
7
+ 'roocode',
8
+ 'kiro',
9
+ 'codex',
10
+ 'qoder',
11
+ 'gemini',
12
+ 'all'
13
+ ];
14
+ export const AI_FOLDERS = {
15
+ claude: ['.claude'],
16
+ cursor: ['.cursor', '.shared'],
17
+ windsurf: ['.windsurf', '.shared'],
18
+ antigravity: ['.agent', '.shared'],
19
+ copilot: ['.github', '.shared'],
20
+ kiro: ['.kiro', '.shared'],
21
+ codex: ['.codex'],
22
+ roocode: ['.roo', '.shared'],
23
+ qoder: ['.qoder', '.shared'],
24
+ gemini: ['.gemini', '.shared'],
25
+ };
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,QAAQ,GAAa;IAChC,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,aAAa;IACb,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,KAAK;CACN,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAA6C;IAClE,MAAM,EAAO,CAAC,SAAS,CAAC;IACxB,MAAM,EAAO,CAAC,SAAS,EAAE,SAAS,CAAC;IACnC,QAAQ,EAAK,CAAC,WAAW,EAAE,SAAS,CAAC;IACrC,WAAW,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAClC,OAAO,EAAM,CAAC,SAAS,EAAE,SAAS,CAAC;IACnC,IAAI,EAAS,CAAC,OAAO,EAAE,SAAS,CAAC;IACjC,KAAK,EAAQ,CAAC,QAAQ,CAAC;IACvB,OAAO,EAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IAChC,KAAK,EAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAClC,MAAM,EAAO,CAAC,SAAS,EAAE,SAAS,CAAC;CACpC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { AIType, DetectionResult } from '../types/index.js';
2
+ export declare function detectAIType(cwd?: string): DetectionResult;
3
+ export declare function getAITypeDescription(aiType: AIType): string;
4
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/utils/detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEjE,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,eAAe,CAyBzE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAc3D"}
@@ -0,0 +1,52 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export function detectAIType(cwd = process.cwd()) {
4
+ const detected = [];
5
+ // 检测各种AI助手的配置文件夹
6
+ if (existsSync(join(cwd, '.claude')))
7
+ detected.push('claude');
8
+ if (existsSync(join(cwd, '.cursor')))
9
+ detected.push('cursor');
10
+ if (existsSync(join(cwd, '.windsurf')))
11
+ detected.push('windsurf');
12
+ if (existsSync(join(cwd, '.agent')))
13
+ detected.push('antigravity');
14
+ if (existsSync(join(cwd, '.github')))
15
+ detected.push('copilot');
16
+ if (existsSync(join(cwd, '.kiro')))
17
+ detected.push('kiro');
18
+ if (existsSync(join(cwd, '.codex')))
19
+ detected.push('codex');
20
+ if (existsSync(join(cwd, '.roo')))
21
+ detected.push('roocode');
22
+ if (existsSync(join(cwd, '.qoder')))
23
+ detected.push('qoder');
24
+ if (existsSync(join(cwd, '.gemini')))
25
+ detected.push('gemini');
26
+ // 智能建议逻辑
27
+ let suggested = null;
28
+ if (detected.length === 1) {
29
+ suggested = detected[0]; // 单个AI:直接建议
30
+ }
31
+ else if (detected.length > 1) {
32
+ suggested = 'all'; // 多个AI:建议安装全部
33
+ }
34
+ // detected.length === 0:无建议,用户自选
35
+ return { detected, suggested };
36
+ }
37
+ export function getAITypeDescription(aiType) {
38
+ switch (aiType) {
39
+ case 'claude': return 'Claude Code (.claude/skills/)';
40
+ case 'cursor': return 'Cursor (.cursor/commands/ + .shared/)';
41
+ case 'windsurf': return 'Windsurf (.windsurf/workflows/ + .shared/)';
42
+ case 'antigravity': return 'Antigravity (.agent/workflows/ + .shared/)';
43
+ case 'copilot': return 'GitHub Copilot (.github/prompts/ + .shared/)';
44
+ case 'kiro': return 'Kiro (.kiro/steering/ + .shared/)';
45
+ case 'codex': return 'Codex (.codex/skills/)';
46
+ case 'roocode': return 'RooCode (.roo/commands/ + .shared/)';
47
+ case 'qoder': return 'Qoder (.qoder/rules/ + .shared/)';
48
+ case 'gemini': return 'Gemini CLI (.gemini/skills/ + .shared/)';
49
+ case 'all': return 'All AI assistants';
50
+ }
51
+ }
52
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/utils/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,YAAY,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACtD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,iBAAiB;IACjB,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE9D,SAAS;IACT,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAQ,YAAY;IAC9C,CAAC;SAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,SAAS,GAAG,KAAK,CAAC,CAAc,cAAc;IAChD,CAAC;IACD,iCAAiC;IAEjC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC,CAAM,OAAO,+BAA+B,CAAC;QAC3D,KAAK,QAAQ,CAAC,CAAM,OAAO,uCAAuC,CAAC;QACnE,KAAK,UAAU,CAAC,CAAI,OAAO,4CAA4C,CAAC;QACxE,KAAK,aAAa,CAAC,CAAC,OAAO,4CAA4C,CAAC;QACxE,KAAK,SAAS,CAAC,CAAK,OAAO,8CAA8C,CAAC;QAC1E,KAAK,MAAM,CAAC,CAAQ,OAAO,mCAAmC,CAAC;QAC/D,KAAK,OAAO,CAAC,CAAO,OAAO,wBAAwB,CAAC;QACpD,KAAK,SAAS,CAAC,CAAK,OAAO,qCAAqC,CAAC;QACjE,KAAK,OAAO,CAAC,CAAO,OAAO,kCAAkC,CAAC;QAC9D,KAAK,QAAQ,CAAC,CAAM,OAAO,yCAAyC,CAAC;QACrE,KAAK,KAAK,CAAC,CAAS,OAAO,mBAAmB,CAAC;IACjD,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AIType } from '../types/index.js';
2
+ export declare function exists(path: string): Promise<boolean>;
3
+ export declare function copyFolders(sourceDir: string, // assets/
4
+ targetDir: string, // 当前工作目录
5
+ aiType: AIType): Promise<string[]>;
6
+ export declare function createDirectory(path: string): Promise<void>;
7
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAOhD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EAAK,UAAU;AAChC,SAAS,EAAE,MAAM,EAAK,SAAS;AAC/B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAoDnB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE"}
@@ -0,0 +1,70 @@
1
+ import { access, mkdir, cp } from 'node:fs/promises';
2
+ import { join, basename } from 'node:path';
3
+ import { exec } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+ import { AI_FOLDERS } from '../types/index.js';
6
+ const execAsync = promisify(exec);
7
+ const EXCLUDED_FILES = ['settings.local.json', '.DS_Store'];
8
+ export async function exists(path) {
9
+ try {
10
+ await access(path);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ export async function copyFolders(sourceDir, // assets/
18
+ targetDir, // 当前工作目录
19
+ aiType) {
20
+ const copiedFolders = [];
21
+ // 1. 确定要复制的文件夹列表
22
+ const foldersToCopy = aiType === 'all'
23
+ ? ['.claude', '.cursor', '.windsurf', '.agent', '.github', '.kiro', '.roo', '.codex', '.gemini', '.shared']
24
+ : AI_FOLDERS[aiType];
25
+ // 2. 去重处理(.shared可能重复)
26
+ const uniqueFolders = [...new Set(foldersToCopy)];
27
+ // 3. 逐个复制文件夹
28
+ for (const folder of uniqueFolders) {
29
+ const sourcePath = join(sourceDir, folder);
30
+ const targetPath = join(targetDir, folder);
31
+ // 3.1 检查源文件夹是否存在
32
+ const sourceExists = await exists(sourcePath);
33
+ if (!sourceExists) {
34
+ continue; // 跳过不存在的文件夹
35
+ }
36
+ // 3.2 创建目标目录
37
+ await mkdir(targetPath, { recursive: true });
38
+ // 3.3 定义文件过滤器
39
+ const filterFn = (src) => {
40
+ const fileName = basename(src);
41
+ return !EXCLUDED_FILES.includes(fileName);
42
+ };
43
+ // 3.4 执行复制(多重容错)
44
+ try {
45
+ // 优先使用Node.js原生API
46
+ await cp(sourcePath, targetPath, { recursive: true, filter: filterFn });
47
+ copiedFolders.push(folder);
48
+ }
49
+ catch {
50
+ // 降级到系统命令
51
+ try {
52
+ if (process.platform === 'win32') {
53
+ await execAsync(`xcopy "${sourcePath}" "${targetPath}" /E /I /Y`);
54
+ }
55
+ else {
56
+ await execAsync(`cp -r "${sourcePath}/." "${targetPath}"`);
57
+ }
58
+ copiedFolders.push(folder);
59
+ }
60
+ catch {
61
+ // 静默跳过失败的文件夹
62
+ }
63
+ }
64
+ }
65
+ return copiedFolders;
66
+ }
67
+ export async function createDirectory(path) {
68
+ await mkdir(path, { recursive: true });
69
+ }
70
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare const logger: {
2
+ info: (msg: string) => void;
3
+ success: (msg: string) => void;
4
+ warn: (msg: string) => void;
5
+ error: (msg: string) => void;
6
+ title: (msg: string) => void;
7
+ dim: (msg: string) => void;
8
+ };
9
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;gBACL,MAAM;mBACH,MAAM;gBACT,MAAM;iBACL,MAAM;iBACN,MAAM;eACR,MAAM;CAClB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import chalk from 'chalk';
2
+ export const logger = {
3
+ info: (msg) => console.log(chalk.blue('info'), msg),
4
+ success: (msg) => console.log(chalk.green('success'), msg),
5
+ warn: (msg) => console.log(chalk.yellow('warn'), msg),
6
+ error: (msg) => console.log(chalk.red('error'), msg),
7
+ title: (msg) => console.log(chalk.bold.cyan(`\n${msg}\n`)),
8
+ dim: (msg) => console.log(chalk.dim(msg)),
9
+ };
10
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;IAC3D,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAClE,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;IAC7D,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC;IAC5D,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAClE,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAClD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "listen-agent",
3
+ "version": "1.0.2",
4
+ "description": "CLI to manage and install agent skills for AI coding assistants",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "listen-agent": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "templates/",
13
+ "skills/",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "dev": "tsx src/index.ts",
20
+ "start": "node dist/index.js",
21
+ "prepare": "npm run build",
22
+ "prepublishOnly": "npm run build",
23
+ "test": "echo \"No tests specified\" && exit 0",
24
+ "lint": "echo \"No linting configured\" && exit 0",
25
+ "type-check": "tsc --noEmit"
26
+ },
27
+ "keywords": [
28
+ "agent",
29
+ "skills",
30
+ "cli",
31
+ "ai",
32
+ "assistant",
33
+ "agent-skills",
34
+ "claude",
35
+ "cursor",
36
+ "windsurf",
37
+ "kiro",
38
+ "automation",
39
+ "workflow"
40
+ ],
41
+ "author": "",
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/lsiten/listen-agent-skills.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/lsiten/listen-agent-skills/issues"
49
+ },
50
+ "homepage": "https://github.com/lsiten/listen-agent-skills#readme",
51
+ "engines": {
52
+ "node": ">=16.0.0"
53
+ },
54
+ "dependencies": {
55
+ "commander": "^11.1.0",
56
+ "prompts": "^2.4.2",
57
+ "chalk": "^5.3.0",
58
+ "ora": "^7.0.1"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^20.10.0",
62
+ "@types/prompts": "^2.4.9",
63
+ "tsx": "^4.6.0",
64
+ "typescript": "^5.3.0"
65
+ }
66
+ }
@@ -0,0 +1,152 @@
1
+ # Mac M4 LoRA自动化训练 Skill
2
+
3
+ ## 描述
4
+
5
+ 专为Mac M4芯片优化的LoRA(Low-Rank Adaptation)自动化训练工具,支持无GUI操作、参数自动调优、MPS加速和自然语言反馈优化。
6
+
7
+ ## 核心特性
8
+
9
+ - 🚀 **M4芯片专属优化** - 完全适配ARM架构和MPS加速
10
+ - 🧠 **智能参数调优** - 基于自然语言反馈自动调整训练参数
11
+ - 📊 **自动化流程** - 从数据准备到模型部署的完整自动化
12
+ - 💾 **显存优化** - 针对M4共享内存架构的显存管理策略
13
+ - 🔄 **ComfyUI集成** - 训练完成自动拷贝到ComfyUI目录
14
+ - 📝 **CSV自动打标** - 自动生成训练数据标注文件
15
+
16
+ ## 系统要求
17
+
18
+ ### 硬件要求
19
+ - **机型**: Mac M4 Pro/Max/Ultra
20
+ - **内存**: ≥16GB(推荐32GB+)
21
+ - **存储**: ≥50GB可用空间
22
+ - **系统**: macOS 13.0+
23
+
24
+ ### 软件依赖
25
+ - Python 3.10+
26
+ - PyTorch (MPS版本)
27
+ - sd-scripts
28
+ - transformers
29
+ - CLIP模型
30
+
31
+ ## 安装指南
32
+
33
+ ### 1. 环境准备
34
+
35
+ ```bash
36
+ # 安装Homebrew
37
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
38
+
39
+ # 安装Python 3.10
40
+ brew install python@3.10
41
+
42
+ # 创建虚拟环境
43
+ python3.10 -m venv auto_lora_train_venv
44
+ source auto_lora_train_venv/bin/activate
45
+ ```
46
+
47
+ ### 2. 依赖安装
48
+
49
+ ```bash
50
+ # 安装PyTorch MPS版本
51
+ pip3 install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 --index-url https://download.pytorch.org/whl/cpu
52
+
53
+ # 克隆sd-scripts
54
+ git clone https://github.com/kohya-ss/sd-scripts.git
55
+ cd sd-scripts
56
+
57
+ # 安装依赖
58
+ pip install -r requirements.txt
59
+ pip install -r requirements-macos.txt
60
+ pip install pillow==9.5.0 transformers==4.30.2 accelerate==0.21.0 argparse==1.4.0
61
+ ```
62
+
63
+ ### 3. 目录结构
64
+
65
+ ```
66
+ sd-scripts/
67
+ ├─ models/
68
+ │ ├─ base_model/ # 基础模型文件
69
+ │ └─ vae/ # VAE模型文件
70
+ ├─ configs/
71
+ │ └─ Qwen-Image-2512-mps.yaml # 模型配置
72
+ ├─ auto_lora_train_mps.py # 主训练脚本
73
+ └─ my_train_images/ # 训练图片目录
74
+ ```
75
+
76
+ ## 使用方法
77
+
78
+ ### 基础训练命令
79
+
80
+ ```bash
81
+ python auto_lora_train_mps.py \
82
+ --train_dir "./my_train_images" \
83
+ --lora_name "my_character_lora" \
84
+ --comfyui_lora_dir "/Users/用户名/ComfyUI/models/Loras" \
85
+ --trigger_word "ai_character"
86
+ ```
87
+
88
+ ### 带反馈调参训练
89
+
90
+ ```bash
91
+ python auto_lora_train_mps.py \
92
+ --train_dir "./my_train_images" \
93
+ --lora_name "my_character_lora_v2" \
94
+ --comfyui_lora_dir "/Users/用户名/ComfyUI/models/Loras" \
95
+ --trigger_word "ai_character" \
96
+ --feedback "角色特征不明显"
97
+ ```
98
+
99
+ ### 参数说明
100
+
101
+ - `--train_dir`: 训练图片目录路径
102
+ - `--lora_name`: LoRA模型名称(不含后缀)
103
+ - `--comfyui_lora_dir`: ComfyUI的LoRA模型目录
104
+ - `--trigger_word`: LoRA触发词
105
+ - `--feedback`: 自然语言反馈(可选)
106
+ - `--ref_img`: 参考图片路径(可选)
107
+
108
+ ## 反馈关键词与参数调整
109
+
110
+ | 反馈关键词 | 参数调整策略 |
111
+ |------------|--------------|
112
+ | "特征不明显" | 增加network_dim、延长训练轮数、提高学习率 |
113
+ | "风格偏差大" | 降低学习率、减少训练轮数、调整clip_skip |
114
+ | "显存不足" | 减少批次大小、降低network_dim、启用梯度检查点 |
115
+ | "过拟合" | 降低学习率、减少训练轮数、增加批次大小 |
116
+
117
+ ## M4专属优化
118
+
119
+ ### 显存优化策略
120
+ - `network_dim` 最大不超过64
121
+ - `train_batch_size` 建议1-2(M4 Max可尝试3)
122
+ - 必须启用 `--gradient_checkpointing` 和 `--lowram`
123
+ - 训练时关闭其他大型软件
124
+
125
+ ### 性能调优
126
+ - 使用混合精度训练(fp16)
127
+ - 启用梯度检查点节省显存
128
+ - 优化批次大小平衡速度与稳定性
129
+
130
+ ## 常见问题解决
131
+
132
+ | 问题 | 解决方案 |
133
+ |------|----------|
134
+ | MPS设备未找到 | 确认macOS≥13.0,验证PyTorch MPS支持 |
135
+ | 训练速度慢 | 降低network_dim/批次,启用混合精度 |
136
+ | 模型拷贝失败 | 检查ComfyUI目录权限 |
137
+ | CLIP评估报错 | 降级transformers到4.30.2 |
138
+
139
+ ## 扩展功能
140
+
141
+ - **多轮迭代训练**: 支持循环反馈和持续调参
142
+ - **训练监控**: 输出详细日志和loss曲线
143
+ - **批量处理**: 支持多数据集并行训练
144
+ - **提示词优化**: 自动生成高质量触发词
145
+
146
+ ## 技术架构
147
+
148
+ - **核心框架**: sd-scripts + PyTorch MPS
149
+ - **模型支持**: Stable Diffusion 2.x系列
150
+ - **加速技术**: MPS (Metal Performance Shaders)
151
+ - **评估工具**: CLIP相似度评估
152
+ - **自动化**: 端到端训练部署流程