Skip to content

goto: keep the app path when the base url has a query or hash (#108) - #116

Merged
gabe4coding merged 3 commits into
mainfrom
quality/108-goto-query
Oct 26, 2026
Merged

gabe4coding merged 3 commits into
mainfrom
quality/108-goto-query

Conversation

@gabe-bots

@gabe-bots gabe-bots Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Step 1/3 of quality/108-goto-query. Previous: none. Next: quality/107-useid-fragment.

Part of #108

Intent

A relative goto stays under the base path. A base query or hash stays unless the target has its own. Credentials in the base url stay.

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  base["base url with query or hash"] --> resolve["resolveUrl"]
  target["relative target"] --> resolve
  resolve --> path["keep the base directory"]
  path --> carry["copy query and hash unless the target has a ? or #"]
  carry --> page["page loads under the base path"]
Loading

Drift

None.

Decisions

  • Search and hash copy independently. A target with only a query still receives the base hash. Door: two-way. One function and one doc sentence can change later.
  • An empty ? or # in the target clears that part of the base url. Door: two-way.
  • A target with its own scheme, such as data: or https:, stays unchanged. Door: two-way.

Evidence

Before: http://host/app?x=1 + /login → http://host/login. http://host/app#section + /login → http://host/login. Fail-first: expected http://host/app/login?x=1, actual http://host/login.

After: http://host/app?x=1 + /login → http://host/app/login?x=1. #section → http://host/app/login#section. Browser goto from http://127.0.0.1:45659/app?from=e2e loaded http://127.0.0.1:45659/app/login?from=e2e, title App login, search ?from=e2e.

npm run verify: 578 pass, 0 fail. docs ok 18. Baseline was 577 pass, 0 fail. Live e2e did not finish: Connection error: fetch failed.

Review round 1

Before: https://user:pass@host/app + /login became https://host/app/login. /login? kept ?x=1. /login# kept #section. Fail-first: 3 fail, 1 pass.

After: the credential url stays https://user:pass@host/app/login. /login? becomes https://host/app/login?#section. /login# becomes https://host/app/login?x=1#. npm run verify: 581 pass, 0 fail. Head 5041210. The branch was rebased onto main after #115 merged, so verify ran on the commits before the rebase.

Reading map

  • Tests changed: src/browser/steps.test.ts (new test), scripts/gates.test.mjs (e2e floor 38 to 39).
  • Config: e2e/goto-base-query.yaml.
  • Public API: resolveUrl is now exported from src/browser/steps.ts.

Stack

Step 1/3 of quality/108-goto-query. Previous: none. Next: quality/107-useid-fragment.

@gabe-bots gabe-bots Bot added the needs-gabe Needs Gabe's decision before work continues label Oct 26, 2026
@gabe-bots

gabe-bots Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@gabe4coding

Copy link
Copy Markdown
Owner

@greptile review

@greptile-apps

greptile-apps Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] Changes how the goto step resolves relative URLs.

Preserve base URL credentials before merging; relative navigation can otherwise fail on protected sites.

Findings

  1. P1 Relative navigation drops credentials ▶
  2. P2 Empty overrides keep base values ▶
Fix with agent prompt
### Issue 1
src/browser/steps.ts:179
`resolveUrl` rebuilds the base using `parsed.origin`, which excludes its username and password. For example, `https://user:pass@host/app` plus `/login` now becomes `https://host/app/login`; previously the credentials stayed.

If a spec supplies credentials through its base URL without a separate `auth` block, relative navigation can no longer open the protected page. Build the directory URL from `parsed` without discarding its credentials.

### Issue 2
src/browser/steps.ts:180-181
`resolveUrl` treats an explicitly empty query or hash as missing. With base `https://host/app?x=1#section`, `/login?` restores `?x=1`, and `/login#` restores `#section`. Users cannot clear the inherited query options or hash route this way.

The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Keeps relative goto paths under the app directory when the base URL has a query or hash.

  • Relative goto keeps the app path and URL suffixes.

Reviews (1) · Last reviewed commit: "Merge origin/main into quality/108-goto-..." · Reviewed by Greptile

Comment thread src/browser/steps.ts Outdated
const directory = parsed.pathname.endsWith('/') ? parsed.pathname : `${parsed.pathname}/`;
const relative = target.startsWith('/') ? target.slice(1) : target;
return new URL(relative, baseWithSlash).toString();
const resolved = new URL(relative, `${parsed.origin}${directory}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Relative navigation drops credentials

resolveUrl rebuilds the base using parsed.origin, which excludes its username and password. For example, https://user:pass@host/app plus /login now becomes https://host/app/login; previously the credentials stayed.

If a spec supplies credentials through its base URL without a separate auth block, relative navigation can no longer open the protected page. Build the directory URL from parsed without discarding its credentials.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/steps.ts
Line: 179

Comment:
**Relative navigation drops credentials**

`resolveUrl` rebuilds the base using `parsed.origin`, which excludes its username and password. For example, `https://user:pass@host/app` plus `/login` now becomes `https://host/app/login`; previously the credentials stayed.

If a spec supplies credentials through its base URL without a separate `auth` block, relative navigation can no longer open the protected page. Build the directory URL from `parsed` without discarding its credentials.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 5041210: a relative goto keeps the user name and password from the base url.

Comment thread src/browser/steps.ts Outdated
Comment on lines +180 to +181
if (!resolved.search) resolved.search = parsed.search;
if (!resolved.hash) resolved.hash = parsed.hash;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Empty overrides keep base values

resolveUrl treats an explicitly empty query or hash as missing. With base https://host/app?x=1#section, /login? restores ?x=1, and /login# restores #section. Users cannot clear the inherited query options or hash route this way.

The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/steps.ts
Line: 180-181

Comment:
**Empty overrides keep base values**

`resolveUrl` treats an explicitly empty query or hash as missing. With base `https://host/app?x=1#section`, `/login?` restores `?x=1`, and `/login#` restores `#section`. Users cannot clear the inherited query options or hash route this way.

The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 5041210: an empty query or hash in the target clears that part of the base url.

cursoragent and others added 2 commits October 26, 2026 10:18
… and hash

Co-authored-by: Gabe <gpavanello@thefork.com>
…hash

Co-authored-by: Gabe <gpavanello@thefork.com>
@gabe4coding
gabe4coding force-pushed the quality/108-goto-query branch from 84d2727 to 5041210 Compare October 26, 2026 09:18
@gabe-bots

gabe-bots Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@gabe4coding
gabe4coding merged commit ed0e5c1 into main Oct 26, 2026
7 checks passed
@gabe4coding
gabe4coding deleted the quality/108-goto-query branch October 26, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-gabe Needs Gabe's decision before work continues risk:t2-hard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants