Skip to content

fix(opencode): use relative SDD prompt paths#1252

Open
decode2 wants to merge 2 commits into
Gentleman-Programming:mainfrom
decode2:fix/issue-723-relative-prompt-paths-v2
Open

fix(opencode): use relative SDD prompt paths#1252
decode2 wants to merge 2 commits into
Gentleman-Programming:mainfrom
decode2:fix/issue-723-relative-prompt-paths-v2

Conversation

@decode2

@decode2 decode2 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Closes #723


PR Type

  • type:bug - Bug fix (non-breaking change that fixes an issue)
  • type:feature - New feature (non-breaking change that adds functionality)
  • type:docs - Documentation only
  • type:refactor - Code refactoring (no functional changes)
  • type:chore - Build, CI, or tooling changes
  • type:breaking-change - Breaking change (fix or feature that changes existing behavior)

Summary

  • Generate OpenCode SDD prompt references as portable relative paths instead of machine-specific absolute paths.
  • Keep prompt resolution deterministic across single- and multi-profile generated settings.

Changes

File / Area What Changed
internal/components/sdd Generate relative prompt paths and update profile injection coverage.
internal/components/golden_test.go Normalize golden generation expectations for relative paths.
testdata/golden/sdd-opencode-multi-settings.golden Update deterministic generated JSON output.

Test Plan

Passed:

  • go test ./internal/components/sdd/...
  • go test ./internal/components -run '^TestGoldenSDD_OpenCode_Multi$'
  • go test ./internal/components
  • git diff --check

Runtime validation: N/A. The affected output is deterministic generated JSON and is covered by focused unit and golden tests; there is no separate runtime boundary.


Automated Checks

The repository checks will run on this PR.


Contributor Checklist

  • PR is linked to an issue with status:approved
  • PR stays within 400 changed lines, or has an approved exception
  • The appropriate type:* label is applied
  • Required tests pass
  • Documentation is updated if necessary
  • Commits follow Conventional Commits
  • Commits do not include Co-Authored-By trailers

Notes for Reviewers

Size: 9 files, +128/-50 (178 changed lines), under the 400-line review budget.

Summary by CodeRabbit

  • Bug Fixes

    • Improved SDD profile and sub-agent prompt references to consistently use stable, portable {file:...} paths in generated opencode.json overlays and inline prompts.
    • Prevented machine-specific home and absolute temp-directory paths from being embedded, improving reliability across OpenCode and Kilocode settings layouts (including XDG config home resolution).
  • Tests

    • Updated golden and integration assertions to expect settings-relative prompt references and to confirm generated outputs do not contain local absolute paths.
    • Added coverage for shared prompt reference generation and fallback behavior.

@decode2

decode2 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Maintainers, please add the type:bug label. The contributor account does not have permission to apply labels.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

SDD profile overlays and OpenCode prompt injection now generate settings-relative {file:...} references. A shared helper normalizes these paths, callers pass settingsPath, and tests verify generated settings do not contain temporary home directories.

Changes

Portable prompt reference generation

Layer / File(s) Summary
Shared prompt reference helper
internal/components/sdd/prompts.go, internal/components/sdd/prompts_test.go
Adds SharedPromptFileRef, uses the configured OpenCode config root, and tests relative-reference generation and fallback behavior.
Overlay and injection integration
internal/components/sdd/profiles.go, internal/components/sdd/inject.go
Passes settingsPath through overlay generation and replaces absolute prompt references with shared relative references.
Integration and portability validation
internal/components/sdd/*_test.go, internal/components/golden_test.go, internal/cli/sync_test.go
Updates callers and assertions to validate relative references and generated settings without temporary home paths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Inject
  participant GenerateProfileOverlay
  participant SharedPromptFileRef
  participant OpenCodeSettings
  Inject->>GenerateProfileOverlay: pass settingsPath
  GenerateProfileOverlay->>SharedPromptFileRef: build phase reference
  SharedPromptFileRef-->>GenerateProfileOverlay: return relative {file:...}
  GenerateProfileOverlay->>OpenCodeSettings: write overlay
  Inject->>SharedPromptFileRef: build inlined prompt reference
  SharedPromptFileRef-->>Inject: return relative {file:...}
Loading

Suggested labels: type:bug

Suggested reviewers: alan-thegentleman

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: using relative SDD prompt paths.
Linked Issues check ✅ Passed The implementation now generates shared prompt refs from the OpenCode settings path and updates tests accordingly, matching the portability goal.
Out of Scope Changes check ✅ Passed All touched code and tests stay focused on portable SDD prompt paths and related expectations.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@decode2
decode2 force-pushed the fix/issue-723-relative-prompt-paths-v2 branch from ff49243 to 2242051 Compare July 13, 2026 18:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/components/sdd/profiles_test.go (1)

778-797: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert portability independently of the production helper.

The test computes expectedRef with the same SharedPromptFileRef used by GenerateProfileOverlay, so a regression that reintroduces absolute home paths can make both sides agree. Also assert that generated references are relative and contain no home path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/components/sdd/profiles_test.go` around lines 778 - 797, Update the
test around GenerateProfileOverlay and its phase loop to validate portability
independently of SharedPromptFileRef: assert each generated prompt reference is
relative and does not contain the home path before or alongside comparing
expectedRef. Keep the existing expected-reference comparison, but ensure the
assertions would fail if GenerateProfileOverlay emits an absolute home-based
path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/components/sdd/profiles_test.go`:
- Around line 778-797: Update the test around GenerateProfileOverlay and its
phase loop to validate portability independently of SharedPromptFileRef: assert
each generated prompt reference is relative and does not contain the home path
before or alongside comparing expectedRef. Keep the existing expected-reference
comparison, but ensure the assertions would fail if GenerateProfileOverlay emits
an absolute home-based path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 917aaee2-f391-4db7-843a-71f771119398

📥 Commits

Reviewing files that changed from the base of the PR and between ff49243 and 2242051.

⛔ Files ignored due to path filters (1)
  • testdata/golden/sdd-opencode-multi-settings.golden is excluded by !testdata/**
📒 Files selected for processing (9)
  • internal/cli/sync_test.go
  • internal/components/golden_test.go
  • internal/components/sdd/inject.go
  • internal/components/sdd/inject_test.go
  • internal/components/sdd/profiles.go
  • internal/components/sdd/profiles_lifecycle_test.go
  • internal/components/sdd/profiles_test.go
  • internal/components/sdd/prompts.go
  • internal/components/sdd/prompts_test.go

@dnlrsls dnlrsls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SharedPromptFileRef is still not portable for OpenCode's supported XDG layout. SettingsPath can be $XDG_CONFIG_HOME/opencode/opencode.json, while SharedPromptDir remains $HOME/.config/opencode/prompts/sdd. On Unix this can generate a relative path containing the original home/user topology, and on Windows different config and home volumes make filepath.Rel fail and abort injection.

Please derive settings and shared prompt locations from one resolved config-root model, or otherwise handle roots that cannot produce a portable relative reference. A focused test for absolute XDG_CONFIG_HOME plus Windows different-volume behavior would establish the contract. The standard OpenCode and Kilocode layouts otherwise look correct.

@decode2
decode2 force-pushed the fix/issue-723-relative-prompt-paths-v2 branch from 2242051 to 6ddf8d1 Compare July 21, 2026 02:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/components/sdd/inject_test.go`:
- Around line 2388-2391: Update the expected prompt value in the test assertion
to use the existing SharedPromptFileRef symbol instead of a hardcoded path
string, preserving the comparison and failure message so path separators remain
platform-independent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9b13106d-814f-4a34-bdfa-d97f97eee299

📥 Commits

Reviewing files that changed from the base of the PR and between 2242051 and 6ddf8d1.

⛔ Files ignored due to path filters (1)
  • testdata/golden/sdd-opencode-multi-settings.golden is excluded by !testdata/**
📒 Files selected for processing (10)
  • internal/cli/sync_test.go
  • internal/components/golden_test.go
  • internal/components/sdd/inject.go
  • internal/components/sdd/inject_test.go
  • internal/components/sdd/issue557_test.go
  • internal/components/sdd/profiles.go
  • internal/components/sdd/profiles_lifecycle_test.go
  • internal/components/sdd/profiles_test.go
  • internal/components/sdd/prompts.go
  • internal/components/sdd/prompts_test.go

Comment on lines +2388 to +2391
want := "{file:../opencode/prompts/sdd/sdd-apply.md}"
if prompt != want {
t.Fatalf("sdd-apply prompt = %q, want %q", prompt, want)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use SharedPromptFileRef instead of a hardcoded string.

Hardcoding the expected path with forward slashes may cause the test to fail on Windows if the injected prompt uses OS-specific separators. Using SharedPromptFileRef ensures cross-platform consistency and aligns with the approach taken in TestInjectOpenCodeSubagentPromptsStayExecutorScoped.

♻️ Proposed refactor
-	want := "{file:../opencode/prompts/sdd/sdd-apply.md}"
+	want, err := SharedPromptFileRef(adapter.SettingsPath(home), home, "sdd-apply")
+	if err != nil {
+		t.Fatalf("SharedPromptFileRef() error = %v", err)
+	}
	if prompt != want {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
want := "{file:../opencode/prompts/sdd/sdd-apply.md}"
if prompt != want {
t.Fatalf("sdd-apply prompt = %q, want %q", prompt, want)
}
want, err := SharedPromptFileRef(adapter.SettingsPath(home), home, "sdd-apply")
if err != nil {
t.Fatalf("SharedPromptFileRef() error = %v", err)
}
if prompt != want {
t.Fatalf("sdd-apply prompt = %q, want %q", prompt, want)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/components/sdd/inject_test.go` around lines 2388 - 2391, Update the
expected prompt value in the test assertion to use the existing
SharedPromptFileRef symbol instead of a hardcoded path string, preserving the
comparison and failure message so path separators remain platform-independent.

@decode2

decode2 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Updated in 6ddf8d18. Prompt references now honor the configured OpenCode root and fall back to an absolute slash-normalized path when the settings and prompt roots cannot be relativized. The tests use independent expected paths and cover the filepath.Rel failure contract.

The full Go suite, vet, Windows runtime, and E2E checks pass. This is ready for re-review. The only remaining required check is the maintainer-applied type:bug label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(opencode): avoid absolute prompt paths in generated settings

2 participants