Skip to content

fix(workspace): name a workspace by its resolved path - #1798

Open
ningmao-hlyz wants to merge 2 commits into
Agent-Field:devfrom
ningmao-hlyz:fix/1761-symlink-workspace-keys
Open

ningmao-hlyz wants to merge 2 commits into
Agent-Field:devfrom
ningmao-hlyz:fix/1761-symlink-workspace-keys

Conversation

@ningmao-hlyz

Copy link
Copy Markdown

Fixes #1761.

What changed

A folder reached through a symlink became two projects, two conversation
histories and two engines. Both doors where a person's path becomes a key now
resolve symlinks with filepath.EvalSymlinks before keying:

  • engineWorkspace (cmd/codeaf/engine.go) — the resolver every engine
    command goes through (--daemon, --status, --stop) and the source of
    the host's workspace name. It stopped at filepath.Clean, so
    sha256(Clean(...)) in enginehost.where minted one host directory per
    spelling: --status <link> missed the engine started at <dir>.
  • /project (internal/tui3/projectcmd.go) — the pin stored the raw typed
    spelling, so home keyed the folder under the alias while a launch from the
    resolved path (already canonicalized by v3OpenTarget) keyed it under the
    target: two project rows, one folder.

Regression test: cmd/codeaf/engine_symlink_test.go drives a symlink through
engineWorkspace and asserts both spellings land on the same directory, and
that a plain path still resolves to itself.

Changelog entry: docs/rules/changelog.md names the entry for its pull
request, and the number exists only once the pull request does — so it
arrives in the next push as
docs/changes/unreleased/<this-pr>-symlink-workspace-keys.md
(kind: fixed, surface: [engine, workspace]). The first red on check
is that workflow, not a mistake.

How it was checked

  • go build ./cmd/codeaf ./internal/tui3 — exit 0 (go1.26.5).
  • go test ./cmd/codeaf -run TestEngineWorkspace -count=1 -v — both tests
    pass: TestEngineWorkspaceResolvesSymlink,
    TestEngineWorkspaceKeepsNonSymlinkPathUnchanged (ok … 2.434s). To run
    this on Windows the other cmd/codeaf test files were moved aside for the
    run and put back — see the limitation below.
  • GOOS=linux go vet ./cmd/codeaf ./internal/tui3 — exit 0, the platform CI
    runs, so every test file (including the added one) typechecks there.
  • gofmt on the committed blobs — clean (engine.go, projectcmd.go,
    engine_symlink_test.go).
  • Reproduction at base 8761488a: a stdlib probe mirroring enginehost.where
    showed sha256(Clean(<link>)) ≠ sha256(Clean(<real>)) — two spellings,
    two host directories — and that EvalSymlinks collapses both spellings to
    one host directory.

Honest limitation: cmd/codeaf's test package does not build on Windows at
all — carried_child_test.go uses fakeFolderProgram, which lives behind
//go:build !windows; the identical failure exists at base 8761488a. So
the full suite cannot run on my Windows checkout and defers to CI on Linux
(where GOOS=linux go vet passes).

Checklist

  • A change entry — arrives in the next push, named for this pull request
    (the number does not exist until the pull request does; see
    docs/rules/changelog.md).
  • The manual knows about it — no slash command, key, tool, default, limit
    or refusal moved (keying fix only), so internal/manual/chat/ is
    unchanged.
  • No new line in .github/known-red.txt.
  • Only my own paths are staged — cmd/codeaf/engine.go,
    cmd/codeaf/engine_symlink_test.go, internal/tui3/projectcmd.go.

@CLAassistant

CLAassistant commented Oct 9, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Member

Hey, thanks for the PR. Could you sign the CLA when you get a chance so we can review it?

ningmao-hlyz added a commit to ningmao-hlyz/CodeAF that referenced this pull request Oct 9, 2026
A folder reached through a symlink became two projects, two conversation
histories and two engines: engineWorkspace and /project stopped at
filepath.Clean, so each spelling hashed to its own enginehost host
directory and its own project row.

Resolve symlinks (filepath.EvalSymlinks) at both doors where a person's
path becomes a key: engineWorkspace (--daemon/--status/--stop and the
host's workspace name) and runProjectCommand (the project pin).

Fixes Agent-Field#1761
@ningmao-hlyz
ningmao-hlyz force-pushed the fix/1761-symlink-workspace-keys branch from fd94fdf to fa7d438 Compare October 9, 2026 16:50
@ningmao-hlyz

Copy link
Copy Markdown
Author

Hey, thanks for the PR. Could you sign the CLA when you get a chance so we can review it?

done

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.

workspace: a folder reached through a symlink becomes two projects and two engines

3 participants