Repository navigation
fix(jtk): make config show reflect the shared store - #483
Conversation
The runtime resolvers (GetURL, GetEmail, GetDefaultProject) consult the shared ~/.config/atlassian-cli/config.yml, but the *WithSource diagnostics behind `jtk config show` skipped it. After `jtk init` writes the shared store, `config show` rendered url/email as empty "-" rows and printed the legacy per-tool path (which may not exist) as "Config file:" — a working configuration looked unconfigured. - GetURLWithSource / GetEmailWithSource / GetDefaultProjectWithSource now consult the shared store between env and the legacy file, matching runtime precedence (auth_method and cloud_id already did). - The Config file row names the file actually read: the shared store when it exists, else the legacy path. - Drop the help text documenting the old blind spot.
monit-reviewer
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: d6b10b2687d6
Profile: claude-monit-reviewer - Posting as: monit-reviewer
Summary
| Reviewer | Findings |
|---|---|
| go:implementation-tests | 1 |
| policies:conventions | 0 |
| security:code-auditor | 0 |
| architecture:solid-reviewer-agnostic | 2 |
go:implementation-tests (1 finding)
Minor - tools/jtk/internal/config/source.go:105
GetURLWithSource calls jtkSectionWithSource("url") to get (v, src) but then discards v and calls GetURL() again to produce the returned value, causing loadShared() (a file read + YAML parse) to run twice per call. GetEmailWithSource just below uses v directly. Since GetURL() re-derives the same value through the same precedence, behavior is currently correct, but the duplicate load is an avoidable seam inconsistency; prefer returning url.NormalizeURL(v) directly (matching GetURL's own normalization) instead of re-invoking the full resolver chain.
architecture:solid-reviewer-agnostic (2 findings)
Major - tools/jtk/internal/config/source.go:75
U-S1:
activeConfigPathbuilds its own copy of "which shared file does the runtime read" (credstore.DefaultPath()+os.Stat). That decision belongs to credstore, and the copy disagrees with credstore's rule. The value resolvers go throughloadShared()->credstore.LoadSharedRuntime(), which is relocation-aware: when only the prior shared file exists (on macOS,~/.config/atlassian-cli/config.ymlvs the canonical~/Library/Application Support/atlassian-cli/config.yml), the runtime reads the prior file. In that case url/email render asshared default, but this function stats only the canonical path, misses it, and prints the legacyjira-ticket-cli/config.json. That is the same misleading output this PR sets out to fix, on the upgrade path users are most likely to be on. The reverse case also misreports: a present but corrupt canonical file makes the resolvers warn and fall back to legacy, while this row still names the shared file.credstore.HasSharedConfigalready has the canonical-then-old probe and validates the file by parsing it. Fix: have credstore report the path it actually loaded, for exampleLoadSharedRuntimereturning the resolved path or a newcredstore.RuntimeSharedPath() (string, error)next tohasSharedConfigAt. Then makeactiveConfigPatha thin call to it that falls back toPath(). Add a test for the old-only relocation case through the existingloadSharedRuntime(newPath)seam.
Nits - tools/jtk/internal/config/source.go:154
U-O1 (consistency of the source vocabulary): the other shared-store rows get their label from the typed
credstore.Sourceenum (SourceDefault= "shared default"). This row uses a bare string literal, "shared jtk", that is not part of that enum. The difference is defensible, because default_project lives in the per-tooljtksection and not indefault. Still, adding a namedcredstore.Sourceconstant (for exampleSourceToolSection) would keep the labels shown byconfig showdefined in one place for consumers and tests to match against.
Reviewer Coverage
go:implementation-tests— complete (broad); skipped: none; constraints: nonepolicies:conventions— complete (broad); inspected 2 assigned files (3 inspected across reviewers):tools/jtk/internal/cmd/configcmd/configcmd.go,tools/jtk/internal/config/source.go; skipped: none; constraints: nonesecurity:code-auditor— complete (broad); inspected 1 assigned file (3 inspected across reviewers):tools/jtk/internal/config/source.go; skipped: none; constraints: nonearchitecture:solid-reviewer-agnostic— complete (broad); inspected 1 assigned file (3 inspected across reviewers):tools/jtk/internal/config/source.go; skipped: none; constraints: Did not run go test; judged from source. Compared against loadShared/jtkSectionWithSource in config.go and credstore's LoadSharedRuntime/HasSharedConfig in shared/credstore.
Inspected files (3)
tools/jtk/internal/cmd/configcmd/configcmd.gotools/jtk/internal/config/source.gotools/jtk/internal/config/source_test.go
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 2m 40s | ~$2.12 (est.) | claude-sonnet-5, claude-opus-5-5 | cr 0.10.318
| Field | Value |
|---|---|
| Model | claude-sonnet-5, claude-opus-5-5 |
| Reviewers | go:implementation-tests, policies:conventions, security:code-auditor, architecture:solid-reviewer-agnostic |
| Engine | claude_cli · claude-sonnet-5, claude-opus-5-5 |
| Reviewed by | cr · monit-reviewer |
| Duration | 2m 40s wall · 5m 28s compute |
| Cost | ~$2.12 (est.) |
| Pricing basis | anthropic-public-2026-09-23 |
| Tokens | 88 in / 19.1k out |
Per-workstream usage
orchestrator-selection— claude-sonnet-5- In: 6
- Out: 2.3k
- Cache read: 87.9k
- Cache create: 41.3k
- Cost: ~$0.21 (est.)
- Duration: 28s
go:implementation-tests— claude-sonnet-5- In: 22
- Out: 5.8k
- Cache read: 630.6k
- Cache create: 58.6k
- Cost: ~$0.42 (est.)
- Duration: 1m 35s
policies:conventions— claude-sonnet-5- In: 28
- Out: 4.8k
- Cache read: 808.1k
- Cache create: 58.4k
- Cost: ~$0.44 (est.)
- Duration: 1m 22s
security:code-auditor— claude-sonnet-5- In: 8
- Out: 1.4k
- Cache read: 152.7k
- Cache create: 40.3k
- Cost: ~$0.21 (est.)
- Duration: 34s
architecture:solid-reviewer-agnostic— claude-opus-5-5- In: 18
- Out: 3.6k
- Cache read: 393.8k
- Cache create: 64.9k
- Cost: ~$0.67 (est.)
- Duration: 1m 09s
orchestrator-rollup— claude-sonnet-5- In: 6
- Out: 1.1k
- Cache read: 142.8k
- Cache create: 34.9k
- Cost: ~$0.18 (est.)
- Duration: 17s
Resolve the config show path row through credstore.SharedRuntimePath, which reuses the runtime relocation logic, so the prior shared location is shown on the old-only read fallback and a corrupt shared file shows the legacy path. Return the normalized shared URL directly instead of re-running GetURL, and label the jtk default_project row with a named credstore.SourceJTK constant.
monit-reviewer
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: 268e5ad4941f
Profile: claude-monit-reviewer - Posting as: monit-reviewer
Summary
| Reviewer | Findings |
|---|---|
| go:implementation-tests | 0 |
| policies:conventions | 0 |
| security:code-auditor | 0 |
| architecture:solid-reviewer-agnostic | 0 |
Reviewer Coverage
go:implementation-tests— complete (constrained); inspected 6 assigned files (7 inspected across reviewers):shared/credstore/credstore.go,shared/credstore/relocate.go,shared/credstore/relocate_test.go,tools/jtk/internal/cmd/configcmd/configcmd.go,tools/jtk/internal/config/source.go,tools/jtk/internal/config/source_test.go; skipped: none; constraints: nonepolicies:conventions— complete (constrained); inspected 2 assigned files (7 inspected across reviewers):tools/jtk/internal/cmd/configcmd/configcmd.go,tools/jtk/internal/config/source.go; skipped: none; constraints: nonesecurity:code-auditor— complete (constrained); inspected 2 assigned files (7 inspected across reviewers):tools/jtk/CHANGELOG.md,tools/jtk/internal/config/source.go; skipped: none; constraints: nonearchitecture:solid-reviewer-agnostic— complete (constrained); inspected 1 assigned file (7 inspected across reviewers):tools/jtk/internal/config/source.go; skipped: none; constraints: Both earlier findings are settled: activeConfigPath now delegates to credstore.SharedRuntimePath, which is built on the same resolveSharedRuntime as LoadSharedRuntime, and the default_project label now uses credstore.SourceJTK. Did not run go test; judged from source and the d48c3a5..268e5ad diff, including the supporting credstore changes (SharedRuntimePath, SourceJTK) that source.go now depends on. activeConfigPath discards the SharedRuntimePath error on purpose. This is acceptable because loadShared already surfaces the same error through its warn-once, and an empty path correctly falls back to the legacy file.
Inspected files (7)
shared/credstore/credstore.goshared/credstore/relocate.goshared/credstore/relocate_test.gotools/jtk/CHANGELOG.mdtools/jtk/internal/cmd/configcmd/configcmd.gotools/jtk/internal/config/source.gotools/jtk/internal/config/source_test.go
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 1m 32s | ~$1.17 (est.) | claude-sonnet-5, claude-opus-5-5 | cr 0.10.318
| Field | Value |
|---|---|
| Model | claude-sonnet-5, claude-opus-5-5 |
| Reviewers | go:implementation-tests, policies:conventions, security:code-auditor, architecture:solid-reviewer-agnostic |
| Engine | claude_cli · claude-sonnet-5, claude-opus-5-5 |
| Reviewed by | cr · monit-reviewer |
| Duration | 1m 32s wall · 2m 20s compute |
| Cost | ~$1.17 (est.) |
| Pricing basis | anthropic-public-2026-09-23 |
| Tokens | 40 in / 6.8k out |
Per-workstream usage
go:implementation-tests— claude-sonnet-5- In: 10
- Out: 2.0k
- Cache read: 382.0k
- Cache create: 65.3k
- Cost: ~$0.36 (est.)
- Duration: 49s
policies:conventions— claude-sonnet-5- In: 8
- Out: 1.7k
- Cache read: 279.4k
- Cache create: 58.5k
- Cost: ~$0.31 (est.)
- Duration: 28s
security:code-auditor— claude-sonnet-5- In: 8
- Out: 925
- Cache read: 237.3k
- Cache create: 48.8k
- Cost: ~$0.25 (est.)
- Duration: 24s
architecture:solid-reviewer-agnostic— claude-opus-5-5- In: 8
- Out: 1.7k
- Cache read: 271.2k
- Cache create: 9.5k
- Cost: ~$0.16 (est.)
- Duration: 27s
orchestrator-rollup— claude-sonnet-5- In: 6
- Out: 469
- Cache read: 182.8k
- Cache create: 11.2k
- Cost: ~$0.09 (est.)
- Duration: 9s
monit-reviewer
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: 064403a2aa8b
Profile: claude-monit-reviewer - Posting as: monit-reviewer
Summary
| Reviewer | Findings |
|---|---|
| go:implementation-tests | 0 |
| policies:conventions | 0 |
| security:code-auditor | 0 |
| architecture:solid-reviewer-agnostic | 0 |
Reviewer Coverage
go:implementation-tests— complete (constrained); inspected 6 assigned files (7 inspected across reviewers):shared/credstore/credstore.go,shared/credstore/relocate.go,shared/credstore/relocate_test.go,tools/jtk/internal/cmd/configcmd/configcmd.go,tools/jtk/internal/config/source.go,tools/jtk/internal/config/source_test.go; skipped: none; constraints: nonepolicies:conventions— complete (constrained); inspected 2 assigned files (7 inspected across reviewers):tools/jtk/internal/cmd/configcmd/configcmd.go,tools/jtk/internal/config/source.go; skipped: none; constraints: nonesecurity:code-auditor— complete (constrained); inspected 2 assigned files (7 inspected across reviewers):tools/jtk/CHANGELOG.md,tools/jtk/internal/config/source.go; skipped: none; constraints: nonearchitecture:solid-reviewer-agnostic— complete (constrained); inspected 1 assigned file (7 inspected across reviewers):tools/jtk/internal/config/source.go; skipped: none; constraints: Did not run go test; judged from source. Earlier findings are settled: activeConfigPath delegates to credstore.SharedRuntimePath, which shares resolveSharedRuntime with LoadSharedRuntime, and default_project uses credstore.SourceJTK. Head 064403a only adds a merge of main on top of 268e5ad. tools/jtk/internal/config/ and shared/credstore/ are byte-identical to the previously reviewed head, so the earlier assessment carries over unchanged.
Inspected files (7)
shared/credstore/credstore.goshared/credstore/relocate.goshared/credstore/relocate_test.gotools/jtk/CHANGELOG.mdtools/jtk/internal/cmd/configcmd/configcmd.gotools/jtk/internal/config/source.gotools/jtk/internal/config/source_test.go
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 3m 03s | ~$3.08 (est.) | claude-sonnet-5, claude-opus-5-5 | cr 0.10.318
| Field | Value |
|---|---|
| Model | claude-sonnet-5, claude-opus-5-5 |
| Reviewers | go:implementation-tests, policies:conventions, security:code-auditor, architecture:solid-reviewer-agnostic |
| Engine | claude_cli · claude-sonnet-5, claude-opus-5-5 |
| Reviewed by | cr · monit-reviewer |
| Duration | 3m 03s wall · 4m 25s compute |
| Cost | ~$3.08 (est.) |
| Pricing basis | anthropic-public-2026-09-23 |
| Tokens | 36 in / 4.5k out |
Per-workstream usage
go:implementation-tests— claude-sonnet-5- In: 8
- Out: 1.1k
- Cache read: 245.6k
- Cache create: 171.4k
- Cost: ~$0.75 (est.)
- Duration: 1m 24s
policies:conventions— claude-sonnet-5- In: 8
- Out: 948
- Cache read: 235.3k
- Cache create: 161.7k
- Cost: ~$0.70 (est.)
- Duration: 48s
security:code-auditor— claude-sonnet-5- In: 8
- Out: 870
- Cache read: 214.6k
- Cache create: 139.8k
- Cost: ~$0.61 (est.)
- Duration: 42s
architecture:solid-reviewer-agnostic— claude-opus-5-5- In: 8
- Out: 1.2k
- Cache read: 237.2k
- Cache create: 75.5k
- Cost: ~$0.68 (est.)
- Duration: 44s
orchestrator-rollup— claude-sonnet-5- In: 4
- Out: 356
- Cache read: 53.9k
- Cache create: 82.1k
- Cost: ~$0.34 (est.)
- Duration: 45s
Problem
jtk config showskips the shared~/.config/atlassian-cli/config.ymlthat the runtime resolvers actually use. Afterjtk initwrites the shared store,config showrenders url/email/default_project as empty-rows and prints the legacy per-tool path (which may not even exist) asConfig file:. A fully working configuration looks unconfigured:while
jtk mesucceeds. The blind spot was documented in the command's help text, but as a diagnostic surface it misleads more than it explains — I hit it minutes after a successfuljtk init.Fix
GetURLWithSource,GetEmailWithSource,GetDefaultProjectWithSourcenow consult the shared store between env and the legacy file — the same precedence the runtime getters use (auth_methodandcloud_idalready did this viajtkSectionWithSource).Config file:row names the file actually read: the shared store when it exists on disk, else the legacy path.After
Tests
Two new tests: shared-store values surface with the shared source label and the path row names the shared file; shared beats legacy per field (url from shared, email falling through to legacy).
go test ./tools/jtk/...green,gofmtclean.