Skip to content

mcpx(source): abs() still expands any ~name under the caller's home — the #1702 tilde rule fixed searchpath (#2967) but missed the source resolver #2988

Closed

Description

@dezren39

Summary

pkgs/mcpx/internal/source/source.go's abs() (line 118-126, main 90f69428) still expands any leading ~ under the caller's own home — the exact bug #1702 pinned for search paths and fixed for searchpath in #2967 (landed 6bee50a8). The source resolver was missed:

func abs(path, dir string) string {
	if filepath.IsAbs(path) { return path }
	if strings.HasPrefix(path, "~") {
		if home, err := os.UserHomeDir(); err == nil {
			return filepath.Join(home, strings.TrimPrefix(path, "~"))
		}
	}
	...
	return filepath.Join(dir, path)
}

So ~alice/secret.ts, ~nosuchuser/x.ts, and ~scratch are silently resolved to $HOME/alice/secret.ts, $HOME/nosuchuser/x.ts, and $HOME/scratch — inventing a home for users who may not exist — instead of being treated as literal relative entries under Dir, which is the rule #1702's triage pinned (only a bare ~ and ~/... name the caller's home) and which the two sibling helpers now implement:

source.abs() is the path resolver for every string-shaped mcpx source setting (launchers, prefixes, error hooks — see the package doc): it is reached via @file:, @dir:, and the bare-value probe path in Resolve().

Evidence (verified this run)

Laptop probe ~/git/fleet/probe-2026-10-31-laneB-sourcetilde/ — the real source.go copied verbatim (md5 ea6a8c5521476daf62b8a0e089104007, matching both clones at main 90f69428), with a test calling the real abs() / Resolve() with HOME set to a temp dir and Dir set to a different temp dir containing a literal ~alice/ directory:

abs("~alice/secret.ts")   = "$HOME/alice/secret.ts"        want "$DIR/~alice/secret.ts"
abs("~nosuchuser/x.ts")   = "$HOME/nosuchuser/x.ts"        want "$DIR/~nosuchuser/x.ts"
abs("~scratch")           = "$HOME/scratch"                want "$DIR/~scratch"
Resolve("@file:~alice/secret.ts") text="FROM_HOME_ALICE"   (read $HOME/alice/secret.ts)
                                  want "FROM_LITERAL_TILDE" (the file under $DIR/~alice/)

Controls behaved correctly and are not in the failure list: abs("~/own.ts") = $HOME/own.ts and abs("~") = $HOME.

Why it matters

A source value beginning ~name reads a different file than the one named — a lookalike file under the caller's own home — with no error. For launcher/prefix/hook sources that is silent wrong-code execution potential if such a lookalike exists, and a confusing "file not found / wrong content" failure otherwise. It also makes the three mcpx path helpers disagree: the same ~alice/... string means one thing as a search-path entry and another as a source value.

Acceptance criteria

  • source.abs() expands only a bare ~ and ~/... to the caller's home; ~name entries resolve literally against Dir, matching searchpath.absolute() and the dashboard helper.
  • Regression test in pkgs/mcpx/internal/source/source_test.go covering ~, ~/x, ~alice/x, ~nosuchuser/x, and ~scratch (mirroring TestOnlyBareTildeAndTildeSlashExpandHome), including an end-to-end Resolve("@file:~alice/...") case that reads the literal directory.
  • No other mcpx path helper retains the bare-HasPrefix(path, "~") form (grep-verifiable).

Dedup / relations

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 31, 2026
  2. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  4. 2 remaining items

  5. added
    queue/queuedHas a queued task in the Supabase agent queue
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  6. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  7. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

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

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)effort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions