Skip to content

Commit fffd39e

Browse files
enunoclaude
andcommitted
fix: use absolute paths in hook commands to fix CWD-dependent resolution
Hook commands used relative paths (bun ./.claude/hooks/index.ts) which fail when Claude Code's hook runner CWD differs from the project root. Replaced all 8 hook entries with absolute paths (/opt/dokploy/.claude/...) Also includes dokploy-specific hook logic added to index.ts: - PreToolUse: warn on remote git build contexts without explicit dockerfile - PostToolUse: suggest validation commands after blueprint file writes - UserPromptSubmit: auto-inject context files for template/deploy prompts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent dd76aca commit fffd39e

2 files changed

Lines changed: 67 additions & 26 deletions

File tree

.claude/hooks/index.ts

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ const preToolUse: PreToolUseHandler = async (payload) => {
5252
console.log(`📝 Claude is editing: ${file_path}`)
5353
}
5454

55+
// Blueprint-specific guards
56+
if (payload.tool_name === 'Write' && payload.tool_input) {
57+
const input = payload.tool_input as {file_path?: string; content?: string}
58+
const filePath = input.file_path || ''
59+
const content = input.content || ''
60+
61+
// Warn when writing remote git build contexts without a local Dockerfile fallback
62+
if (filePath.endsWith('docker-compose.yml') && content.includes('context: https://github.com')) {
63+
if (!content.includes('dockerfile:')) {
64+
console.log('⚠️ Warning: Remote git build context without explicit dockerfile. Consider pinning to a tag or using a local Dockerfile fallback.')
65+
}
66+
}
67+
}
68+
5569
// Example: Track bash commands
5670
if (payload.tool_name === 'Bash' && payload.tool_input && 'command' in payload.tool_input) {
5771
const command = (payload.tool_input as {command: string}).command
@@ -67,9 +81,6 @@ const preToolUse: PreToolUseHandler = async (payload) => {
6781
}
6882
}
6983

70-
// Add your custom logic here!
71-
// You have full TypeScript support and can use any npm packages
72-
7384
return {} // Empty object means continue with default behavior
7485
}
7586

@@ -78,12 +89,27 @@ const postToolUse: PostToolUseHandler = async (payload) => {
7889
// Save session data (optional - remove if not needed)
7990
await saveSessionData('PostToolUse', {...payload, hook_type: 'PostToolUse'} as const)
8091

81-
// Example: React to successful file writes
82-
if (payload.tool_name === 'Write' && payload.tool_response) {
83-
console.log(`✅ File written successfully!`)
84-
}
92+
// Auto-validate blueprint files after write/edit
93+
if ((payload.tool_name === 'Write' || payload.tool_name === 'Edit') && payload.tool_input) {
94+
const input = payload.tool_input as {file_path?: string}
95+
const filePath = input.file_path || ''
8596

86-
// Add your custom post-processing logic here
97+
if (filePath.includes('blueprints/') && filePath.endsWith('docker-compose.yml')) {
98+
console.log(`📋 Blueprint docker-compose updated: ${filePath}`)
99+
console.log(`💡 Suggestion: Run validation: docker compose -f ${filePath} config`)
100+
console.log(`💡 Suggestion: Review with dokploy-template-validation skill`)
101+
}
102+
103+
if (filePath.includes('blueprints/') && filePath.endsWith('template.toml')) {
104+
console.log(`📋 Blueprint template.toml updated: ${filePath}`)
105+
console.log(`💡 Suggestion: Verify all variables are mapped in [config.env]`)
106+
}
107+
108+
if (filePath.includes('blueprints/') && filePath.endsWith('Dockerfile')) {
109+
console.log(`🐳 Blueprint Dockerfile updated: ${filePath}`)
110+
console.log(`💡 Suggestion: Validate syntax: docker build -f ${filePath} --target deps .`)
111+
}
112+
}
87113

88114
return {} // Return empty object to continue normally
89115
}
@@ -128,15 +154,32 @@ const subagentStop: SubagentStopHandler = async (payload) => {
128154
const userPromptSubmit: UserPromptSubmitHandler = async (payload) => {
129155
await saveSessionData('UserPromptSubmit', {...payload, hook_type: 'UserPromptSubmit'} as const)
130156

131-
// Example: Log user prompts
132-
console.log(`💬 User prompt: ${payload.prompt}`)
133-
134-
// Example: Add context files automatically based on prompt content
157+
const prompt = payload.prompt.toLowerCase()
135158
const contextFiles: string[] = []
136-
if (payload.prompt.toLowerCase().includes('test')) {
137-
// Automatically include test files when user mentions testing
138-
contextFiles.push('**/*.test.ts', '**/*.test.js')
139-
console.log('📁 Auto-adding test files to context')
159+
160+
// Auto-add relevant skills/context for Dokploy template work
161+
if (prompt.includes('dokploy') || prompt.includes('template') || prompt.includes('docker-compose')) {
162+
console.log('🛠️ Dokploy template work detected')
163+
164+
if (prompt.includes('create') || prompt.includes('new template') || prompt.includes('blueprint')) {
165+
console.log('💡 Tip: Use /dokploy-create <app-name> for the full workflow')
166+
contextFiles.push('.claude/commands/dokploy-create.md')
167+
contextFiles.push('AGENTS.md')
168+
}
169+
170+
if (prompt.includes('troubleshoot') || prompt.includes('deploy') || prompt.includes('error')) {
171+
console.log('💡 Tip: Use /dokploy-troubleshoot <app-name> for diagnostics')
172+
contextFiles.push('.claude/commands/dokploy-troubleshoot.md')
173+
}
174+
175+
if (prompt.includes('upstream') || prompt.includes('dockerfile') || prompt.includes('build fail')) {
176+
console.log('💡 Tip: Use dokploy-upstream-build-fix skill for patching broken upstream builds')
177+
contextFiles.push('.claude/skills/dokploy-upstream-build-fix/SKILL.md')
178+
}
179+
180+
if (prompt.includes('validate') || prompt.includes('check') || prompt.includes('lint')) {
181+
contextFiles.push('.claude/skills/dokploy-template-validation/SKILL.md')
182+
}
140183
}
141184

142185
// Example: Validate or modify prompts
@@ -145,8 +188,6 @@ const userPromptSubmit: UserPromptSubmitHandler = async (payload) => {
145188
return {decision: 'block', reason: 'Prompts containing "delete all" are not allowed'}
146189
}
147190

148-
// Add your custom prompt processing logic here
149-
150191
return contextFiles.length > 0 ? {contextFiles} : {}
151192
}
152193

.claude/settings.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"hooks": [
77
{
88
"type": "command",
9-
"command": "bun ./.claude/hooks/index.ts Notification"
9+
"command": "bun /opt/dokploy/.claude/hooks/index.ts Notification"
1010
}
1111
]
1212
}
@@ -17,7 +17,7 @@
1717
"hooks": [
1818
{
1919
"type": "command",
20-
"command": "bun ./.claude/hooks/index.ts Stop"
20+
"command": "bun /opt/dokploy/.claude/hooks/index.ts Stop"
2121
}
2222
]
2323
}
@@ -28,7 +28,7 @@
2828
"hooks": [
2929
{
3030
"type": "command",
31-
"command": "bun ./.claude/hooks/index.ts PreToolUse"
31+
"command": "bun /opt/dokploy/.claude/hooks/index.ts PreToolUse"
3232
}
3333
]
3434
}
@@ -39,7 +39,7 @@
3939
"hooks": [
4040
{
4141
"type": "command",
42-
"command": "bun ./.claude/hooks/index.ts PostToolUse"
42+
"command": "bun /opt/dokploy/.claude/hooks/index.ts PostToolUse"
4343
}
4444
]
4545
}
@@ -50,7 +50,7 @@
5050
"hooks": [
5151
{
5252
"type": "command",
53-
"command": "bun ./.claude/hooks/index.ts SubagentStop"
53+
"command": "bun /opt/dokploy/.claude/hooks/index.ts SubagentStop"
5454
}
5555
]
5656
}
@@ -61,7 +61,7 @@
6161
"hooks": [
6262
{
6363
"type": "command",
64-
"command": "bun ./.claude/hooks/index.ts UserPromptSubmit"
64+
"command": "bun /opt/dokploy/.claude/hooks/index.ts UserPromptSubmit"
6565
}
6666
]
6767
}
@@ -72,7 +72,7 @@
7272
"hooks": [
7373
{
7474
"type": "command",
75-
"command": "bun ./.claude/hooks/index.ts PreCompact"
75+
"command": "bun /opt/dokploy/.claude/hooks/index.ts PreCompact"
7676
}
7777
]
7878
}
@@ -83,7 +83,7 @@
8383
"hooks": [
8484
{
8585
"type": "command",
86-
"command": "bun ./.claude/hooks/index.ts SessionStart"
86+
"command": "bun /opt/dokploy/.claude/hooks/index.ts SessionStart"
8787
}
8888
]
8989
}

0 commit comments

Comments
 (0)