Skip to content

feat(issue): add workspace-scoped alias cache#52

Merged
BYK merged 9 commits intomainfrom
feat/workspace-scoped-aliases
Jan 23, 2026
Merged

feat(issue): add workspace-scoped alias cache#52
BYK merged 9 commits intomainfrom
feat/workspace-scoped-aliases

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Jan 23, 2026

Summary

Adds workspace-scoped alias caching using DSN fingerprinting to prevent cross-workspace conflicts, and adds support for self-hosted/non-standard DSN resolution.

Closes #49.

Problem

  1. Alias cache conflicts: The alias cache was stored globally without workspace context. When switching between monorepos or using multiple terminals in different workspaces, aliases from one workspace would overwrite another, potentially resolving to the wrong project's issues.

  2. Self-hosted DSN resolution: DSNs from self-hosted Sentry instances (or non-standard SaaS patterns) don't have an embedded org ID, so they couldn't be auto-resolved.

Solution

Workspace-scoped aliases via DSN fingerprinting

Instead of detecting workspace paths, we use a DSN fingerprint - a sorted string of orgId:projectId (or host:projectId for self-hosted) pairs from all detected DSNs. Aliases are only valid when the current workspace's DSN fingerprint matches what was stored.

  • Add createDsnFingerprint() to generate fingerprint from detected DSNs
  • Store fingerprint when caching aliases in issue list
  • Validate fingerprint when resolving aliases in issue view
  • Aliases automatically invalidate when DSN detection changes

Self-hosted DSN resolution

For DSNs without an embedded org ID, we now resolve projects by searching with the DSN's public key via /api/0/projects?query=dsn:<publicKey>.

  • Add findProjectByDsnKey() API function
  • Add resolveDsnByPublicKey() fallback in target resolution
  • Cache resolved projects by DSN public key
  • Use host:projectId in fingerprints for non-SaaS DSNs

Changes

New/Updated:

  • src/lib/dsn/parser.ts - Add createDsnFingerprint()
  • src/lib/api-client.ts - Add findProjectByDsnKey()
  • src/lib/config.ts - Fingerprint-aware alias functions, DSN key caching
  • src/lib/resolve-target.ts - Add resolveDsnByPublicKey() fallback
  • src/lib/dsn/resolver.ts - Use public key lookup for DSNs without orgId
  • src/commands/issue/list.ts - Store fingerprint when caching
  • src/commands/issue/view.ts - Validate fingerprint when resolving
  • src/commands/project/view.ts - Generic error messages

Tests:

  • test/lib/config.test.ts - DSN key cache, fingerprint validation
  • test/lib/dsn.test.ts - Fingerprint creation tests

The alias cache was global without workspace context. When switching
between monorepos or using multiple terminals, aliases from one workspace
would overwrite another, potentially resolving to the wrong project.

This change adds workspace scoping to the alias cache:

- Add workspace detection (git root, package.json, or cwd fallback)
- Store workspace path when caching aliases in `issue list`
- Validate workspace context when resolving aliases in `issue get`
- Add org validation as additional safety measure
- Maintain backward compatibility with legacy caches

Closes getsentry/sentry-cli-next#31 (comment)
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 23, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Issue

  • Add workspace-scoped alias cache by BYK in #52
  • Add workspace-scoped alias cache by BYK in #52
  • Add short ID aliases for multi-project support by BYK in #31

Other

  • (commands) Rename get commands to view and add -w browser flag by BYK in #53

Bug Fixes 🐛

  • (issue) Use org-scoped endpoint for latest event + enhanced display by betegon in #40

Documentation 📚

  • Update command references from 'get' to 'view' and document -w flag by BYK in #54

Internal Changes 🔧

  • (release) Fix changelog-preview permissions by BYK in #41
  • Rename config folder from .sentry-cli-next to .sentry by BYK in #50

🤖 This preview updates automatically when you update the PR.

BYK added 2 commits January 23, 2026 13:45
- Fix import order in get.ts and list.ts
- Add biome-ignore for cognitive complexity in get.ts
- Remove unnecessary undefined and collapse if in config.ts
Bun.file().exists() doesn't work correctly for directories.
Use node:fs existsSync instead which handles both files and directories.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 23, 2026

Codecov Results 📊

❌ Patch coverage is 62.20%. Project has 1564 uncovered lines.
✅ Project coverage is 55.07%. Comparing base (base) to head (head).

Files with missing lines (18)
File Patch % Lines
human.ts 9.42% ⚠️ 731 Missing
oauth.ts 21.71% ⚠️ 202 Missing
api-client.ts 46.98% ⚠️ 123 Missing
resolver.ts 3.23% ⚠️ 120 Missing
errors.ts 5.94% ⚠️ 95 Missing
fixture.ts 28.74% ⚠️ 62 Missing
api.ts 66.30% ⚠️ 61 Missing
errors.ts 51.61% ⚠️ 60 Missing
config.ts 86.01% ⚠️ 34 Missing
preload.ts 39.02% ⚠️ 25 Missing
detector.ts 87.79% ⚠️ 16 Missing
cache.ts 76.27% ⚠️ 14 Missing
colors.ts 85.42% ⚠️ 7 Missing
index.ts 95.06% ⚠️ 4 Missing
parser.ts 94.52% ⚠️ 4 Missing
env-file.ts 97.17% ⚠️ 3 Missing
alias.ts 96.43% ⚠️ 2 Missing
java.ts 97.22% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    54.90%    55.07%    +0.17%
==========================================
  Files           33        33         —
  Lines         3410      3481       +71
  Branches         0         0         —
==========================================
+ Hits          1872      1917       +45
- Misses        1538      1564       +26
- Partials         0         0         —

Generated by Codecov Action

…ping

Replace workspace path detection with DSN fingerprint validation for the
project alias cache. This is simpler because:
- No need for separate workspace detection logic
- Aliases naturally invalidate when DSN detection changes
- Uses existing DSN caching infrastructure

The fingerprint is a sorted, comma-separated string of 'orgId:projectId'
pairs, ensuring aliases are only valid when the same set of DSNs are detected.

Changes:
- Add createDsnFingerprint() in src/lib/dsn/parser.ts
- Update setProjectAliases/getProjectByAlias to use dsnFingerprint
- Update issue list/get commands to use DSN fingerprinting
- Remove src/lib/workspace.ts (no longer needed)
- Update tests for new fingerprint-based validation
@BYK BYK marked this pull request as ready for review January 23, 2026 14:23
Improves patch coverage by testing:
- Multiple DSN fingerprint creation
- Alphabetical sorting of fingerprint
- Deduplication of same DSN from multiple sources
- Filtering out self-hosted DSNs (no orgId)
- Empty array handling
BYK added 4 commits January 23, 2026 14:31
The fingerprint validation was using truthy checks which caused empty
string fingerprints to bypass validation. Empty string is a valid
fingerprint value (means no SaaS DSNs detected), so we now use explicit
undefined checks instead.

This prevents aliases from being incorrectly used across workspaces when
one or both have only self-hosted DSNs or when DSN detection fails.
Add support for resolving DSNs that don't have an embedded org ID
(self-hosted Sentry instances or some SaaS patterns) by:

1. Add findProjectByDsnKey() API using /api/0/projects?query=dsn:<key>
2. Update resolveDsnToTarget() to use DSN public key lookup as fallback
3. Add getCachedProjectByDsnKey/setCachedProjectByDsnKey for DSN-based caching
4. Update createDsnFingerprint() to use host:projectId for DSNs without orgId
5. Update error messages to be more generic (not self-hosted specific)

This enables automatic project resolution for self-hosted users without
requiring explicit --org and --project flags.
…-aliases

# Conflicts:
#	src/commands/issue/get.ts
#	src/commands/project/view.ts
@betegon
Copy link
Copy Markdown
Member

betegon commented Jan 23, 2026

closes #49

@BYK BYK merged commit 17e68b9 into main Jan 23, 2026
17 checks passed
@BYK BYK deleted the feat/workspace-scoped-aliases branch January 23, 2026 17:55
BYK added a commit that referenced this pull request Jan 23, 2026
Add missing tests for functions introduced in the workspace-scoped
alias caching feature:

- getCachedProject / setCachedProject / clearProjectCache
- getConfigPath
- createDetectedDsn with invalid DSN
- inferPackagePath for various monorepo patterns

This brings patch coverage to 100% for the changes in PR #52.
BYK added a commit that referenced this pull request Jan 23, 2026
## Summary

Adds missing tests to achieve 100% patch coverage for the changes
introduced in PR #52 (workspace-scoped alias caching).

## Tests Added

### `test/lib/config.test.ts`
- `getCachedProject` / `setCachedProject` / `clearProjectCache` -
project cache by orgId:projectId
- `getConfigPath` - returns the config file path

### `test/lib/dsn.test.ts`
- `createDetectedDsn` - creates DetectedDsn from valid/invalid DSN
strings
- `inferPackagePath` - infers package paths from monorepo directory
patterns (packages/, apps/, libs/, modules/, services/)

## Coverage Improvement

| File | Before | After |
|------|--------|-------|
| `src/lib/config.ts` | 86.01% | 97.11% |
| `src/lib/dsn/parser.ts` | 94.52% | 98.63% |
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.

Bug: Global alias cache causes cross-workspace contamination

2 participants