aico-cli 2.0.28 → 2.0.30
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/bin/cli/LICENSE.md +1 -0
- package/bin/cli/cli.js +2920 -2457
- package/bin/cli/package.json +1 -1
- package/bin/cli/sdk-tools.d.ts +1216 -3
- package/dist/chunks/simple-config.mjs +527 -43
- package/dist/cli.mjs +126 -481
- package/dist/index.mjs +1 -0
- package/package.json +11 -3
- package/templates/agents/agent-capability-map.json +598 -0
- package/templates/agents/agent-selector.ts +991 -0
- package/templates/agents/auto-task-executor.ts +222 -0
- package/templates/agents/bonus/studio-coach.md +133 -0
- package/templates/agents/core/code-archaeologist.md +89 -0
- package/templates/agents/core/code-reviewer.md +88 -0
- package/templates/agents/core/documentation-specialist.md +100 -0
- package/templates/agents/core/performance-optimizer.md +67 -0
- package/templates/agents/databases/customer-support.md +34 -0
- package/templates/agents/databases/data-engineer.md +31 -0
- package/templates/agents/databases/data-scientist.md +28 -0
- package/templates/agents/databases/database-admin.md +31 -0
- package/templates/agents/databases/database-optimizer.md +31 -0
- package/templates/agents/deployment/debugger.md +29 -0
- package/templates/agents/deployment/deployment-engineer.md +31 -0
- package/templates/agents/deployment/devops-troubleshooter.md +31 -0
- package/templates/agents/deployment/dx-optimizer.md +62 -0
- package/templates/agents/deployment/error-detective.md +31 -0
- package/templates/agents/deployment/legacy-modernizer.md +31 -0
- package/templates/agents/deployment/network-engineer.md +31 -0
- package/templates/agents/deployment/payment-integration.md +31 -0
- package/templates/agents/deployment/performance-engineer.md +31 -0
- package/templates/agents/deployment/prompt-engineer.md +58 -0
- package/templates/agents/deployment/quant-analyst.md +31 -0
- package/templates/agents/deployment/refactor-agent.md +77 -0
- package/templates/agents/deployment/risk-manager.md +40 -0
- package/templates/agents/deployment/sales-automator.md +34 -0
- package/templates/agents/deployment/search-specialist.md +96 -0
- package/templates/agents/deployment/security-auditor.md +31 -0
- package/templates/agents/design/brand-guardian.md +278 -0
- package/templates/agents/design/frontend-analyst.md +42 -0
- package/templates/agents/design/ui-designer.md +157 -0
- package/templates/agents/design/ui-ux-master.md +568 -0
- package/templates/agents/design/ux-researcher.md +210 -0
- package/templates/agents/design/visual-storyteller.md +271 -0
- package/templates/agents/design/whimsy-injector.md +148 -0
- package/templates/agents/engineering/backend/ai-engineer.md +118 -0
- package/templates/agents/engineering/backend/backend-architect.md +95 -0
- package/templates/agents/engineering/backend/senior-backend-architect.md +554 -0
- package/templates/agents/engineering/frontend/frontend-developer.md +105 -0
- package/templates/agents/engineering/frontend/mobile-app-builder.md +108 -0
- package/templates/agents/engineering/frontend/rapid-prototyper.md +114 -0
- package/templates/agents/engineering/frontend/senior-frontend-architect.md +573 -0
- package/templates/agents/engineering/middlend/api-documenter.md +31 -0
- package/templates/agents/engineering/middlend/architect-review.md +41 -0
- package/templates/agents/engineering/middlend/cloud-architect.md +31 -0
- package/templates/agents/engineering/middlend/code-reviewer.md +28 -0
- package/templates/agents/engineering/middlend/devops-automator.md +118 -0
- package/templates/agents/marketing/app-store-optimizer.md +180 -0
- package/templates/agents/marketing/business-analyst.md +34 -0
- package/templates/agents/marketing/content-creator.md +209 -0
- package/templates/agents/marketing/growth-hacker.md +218 -0
- package/templates/agents/marketing/instagram-curator.md +154 -0
- package/templates/agents/marketing/reddit-community-builder.md +197 -0
- package/templates/agents/marketing/tiktok-strategist.md +151 -0
- package/templates/agents/marketing/twitter-engager.md +175 -0
- package/templates/agents/orchestrators/context-manager.md +63 -0
- package/templates/agents/orchestrators/project-analyst.md +66 -0
- package/templates/agents/orchestrators/team-configurator.md +52 -0
- package/templates/agents/orchestrators/tech-lead-orchestrator.md +103 -0
- package/templates/agents/product/feedback-synthesizer.md +174 -0
- package/templates/agents/product/sprint-prioritizer.md +128 -0
- package/templates/agents/product/trend-researcher.md +133 -0
- package/templates/agents/project-management/experiment-tracker.md +165 -0
- package/templates/agents/project-management/project-shipper.md +190 -0
- package/templates/agents/project-management/studio-producer.md +203 -0
- package/templates/agents/specialist/spec-analyst.md +228 -0
- package/templates/agents/specialist/spec-architect.md +375 -0
- package/templates/agents/specialist/spec-developer.md +544 -0
- package/templates/agents/specialist/spec-orchestrator.md +465 -0
- package/templates/agents/specialist/spec-planner.md +497 -0
- package/templates/agents/specialist/spec-reviewer.md +487 -0
- package/templates/agents/specialist/spec-task-reviewer.md +50 -0
- package/templates/agents/specialist/spec-tester.md +652 -0
- package/templates/agents/specialist/spec-validator.md +441 -0
- package/templates/agents/specialized/C++/cpp-pro.md +37 -0
- package/templates/agents/specialized/Golang/golang-pro.md +31 -0
- package/templates/agents/specialized/JavaScript/javascript-pro.md +34 -0
- package/templates/agents/specialized/Python/python-pro.md +31 -0
- package/templates/agents/specialized/databases/sql-pro.md +34 -0
- package/templates/agents/specialized/django/django-api-developer.md +804 -0
- package/templates/agents/specialized/django/django-backend-expert.md +875 -0
- package/templates/agents/specialized/django/django-orm-expert.md +828 -0
- package/templates/agents/specialized/laravel/laravel-backend-expert.md +174 -0
- package/templates/agents/specialized/laravel/laravel-eloquent-expert.md +75 -0
- package/templates/agents/specialized/rails/rails-activerecord-expert.md +690 -0
- package/templates/agents/specialized/rails/rails-api-developer.md +943 -0
- package/templates/agents/specialized/rails/rails-backend-expert.md +876 -0
- package/templates/agents/specialized/react/react-component-architect.md +41 -0
- package/templates/agents/specialized/react/react-nextjs-expert.md +141 -0
- package/templates/agents/specialized/vue/vue-component-architect.md +98 -0
- package/templates/agents/specialized/vue/vue-nuxt-expert.md +720 -0
- package/templates/agents/specialized/vue/vue-state-manager.md +33 -0
- package/templates/agents/studio-operations/analytics-reporter.md +204 -0
- package/templates/agents/studio-operations/finance-tracker.md +293 -0
- package/templates/agents/studio-operations/infrastructure-maintainer.md +219 -0
- package/templates/agents/studio-operations/legal-compliance-checker.md +259 -0
- package/templates/agents/studio-operations/support-responder.md +166 -0
- package/templates/agents/task-execution-agent.ts +160 -0
- package/templates/agents/testing/api-tester.md +214 -0
- package/templates/agents/testing/integration-test-fixer.md +52 -0
- package/templates/agents/testing/performance-benchmarker.md +277 -0
- package/templates/agents/testing/test-automator.md +31 -0
- package/templates/agents/testing/test-results-analyzer.md +273 -0
- package/templates/agents/testing/test-writer-fixer.md +129 -0
- package/templates/agents/testing/tool-evaluator.md +184 -0
- package/templates/agents/testing/workflow-optimizer.md +239 -0
- package/templates/agents/universal/api-architect.md +84 -0
- package/templates/agents/universal/backend-developer.md +95 -0
- package/templates/agents/universal/frontend-developer.md +66 -0
- package/templates/agents/universal/tailwind-css-expert.md +84 -0
- package/templates/cursor.md +20 -14
- package/templates/hooks/claude-code-hooks.json +13 -9
- package/templates/hooks/hook-wrapper.ts +173 -0
- package/templates/hooks/install-hooks.ts +201 -0
- package/templates/hooks/scripts/Notification/desktop-notifier.ts +268 -0
- package/templates/hooks/scripts/Notification/notification.ts +28 -0
- package/templates/hooks/scripts/PostToolUse/code-formatter.ts +182 -0
- package/templates/hooks/scripts/PostToolUse/post-tool-use.ts +27 -0
- package/templates/hooks/scripts/PreToolUse/command-logger.ts +107 -0
- package/templates/hooks/scripts/PreToolUse/file-protection.ts +109 -0
- package/templates/hooks/scripts/PreToolUse/pre-tool-use.ts +42 -0
- package/templates/hooks/scripts/Stop/session-summary.ts +150 -0
- package/templates/hooks/scripts/Stop/stop.ts +17 -0
- package/templates/hooks/scripts/UserPromptSubmit/input-notifier.ts +139 -0
- package/templates/hooks/scripts/UserPromptSubmit/user-prompt-submit.ts +16 -0
- package/templates/hooks/test-hook.ts +171 -0
- package/templates/hooks/tsconfig.json +27 -0
- package/templates/hooks/utils/execution-utils.ts +176 -0
- package/templates/hooks/utils/file-utils.ts +256 -0
- package/templates/hooks/utils/hook-utils.ts +86 -0
- package/templates/hooks/utils/index.ts +42 -0
- package/templates/personality.md +19 -14
- package/templates/settings.json +27 -4
- package/dist/chunks/run-command.mjs +0 -48
- package/templates/agents/base/frontend-designer.md +0 -193
- package/templates/commands/base//344/270/223/345/256/266/347/273/204/345/210/206/346/236/220/346/231/272/350/203/275/344/275/223.md +0 -82
- package/templates/hooks/scripts/Notification/bash/desktop-notifier.sh +0 -63
- package/templates/hooks/scripts/Notification/powershell/desktop-notifier.ps1 +0 -67
- package/templates/hooks/scripts/PostToolUse/bash/code-formatter.sh +0 -73
- package/templates/hooks/scripts/PostToolUse/powershell/code-formatter.ps1 +0 -90
- package/templates/hooks/scripts/PreToolUse/bash/command-logger.sh +0 -38
- package/templates/hooks/scripts/PreToolUse/bash/file-protection.sh +0 -55
- package/templates/hooks/scripts/PreToolUse/powershell/command-logger.ps1 +0 -34
- package/templates/hooks/scripts/PreToolUse/powershell/file-protection.ps1 +0 -46
- package/templates/hooks/scripts/Stop/bash/session-summary.sh +0 -83
- package/templates/hooks/scripts/Stop/powershell/session-summary.ps1 +0 -125
- package/templates/hooks/scripts/UserPromptSubmit/bash/input-notifier.sh +0 -58
- package/templates/hooks/scripts/UserPromptSubmit/powershell/input-notifier.ps1 +0 -85
- package/templates/skills/slack-gif-creator/LICENSE.txt +0 -202
- package/templates/skills/slack-gif-creator/SKILL.md +0 -646
- package/templates/skills/slack-gif-creator/core/color_palettes.py +0 -302
- package/templates/skills/slack-gif-creator/core/easing.py +0 -230
- package/templates/skills/slack-gif-creator/core/frame_composer.py +0 -469
- package/templates/skills/slack-gif-creator/core/gif_builder.py +0 -246
- package/templates/skills/slack-gif-creator/core/typography.py +0 -357
- package/templates/skills/slack-gif-creator/core/validators.py +0 -264
- package/templates/skills/slack-gif-creator/core/visual_effects.py +0 -494
- package/templates/skills/slack-gif-creator/requirements.txt +0 -4
- package/templates/skills/slack-gif-creator/templates/bounce.py +0 -106
- package/templates/skills/slack-gif-creator/templates/explode.py +0 -331
- package/templates/skills/slack-gif-creator/templates/fade.py +0 -329
- package/templates/skills/slack-gif-creator/templates/flip.py +0 -291
- package/templates/skills/slack-gif-creator/templates/kaleidoscope.py +0 -211
- package/templates/skills/slack-gif-creator/templates/morph.py +0 -329
- package/templates/skills/slack-gif-creator/templates/move.py +0 -293
- package/templates/skills/slack-gif-creator/templates/pulse.py +0 -268
- package/templates/skills/slack-gif-creator/templates/shake.py +0 -127
- package/templates/skills/slack-gif-creator/templates/slide.py +0 -291
- package/templates/skills/slack-gif-creator/templates/spin.py +0 -269
- package/templates/skills/slack-gif-creator/templates/wiggle.py +0 -300
- package/templates/skills/slack-gif-creator/templates/zoom.py +0 -312
- package/templates/skills/swimlane-diagram/README.md +0 -373
- package/templates/skills/swimlane-diagram/SKILL.md +0 -242
- package/templates/skills/swimlane-diagram/examples.md +0 -405
- package/templates/skills/swimlane-diagram/generators.mjs +0 -258
- package/templates/skills/swimlane-diagram/package.json +0 -126
- package/templates/skills/swimlane-diagram/reference.md +0 -368
- package/templates/skills/swimlane-diagram/swimlane-diagram.mjs +0 -215
- package/templates/skills/swimlane-diagram/swimlane-diagram.test.mjs +0 -358
- package/templates/skills/swimlane-diagram/validators.mjs +0 -291
- package/templates/skills/theme-factory/LICENSE.txt +0 -202
- package/templates/skills/theme-factory/SKILL.md +0 -59
- package/templates/skills/theme-factory/theme-showcase.pdf +0 -0
- package/templates/skills/theme-factory/themes/arctic-frost.md +0 -19
- package/templates/skills/theme-factory/themes/botanical-garden.md +0 -19
- package/templates/skills/theme-factory/themes/desert-rose.md +0 -19
- package/templates/skills/theme-factory/themes/forest-canopy.md +0 -19
- package/templates/skills/theme-factory/themes/golden-hour.md +0 -19
- package/templates/skills/theme-factory/themes/midnight-galaxy.md +0 -19
- package/templates/skills/theme-factory/themes/modern-minimalist.md +0 -19
- package/templates/skills/theme-factory/themes/ocean-depths.md +0 -19
- package/templates/skills/theme-factory/themes/sunset-boulevard.md +0 -19
- package/templates/skills/theme-factory/themes/tech-innovation.md +0 -19
- /package/templates/agents/{code//346/240/271/346/234/254/345/216/237/345/233/240/345/210/206/346/236/220/345/270/210.md" → core/root-cause-analyst.md} +0 -0
- /package/templates/agents/{code//346/212/200/346/234/257/346/226/207/346/241/243/345/267/245/347/250/213/345/270/210.md" → core/technical-writer.md} +0 -0
- /package/templates/agents/{code//346/200/247/350/203/275/345/210/206/346/236/220/344/270/223/345/256/266.md" → deployment/performance-analyst.md} +0 -0
- /package/templates/agents/{code//345/256/211/345/205/250/346/274/217/346/264/236/350/257/206/345/210/253/344/270/223/345/256/266.md" → deployment/security-engineer.md} +0 -0
- /package/templates/agents/{code//347/263/273/347/273/237/346/236/266/346/236/204/345/270/210.md" → engineering/middlend/architect.md} +0 -0
- /package/templates/agents/{code/python/345/274/200/345/217/221/344/270/223/345/256/266.md" → specialized/Python/python-expert.md} +0 -0
- /package/templates/agents/{code//350/264/250/351/207/217/350/257/204/344/274/260/345/267/245/347/250/213/345/270/210.md" → testing/quality-engineer.md} +0 -0
- /package/templates/agents/{base → universal}/panel-experts.md +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"description": "跨平台 Hooks 配置 - TypeScript 实现,兼容 Windows, Linux, macOS",
|
|
4
|
+
"version": "2.0.0",
|
|
3
5
|
"hooks": {
|
|
4
6
|
"PreToolUse": [
|
|
5
7
|
{
|
|
@@ -7,51 +9,53 @@
|
|
|
7
9
|
"hooks": [
|
|
8
10
|
{
|
|
9
11
|
"type": "command",
|
|
10
|
-
"command":
|
|
12
|
+
"command": "node -e \"require('child_process').execSync('npx tsx ' + require('path').join(require('os').homedir(), '.claude/hooks/scripts/PreToolUse/pre-tool-use.ts'), {stdio: 'inherit'})\"",
|
|
13
|
+
"timeout": 10
|
|
11
14
|
}
|
|
12
15
|
]
|
|
13
16
|
}
|
|
14
17
|
],
|
|
15
|
-
"PostToolUse":
|
|
18
|
+
"PostToolUse":[
|
|
16
19
|
{
|
|
17
20
|
"matcher": "Edit|Write",
|
|
18
21
|
"hooks": [
|
|
19
22
|
{
|
|
20
23
|
"type": "command",
|
|
21
|
-
"command":
|
|
24
|
+
"command": "node -e \"require('child_process').execSync('npx tsx ' + require('path').join(require('os').homedir(), '.claude/hooks/scripts/PostToolUse/post-tool-use.ts'), {stdio: 'inherit'})\"",
|
|
25
|
+
"timeout": 10
|
|
22
26
|
}
|
|
23
27
|
]
|
|
24
28
|
}
|
|
25
29
|
],
|
|
26
30
|
"UserPromptSubmit": [
|
|
27
31
|
{
|
|
28
|
-
"matcher": "",
|
|
29
32
|
"hooks": [
|
|
30
33
|
{
|
|
31
34
|
"type": "command",
|
|
32
|
-
"command": "
|
|
35
|
+
"command": "node -e \"require('child_process').execSync('npx tsx ' + require('path').join(require('os').homedir(), '.claude/hooks/scripts/UserPromptSubmit/user-prompt-submit.ts'), {stdio: 'inherit'})\"",
|
|
36
|
+
"timeout": 10
|
|
33
37
|
}
|
|
34
38
|
]
|
|
35
39
|
}
|
|
36
40
|
],
|
|
37
41
|
"Notification": [
|
|
38
42
|
{
|
|
39
|
-
"matcher": "",
|
|
40
43
|
"hooks": [
|
|
41
44
|
{
|
|
42
45
|
"type": "command",
|
|
43
|
-
"command": "
|
|
46
|
+
"command": "node -e \"require('child_process').execSync('npx tsx ' + require('path').join(require('os').homedir(), '.claude/hooks/scripts/Notification/notification.ts'), {stdio: 'inherit'})\"",
|
|
47
|
+
"timeout": 10
|
|
44
48
|
}
|
|
45
49
|
]
|
|
46
50
|
}
|
|
47
51
|
],
|
|
48
52
|
"Stop": [
|
|
49
53
|
{
|
|
50
|
-
"matcher": "",
|
|
51
54
|
"hooks": [
|
|
52
55
|
{
|
|
53
56
|
"type": "command",
|
|
54
|
-
"command": "
|
|
57
|
+
"command": "node -e \"require('child_process').execSync('npx tsx ' + require('path').join(require('os').homedir(), '.claude/hooks/scripts/Stop/stop.ts'), {stdio: 'inherit'})\"",
|
|
58
|
+
"timeout": 10
|
|
55
59
|
}
|
|
56
60
|
]
|
|
57
61
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* 跨平台 Hook 包装脚本 (TypeScript)
|
|
4
|
+
* 兼容 Windows, Linux, macOS
|
|
5
|
+
*
|
|
6
|
+
* 使用方法:
|
|
7
|
+
* ts-node hook-wrapper.ts <HookType> [matcher]
|
|
8
|
+
* node hook-wrapper.js <HookType> [matcher]
|
|
9
|
+
*
|
|
10
|
+
* 示例:
|
|
11
|
+
* ts-node hook-wrapper.ts UserPromptSubmit
|
|
12
|
+
* ts-node hook-wrapper.ts PreToolUse Bash
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { spawn, SpawnOptions } from 'child_process';
|
|
18
|
+
import * as os from 'os';
|
|
19
|
+
|
|
20
|
+
// 类型定义
|
|
21
|
+
type Platform = 'win32' | 'darwin' | 'linux' | 'aix' | 'freebsd' | 'openbsd' | 'sunos';
|
|
22
|
+
type HookType = 'UserPromptSubmit' | 'PreToolUse' | 'PostToolUse' | 'Notification' | 'Stop';
|
|
23
|
+
|
|
24
|
+
interface HookConfig {
|
|
25
|
+
hookType: HookType;
|
|
26
|
+
matcher: string;
|
|
27
|
+
platform: Platform;
|
|
28
|
+
isWindows: boolean;
|
|
29
|
+
isMac: boolean;
|
|
30
|
+
isLinux: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 获取命令行参数
|
|
34
|
+
const hookType = process.argv[2] as HookType;
|
|
35
|
+
const matcher = process.argv[3] || '';
|
|
36
|
+
|
|
37
|
+
// 检测操作系统
|
|
38
|
+
const platform = os.platform() as Platform;
|
|
39
|
+
const isWindows = platform === 'win32';
|
|
40
|
+
const isMac = platform === 'darwin';
|
|
41
|
+
const isLinux = platform === 'linux';
|
|
42
|
+
|
|
43
|
+
// 获取 hooks 目录路径(跨平台)
|
|
44
|
+
function getHooksDir(): string {
|
|
45
|
+
const homeDir = os.homedir();
|
|
46
|
+
return path.join(homeDir, '.claude', 'hooks');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 获取日志目录
|
|
50
|
+
function getLogDir(): string {
|
|
51
|
+
const hooksDir = getHooksDir();
|
|
52
|
+
const logDir = path.join(hooksDir, 'logs');
|
|
53
|
+
|
|
54
|
+
// 确保日志目录存在
|
|
55
|
+
if (!fs.existsSync(logDir)) {
|
|
56
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return logDir;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 日志记录函数
|
|
63
|
+
function log(level: 'INFO' | 'WARN' | 'ERROR', message: string): void {
|
|
64
|
+
const timestamp = new Date().toISOString();
|
|
65
|
+
const logFile = path.join(getLogDir(), 'hook-execution.log');
|
|
66
|
+
const logEntry = `[${timestamp}] [${level}] [${hookType}] ${message}\n`;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
fs.appendFileSync(logFile, logEntry);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
// Log write failed silently
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 执行平台特定的脚本
|
|
76
|
+
function executeHook(config: HookConfig): void {
|
|
77
|
+
log('INFO', `Starting hook execution on ${config.platform}`);
|
|
78
|
+
|
|
79
|
+
const hooksDir = getHooksDir();
|
|
80
|
+
const scriptsDir = path.join(hooksDir, 'scripts', config.hookType);
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
// 根据平台选择执行不同的脚本
|
|
84
|
+
if (config.isWindows) {
|
|
85
|
+
executeWindowsHook(scriptsDir, config);
|
|
86
|
+
} else {
|
|
87
|
+
executeUnixHook(scriptsDir, config);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 快速退出,不等待脚本完成
|
|
91
|
+
process.exit(0);
|
|
92
|
+
|
|
93
|
+
} catch (err) {
|
|
94
|
+
log('ERROR', `Hook execution failed: ${(err as Error).message}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 执行 Windows PowerShell 脚本
|
|
100
|
+
function executeWindowsHook(scriptsDir: string, config: HookConfig): void {
|
|
101
|
+
const psScript = path.join(scriptsDir, 'powershell', `${config.hookType.toLowerCase()}.ps1`);
|
|
102
|
+
|
|
103
|
+
if (fs.existsSync(psScript)) {
|
|
104
|
+
log('INFO', `Executing PowerShell script: ${psScript}`);
|
|
105
|
+
|
|
106
|
+
const spawnOptions: SpawnOptions = {
|
|
107
|
+
detached: true,
|
|
108
|
+
stdio: 'ignore'
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const child = spawn('powershell.exe', [
|
|
112
|
+
'-NoProfile',
|
|
113
|
+
'-ExecutionPolicy', 'Bypass',
|
|
114
|
+
'-File', psScript,
|
|
115
|
+
config.matcher
|
|
116
|
+
], spawnOptions);
|
|
117
|
+
|
|
118
|
+
child.unref();
|
|
119
|
+
log('INFO', 'PowerShell script started successfully');
|
|
120
|
+
} else {
|
|
121
|
+
log('WARN', `PowerShell script not found: ${psScript}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 执行 Unix Shell 脚本
|
|
126
|
+
function executeUnixHook(scriptsDir: string, config: HookConfig): void {
|
|
127
|
+
const shScript = path.join(scriptsDir, 'bash', `${config.hookType.toLowerCase()}.sh`);
|
|
128
|
+
|
|
129
|
+
if (fs.existsSync(shScript)) {
|
|
130
|
+
log('INFO', `Executing shell script: ${shScript}`);
|
|
131
|
+
|
|
132
|
+
// 确保脚本有执行权限
|
|
133
|
+
try {
|
|
134
|
+
fs.chmodSync(shScript, '755');
|
|
135
|
+
} catch (err) {
|
|
136
|
+
log('WARN', `Failed to chmod script: ${(err as Error).message}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const spawnOptions: SpawnOptions = {
|
|
140
|
+
detached: true,
|
|
141
|
+
stdio: 'ignore'
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const child = spawn('/bin/bash', [shScript, config.matcher], spawnOptions);
|
|
145
|
+
|
|
146
|
+
child.unref();
|
|
147
|
+
log('INFO', 'Shell script started successfully');
|
|
148
|
+
} else {
|
|
149
|
+
log('WARN', `Shell script not found: ${shScript}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 主函数
|
|
154
|
+
function main(): void {
|
|
155
|
+
if (!hookType) {
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const config: HookConfig = {
|
|
160
|
+
hookType,
|
|
161
|
+
matcher,
|
|
162
|
+
platform,
|
|
163
|
+
isWindows,
|
|
164
|
+
isMac,
|
|
165
|
+
isLinux
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
log('INFO', `Platform: ${platform}, Hook: ${hookType}, Matcher: ${matcher || 'none'}`);
|
|
169
|
+
executeHook(config);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 执行主函数
|
|
173
|
+
main();
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* 跨平台 Hooks 安装脚本 (TypeScript)
|
|
4
|
+
* 自动检测操作系统并安装相应的 hook 脚本
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
|
|
11
|
+
// 类型定义
|
|
12
|
+
type Platform = 'win32' | 'darwin' | 'linux' | 'aix' | 'freebsd' | 'openbsd' | 'sunos';
|
|
13
|
+
type HookType = 'UserPromptSubmit' | 'PreToolUse' | 'PostToolUse' | 'Notification' | 'Stop';
|
|
14
|
+
|
|
15
|
+
interface InstallConfig {
|
|
16
|
+
platform: Platform;
|
|
17
|
+
homeDir: string;
|
|
18
|
+
hooksDir: string;
|
|
19
|
+
isWindows: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const platform = os.platform() as Platform;
|
|
23
|
+
const homeDir = os.homedir();
|
|
24
|
+
const hooksDir = path.join(homeDir, '.claude', 'hooks');
|
|
25
|
+
|
|
26
|
+
const hook_types = ['UserPromptSubmit', 'PreToolUse', 'PostToolUse',
|
|
27
|
+
'Notification', 'Stop'];
|
|
28
|
+
const hook_scr_name = ['user-prompt-submit', 'pre-tool-use',
|
|
29
|
+
'post-tool-use', 'notification', 'stop'];
|
|
30
|
+
const execution_scr_name = ['input-notifier', 'file-protection',
|
|
31
|
+
'code-formatter', 'desktop-notifier', 'session-summary'];
|
|
32
|
+
|
|
33
|
+
const hookScriptMap = new Map<string, any>();
|
|
34
|
+
const executionScriptMap = new Map<string, any>();
|
|
35
|
+
|
|
36
|
+
// 确保数组长度一致
|
|
37
|
+
if (hook_types.length === hook_scr_name.length && hook_types.length === execution_scr_name.length) {
|
|
38
|
+
for (let i = 0; i < hook_types.length; i++) {
|
|
39
|
+
hookScriptMap.set(hook_types[i], hook_scr_name[i]);
|
|
40
|
+
executionScriptMap.set(hook_types[i], execution_scr_name[i]);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
throw new Error('Keys and values arrays must have the same length');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// 创建必要的目录结构
|
|
48
|
+
function createDirectories(config: InstallConfig): void {
|
|
49
|
+
const dirs: string[] = [
|
|
50
|
+
config.hooksDir,
|
|
51
|
+
path.join(config.hooksDir, 'scripts'),
|
|
52
|
+
path.join(config.hooksDir, 'logs'),
|
|
53
|
+
path.join(config.hooksDir, 'utils'),
|
|
54
|
+
path.join(config.hooksDir, 'scripts', 'UserPromptSubmit'),
|
|
55
|
+
path.join(config.hooksDir, 'scripts', 'PreToolUse'),
|
|
56
|
+
path.join(config.hooksDir, 'scripts', 'PostToolUse'),
|
|
57
|
+
path.join(config.hooksDir, 'scripts', 'Notification'),
|
|
58
|
+
path.join(config.hooksDir, 'scripts', 'Stop')
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
// 根据平台创建特定子目录
|
|
62
|
+
const hookTypes: HookType[] = ['UserPromptSubmit', 'PreToolUse', 'PostToolUse', 'Notification', 'Stop'];
|
|
63
|
+
|
|
64
|
+
dirs.forEach(dir => {
|
|
65
|
+
if (!fs.existsSync(dir)) {
|
|
66
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Hook包装脚本的复制
|
|
72
|
+
function copyWrapperScript(config: InstallConfig): void {
|
|
73
|
+
const tsSource = path.join(__dirname, 'hook-wrapper.ts');
|
|
74
|
+
const tsDest = path.join(config.hooksDir, 'scripts', 'hook-wrapper.ts');
|
|
75
|
+
|
|
76
|
+
if (fs.existsSync(tsSource)) {
|
|
77
|
+
fs.copyFileSync(tsSource, tsDest);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 创建 hook 脚本至homeDir/.claude/hooks/scripts下
|
|
82
|
+
function copyScriptsToHomeDir(config: InstallConfig): void {
|
|
83
|
+
const hookTypes: HookType[] = ['UserPromptSubmit', 'PreToolUse', 'PostToolUse', 'Notification', 'Stop'];
|
|
84
|
+
|
|
85
|
+
// 创建系统环境兼容的typescript脚本
|
|
86
|
+
hookTypes.forEach(type => {
|
|
87
|
+
const sourceHooksScriptPath = path.join(__dirname, 'scripts', type);
|
|
88
|
+
const targetHooksScriptPath = path.join(config.hooksDir, 'scripts', type);
|
|
89
|
+
|
|
90
|
+
if(fs.existsSync(sourceHooksScriptPath)){
|
|
91
|
+
if(!fs.existsSync(targetHooksScriptPath)){
|
|
92
|
+
//确保目标目录存在
|
|
93
|
+
fs.mkdirSync(targetHooksScriptPath, {recursive: true});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 读取目录下所有文件
|
|
97
|
+
const files = fs.readdirSync(sourceHooksScriptPath);
|
|
98
|
+
// 遍历并复制所有.ts文件
|
|
99
|
+
files.forEach(file => {
|
|
100
|
+
if(file.endsWith('.ts')){
|
|
101
|
+
const sourceFile = path.join(sourceHooksScriptPath, file);
|
|
102
|
+
const targetFile = path.join(targetHooksScriptPath, file);
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
fs.copyFileSync(sourceFile, targetFile);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
// Copy failed silently
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
//复制工具类至用户主目录
|
|
115
|
+
const sourceUtilsPath = path.join(__dirname, 'utils');
|
|
116
|
+
const targetUtilsPath = path.join(config.hooksDir, 'utils');
|
|
117
|
+
const utilFiles = fs.readdirSync(sourceUtilsPath);
|
|
118
|
+
utilFiles.forEach(utilFile => {
|
|
119
|
+
if(utilFile.endsWith('.ts')){
|
|
120
|
+
const sourceUtil = path.join(sourceUtilsPath, utilFile);
|
|
121
|
+
const targetUtil = path.join(targetUtilsPath, utilFile);
|
|
122
|
+
try{
|
|
123
|
+
fs.copyFileSync(sourceUtil, targetUtil);
|
|
124
|
+
}
|
|
125
|
+
catch(err){
|
|
126
|
+
// Copy failed silently
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 复制配置文件
|
|
134
|
+
function copyConfigFile(config: InstallConfig): void {
|
|
135
|
+
const source = path.join(__dirname, 'claude-code-hooks.json');
|
|
136
|
+
const dest = path.join(config.hooksDir, 'claude-code-hooks.json');
|
|
137
|
+
|
|
138
|
+
if (fs.existsSync(source)) {
|
|
139
|
+
if (fs.existsSync(dest)) {
|
|
140
|
+
const backup = path.join(config.hooksDir, `claude-code-hooks.backup.${Date.now()}.json`);
|
|
141
|
+
fs.copyFileSync(dest, backup);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fs.copyFileSync(source, dest);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 注意:不再创建 package.json,依赖已整合到项目根目录
|
|
149
|
+
|
|
150
|
+
// 创建 tsconfig.json
|
|
151
|
+
function createTsConfig(config: InstallConfig): void {
|
|
152
|
+
const tsconfigPath = path.join(config.hooksDir, 'scripts', 'tsconfig.json');
|
|
153
|
+
|
|
154
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
155
|
+
const tsconfig = {
|
|
156
|
+
compilerOptions: {
|
|
157
|
+
target: "ES2020",
|
|
158
|
+
module: "commonjs",
|
|
159
|
+
lib: ["ES2020"],
|
|
160
|
+
outDir: "./",
|
|
161
|
+
rootDir: "./",
|
|
162
|
+
strict: true,
|
|
163
|
+
esModuleInterop: true,
|
|
164
|
+
skipLibCheck: true,
|
|
165
|
+
forceConsistentCasingInFileNames: true,
|
|
166
|
+
resolveJsonModule: true,
|
|
167
|
+
declaration: true,
|
|
168
|
+
declarationMap: true,
|
|
169
|
+
sourceMap: true
|
|
170
|
+
},
|
|
171
|
+
include: ["*.ts"],
|
|
172
|
+
exclude: ["node_modules"]
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 主安装流程
|
|
180
|
+
function install(): void {
|
|
181
|
+
try {
|
|
182
|
+
const config: InstallConfig = {
|
|
183
|
+
platform,
|
|
184
|
+
homeDir,
|
|
185
|
+
hooksDir,
|
|
186
|
+
isWindows: platform === 'win32'
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
createDirectories(config);
|
|
190
|
+
// copyWrapperScript(config);
|
|
191
|
+
copyScriptsToHomeDir(config);
|
|
192
|
+
copyConfigFile(config);
|
|
193
|
+
createTsConfig(config);
|
|
194
|
+
|
|
195
|
+
} catch (err) {
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 执行安装
|
|
201
|
+
install();
|