From 16cacf442b9a93cf63855e681305211c7bea3afe Mon Sep 17 00:00:00 2001 From: sven1103-agent <261423644+sven1103-agent@users.noreply.github.com> Date: Thu, 16 Apr 2026 21:03:06 +0200 Subject: [PATCH] fix: strip prompts/ prefix from config paths to avoid duplication Previously, config paths like 'prompts/coder.md' resulted in destination .opencode/prompts/prompts/coder.md (duplicated prompts/). Now the CLI normalizes paths by stripping the leading 'prompts/' prefix before determining the destination, ensuring the output matches the config structure. Also adds validation to fail with a clear error if the normalized path would be empty (e.g., config just says 'prompts'). --- cmd/bundle.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/cmd/bundle.go b/cmd/bundle.go index 6302ef1..db1bd40 100644 --- a/cmd/bundle.go +++ b/cmd/bundle.go @@ -344,6 +344,15 @@ func installPromptFiles(bundleRoot, projectRoot string, promptFiles []string, fo } for _, pf := range promptFiles { + // Normalize path: strip leading "prompts/" prefix to avoid duplication + normalizedPath := strings.TrimPrefix(pf, "prompts/") + normalizedPath = strings.TrimPrefix(normalizedPath, "/") + + // Validate normalized path isn't empty + if normalizedPath == "" { + return nil, fmt.Errorf("invalid prompt path in config: %q - path cannot be empty after normalization", pf) + } + sourcePath := filepath.Join(bundleRoot, pf) // Verify source file exists @@ -351,17 +360,17 @@ func installPromptFiles(bundleRoot, projectRoot string, promptFiles []string, fo return nil, fmt.Errorf("prompt file not found in bundle: %s", pf) } - // Determine destination (preserve relative structure) - destPath := filepath.Join(promptsDir, filepath.Base(pf)) + // Determine destination (preserve relative structure, but strip leading "prompts/" prefix) + destPath := filepath.Join(promptsDir, filepath.Base(normalizedPath)) - // Create subdirectory if needed (for paths like prompts/subdir/file.md) - if strings.Contains(pf, string(filepath.Separator)) { - subdir := filepath.Dir(pf) + // Create subdirectory if needed (for paths like subdir/file.md) + if strings.Contains(normalizedPath, string(filepath.Separator)) { + subdir := filepath.Dir(normalizedPath) subdirPath := filepath.Join(promptsDir, subdir) if err := os.MkdirAll(subdirPath, 0755); err != nil { return nil, fmt.Errorf("failed to create subdirectory: %w", err) } - destPath = filepath.Join(promptsDir, pf) + destPath = filepath.Join(promptsDir, normalizedPath) } // Check if destination exists (unless force)