Skip to content

feat(ghost): replace symlink farm with native project discovery control#62

Merged
kdcokenny merged 8 commits intomainfrom
feat/remove-symlink-farm
Jan 20, 2026
Merged

feat(ghost): replace symlink farm with native project discovery control#62
kdcokenny merged 8 commits intomainfrom
feat/remove-symlink-farm

Conversation

@kdcokenny
Copy link
Owner

@kdcokenny kdcokenny commented Jan 13, 2026

Summary

Removes the symlink farm architecture from ghost mode, replacing it with OpenCode's native OPENCODE_DISABLE_PROJECT_CONFIG environment variable.

Dependencies

⚠️ Blocked by upstream: This PR requires sst/opencode#8093 to be merged first.

Changes

  • Deleted: symlink-farm.ts, pattern-filter.ts, file-sync.ts + tests (~1000 lines)
  • Simplified: opencode.ts (512 → 304 lines, -40%)
  • Schema: Removed exclude, include, maxFiles fields
  • Docs: Updated AGENTS.md with new flow

Migration

Profiles with instruction files must add to their opencode.jsonc:

{
  "instructions": ["./AGENTS.md"]  // and/or CLAUDE.md, CONTEXT.md
}

New Flow

OpenCode now runs directly in the project directory with:

  • OPENCODE_DISABLE_PROJECT_CONFIG=true
  • OPENCODE_CONFIG_DIR pointing to profile

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 13, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
ocx 20c5aa0 Jan 20 2026, 04:08 AM

Remove symlink farm architecture from ghost mode, replacing it with
OpenCode's native OPENCODE_DISABLE_PROJECT_DISCOVERY environment variable.

Changes:
- Delete symlink-farm.ts, pattern-filter.ts, file-sync.ts + tests
- Simplify opencode.ts (512 → 304 lines)
- Remove exclude/include/maxFiles from ghost schema
- Update AGENTS.md documentation

BREAKING CHANGE: Profiles with AGENTS.md must add `instructions: ["./AGENTS.md"]`
to their opencode.jsonc configuration.

Depends on: anomalyco/opencode#8093
@kdcokenny kdcokenny force-pushed the feat/remove-symlink-farm branch from 9847cb4 to a467487 Compare January 13, 2026 20:36
The ghost-include-opencode.test.ts file was testing the now-deleted
symlink farm functionality and was causing test failures due to missing
module imports.
@kdcokenny
Copy link
Owner Author

Testing Summary

Tested with OpenCode fork containing PR #8093 (OPENCODE_DISABLE_PROJECT_DISCOVERY).

Test Environment

  • OCX branch: feat/remove-symlink-farm
  • OpenCode: feat/disable-project-discovery branch (built from source)
  • Profile: ocx-dev

Recreation Steps

# 1. Build OCX
cd ~/workspace/kdcokenny/ocx/packages/cli && bun run build && cd ../..

# 2. Build OpenCode fork
cd /path/to/opencode/packages/opencode && bun run build

# 3. Create test project
mkdir -p /tmp/ocx-test/src/components
echo "ROOT" > /tmp/ocx-test/AGENTS.md
echo "SRC" > /tmp/ocx-test/src/AGENTS.md
echo "COMP" > /tmp/ocx-test/src/components/AGENTS.md
cd /tmp/ocx-test && git init

# 4. Set OpenCode binary
export OPENCODE_BIN="/path/to/opencode/dist/opencode-darwin-arm64/bin/opencode"

# 5. Run tests
~/workspace/kdcokenny/ocx/packages/cli/dist/index.js ghost opencode run "List AGENTS.md contents and MCP servers"

Test Results

Test ghost.jsonc Config Expected Result
Default (exclude all) Default excludes Only profile AGENTS.md visible ✅ Pass
Include all AGENTS.md Remove **/AGENTS.md from exclude COMP → SRC → ROOT (deepest first) ✅ Pass
Include specific file exclude: ["**/AGENTS.md"], include: ["src/components/AGENTS.md"] Only COMP visible ✅ Pass
MCP servers loaded Default context7, exa, gh_grep connected ✅ Pass
./ prefix normalization include: ["./src/components/AGENTS.md"] Pattern matches correctly ✅ Pass
OPENCODE_BIN override N/A Custom binary used ✅ Pass

Dependencies

⚠️ Blocked by upstream: This PR requires sst/opencode#8093 to be merged first.

Summary

All tests passed. The new architecture:

  • Replaces symlink farm with direct execution
  • Uses OPENCODE_DISABLE_PROJECT_DISCOVERY to prevent project config loading
  • Implements TypeScript/Vite-style exclude/include patterns for instruction file discovery
  • Reduces code complexity by ~3,000 lines

- Remove symlink farm, file sync, maxFiles references
- Add OPENCODE_BIN env var documentation
- Add exclude/include pattern documentation
- Update 'How It Works' section
- Update verification tests in CONTRIBUTING.md
@kdcokenny kdcokenny force-pushed the feat/remove-symlink-farm branch from cc85bb4 to 05b3a21 Compare January 14, 2026 01:41
…OJECT_CONFIG

Align with upstream OpenCode PR #8093 which renamed the environment
variable in commit 31aae19.

Updated files:
- packages/cli/src/commands/ghost/opencode.ts
- packages/cli/tests/ghost/ghost-opencode.test.ts
- AGENTS.md
- README.md
- docs/CLI.md
Allow each ghost profile to specify its own OpenCode binary path
via the `bin` option in ghost.jsonc.

Resolution order:
1. ghost.jsonc `bin` option (per-profile)
2. OPENCODE_BIN environment variable (global)
3. "opencode" (default, from PATH)

Changes:
- Add bin property to ghostConfigSchema
- Update opencode.ts to use config.bin in fallback chain
- Add documentation in AGENTS.md
- Add tests for bin fallback behavior
Update all documentation to include the new ghost.jsonc `bin` option
for specifying custom OpenCode binary paths.

Updated files:
- docs/CLI.md: Added bin to schema table and Custom OpenCode Binary section
- README.md: Updated env var table and ghost.jsonc example
- CONTRIBUTING.md: Recommend bin config as preferred approach

Also fixes: Remove non-existent maxFiles field from README example
@kdcokenny kdcokenny marked this pull request as ready for review January 20, 2026 04:08
@kdcokenny kdcokenny merged commit ae5eb17 into main Jan 20, 2026
2 checks passed
@kdcokenny kdcokenny deleted the feat/remove-symlink-farm branch January 20, 2026 04:08
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.

1 participant