feat(cli): read a config file for the deployment URL and last-used identity - #336
Merged
blockchain-maxis merged 3 commits intoSep 2, 2026
Conversation
Every CLI issue is blocked on this module existing. Add cli/ as a standalone Go module (go 1.25, no cgo) alongside the pnpm workspace, building a signet binary via cobra: cmd/signet/main.go is the entrypoint, internal/cmd holds the command tree, and internal/link, internal/keys, internal/spec are placeholder packages for the wallet-linking, key-management, and API-spec work that follows. signet --version carries a version and commit string injected via ldflags. signet --help and a bare `signet` invocation both print real usage text — cobra only renders the Usage: section when a command is Runnable() or has subcommands, so the root command needed an explicit RunE (falling through to cmd.Help()) to show it before any subcommand exists. golangci-lint is configured via cli/.golangci.yml, and a new CI job builds, vets, tests, and lints the module. Verified go build/go vet/go test all pass, and the binary cross-compiles with CGO_ENABLED=0 for linux/amd64 and darwin/arm64.
…entity Self-hosters and testnet users need to point the CLI at a deployment other than the default, and repeat runs shouldn't re-ask which identity to use. Every invocation needing --url and --source made self-hosted deployments second-class. Add internal/config: Load/Save a JSON file under os.UserConfigDir()/ signet (baseUrl, source), and Resolve combines flag > env (SIGNET_URL, baseUrl only) > config file > built-in default per field. Wire --url/ --source as persistent flags on the root command, resolved in PersistentPreRunE and attached to the command context via config.WithResolved/FromContext for subcommands to read once they exist. An explicit --source is saved back to the config file (RememberSource) so the next run without it picks the same identity back up. No config file is required for the default deployment. Document the precedence and file location in cli/README.md, and add SIGNET_URL to check-docs.mjs's ENV_ALLOW list — it's the cli/ module's own shell env, not part of the pnpm workspace's .env.
|
@ibochivincent-lang is attempting to deploy a commit to the blockchainmaxis-8449's projects Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for stellar-signet ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
@ibochivincent-lang Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This was referenced Aug 30, 2026
This was referenced Aug 30, 2026
This was referenced Aug 30, 2026
blockchain-maxis#335 landed as a squash, so its files came back as add/add conflicts against this branch's copy of the same commit. Verified main's cli/ tree is identical to 8dbbe29 (the commit this branch was built on) before resolving, so: - cli/README.md, cli/internal/cmd/root.go, cli/internal/cmd/root_test.go: take this branch's versions, which are blockchain-maxis#335's content plus this PR's config work. - .github/workflows/ci.yml, README.md: take main's, which carry the golangci fixes made while merging blockchain-maxis#335 (action v8 + a golangci-lint built with Go 1.25) and main's removal of the packages/ui row. Verified after resolving: go build, go vet, go test, gofmt -l and golangci-lint v2.13.2 all clean; node scripts/check-docs.mjs passes.
blockchain-maxis
merged commit Sep 2, 2026
d2f133d
into
blockchain-maxis:main
10 of 11 checks passed
blockchain-maxis
added a commit
to ibochielizabeth-spec/signet
that referenced
this pull request
Sep 2, 2026
blockchain-maxis#335 and blockchain-maxis#336 landed as squashes, so their files came back as add/add conflicts against this branch's cherry-picks of the same work: - .github/workflows/ci.yml, README.md: take main's (carries the golangci action/version fixes and the packages/ui removal). - cli/internal/cmd/root.go: main's version is blockchain-maxis#336's fuller one (config resolution in PersistentPreRunE); this branch only adds AddCommand(newLinkCmd()). - cli/README.md: take this branch's, which documents the link command. Also made the non-JSON output stop claiming a link that did not happen. internal/keys and internal/spec are still scaffolds, so 'Linked aquawolf to G… (testnet)' reported a success for a no-op. It now reads 'Validated … Not yet submitted — the on-chain claim is not implemented.' The --json contract is untouched, which is what issue blockchain-maxis#264 and the downstream stack depend on. Verified: go build/vet/test, gofmt -l, golangci-lint v2.13.2 (0 issues), plus a manual run of all three paths — --json emits exactly one JSON line on stdout, the human path writes the honest summary, and an invalid handle leaves stdout empty with the error on stderr and exit 1.
blockchain-maxis
added a commit
to Mamavee001/signet
that referenced
this pull request
Sep 2, 2026
…error Conflict resolution against the squashed blockchain-maxis#335/blockchain-maxis#336/blockchain-maxis#342: - .github/workflows/ci.yml, README.md: main's. - cli/cmd/signet/main.go: this branch's exit-code mapping (the point of the PR). - cli/internal/cmd/link.go, cli/README.md: main's honest 'Validated … not yet submitted' wording rather than this branch's older 'Linked …'. - cli/internal/link/link.go: this branch's ValidationError and public-key redaction. The secret-hygiene test only inspected cobra's output buffers. The command tree runs with SilenceErrors, so a returned error never reaches those buffers — cmd/signet/main.go prints it to the process's real stderr. The test therefore could not fail no matter what an error message said, which is the half of the acceptance criterion ('stdout, stderr, or an error string') that most needed covering. Now asserts the error string too. That immediately caught a real leak. The public-key path was already careful not to echo its input, but the handle path was not: $ signet link SASAAEJC6P5U…UUEMCD --public-key GASAAEJC… invalid handle "SASAAEJC6P5U…UUEMCD": expected 1-32 lowercase letters… Reproduced with the built binary, not just in a test — a seed put in the wrong argument slot was read straight back into shell history and any CI log. Errors now pass the value through redactSecrets, so an ordinary typo is still echoed ('invalid handle "Bad Handle"') while a secret-shaped value becomes '[redacted: secret-shaped value]'. Verified: go build, go vet, gofmt -l, golangci-lint v2.13.2 (0 issues) and go test -race ./... all clean, plus the built binary — redaction confirmed, typo feedback intact, and exit codes 2 for invalid input / 0 for success.
blockchain-maxis
added a commit
to Mamavee001/signet
that referenced
this pull request
Sep 2, 2026
Conflict resolution against the squashed blockchain-maxis#335/blockchain-maxis#336/blockchain-maxis#342: - .github/workflows/ci.yml, README.md: main's. - cli/cmd/signet/main.go, cli/internal/link/link.go, cli/internal/cmd/link.go: this branch's, which carry blockchain-maxis#345's exit-code mapping that this PR is stacked on. Taking main's first silently dropped it — caught because the shim then forwarded exit 1 instead of 2 in the end-to-end check below. - cli/README.md: this branch's, with the stale 'Linked …' example updated to main's honest 'Validated … not yet submitted' wording. - scripts/check-docs.mjs: keep the CLI_RELEASE_ENABLED / NPM_TOKEN allowlist entries (GitHub repo variable and Actions secret, not app env). Reapplied the handle-error secret redaction from blockchain-maxis#345, which this branch predates. Verified the release path end to end rather than by reading it — built a linux/amd64 binary with the workflow's own ldflags, staged it through scripts/release/stage-platform-package.mjs, pinned with pin-shim-version.mjs, laid the two packages out as npm would under node_modules/@signet, and ran the shim: --version -> signet version 9.9.9-test (commit deadbeef) link --json -> one JSON object, nothing else invalid handle, $? -> 2 (the shim forwards the binary's real exit code) Then reverted the staged binary and the 9.9.9-test version pins. Publishing stays inert on merge: release-cli.yml triggers only on a cli-v* tag (none exist) and the npm publish step is additionally gated on vars.CLI_RELEASE_ENABLED, which is not set. go build/vet/test -race, gofmt, golangci-lint v2.13.2 (0 issues) and check-docs all clean.
blockchain-maxis
added a commit
to Otfrugger/signet
that referenced
this pull request
Sep 2, 2026
This PR's only real change is the cross-compile smoke build; everything else in the diff is cherry-picked blockchain-maxis#335/blockchain-maxis#336/blockchain-maxis#342/blockchain-maxis#345, all now squashed onto main. Took main's version of every one of those files. ci.yml keeps all three improvements rather than either side: - `go test -race ./...` from this branch (issue blockchain-maxis#252 asks for -race; main still had a plain `go test`), - the golangci-lint action v8 + pinned v2.13.2 from main, - the four-target cross-compile smoke build this PR adds. Noted in the comment that the target set matches what release-cli.yml publishes, so the two cannot silently diverge. Verified locally: all four targets build with CGO_ENABLED=0, and go test -race ./... is clean across all 7 packages.
blockchain-maxis
added a commit
to Otfrugger/signet
that referenced
this pull request
Sep 2, 2026
Everything except cli/internal/browser/ and its docs was a cherry-pick of blockchain-maxis#335/blockchain-maxis#336/blockchain-maxis#342/blockchain-maxis#345/blockchain-maxis#356/blockchain-maxis#357/blockchain-maxis#358, all now on main — took main's for all of those. scripts/check-docs.mjs keeps all three allowlist entries rather than either side's pair (WAYLAND_DISPLAY from this branch, CLI_RELEASE_ENABLED and NPM_TOKEN from blockchain-maxis#346). Verified the fallback behaves as issue blockchain-maxis#257 requires, by driving OpenOrPrint with DISPLAY and WAYLAND_DISPLAY unset: headless, browser allowed -> prints 'Open this URL to continue: <url>', returns nil --no-browser -> same so the opener's failure is absorbed rather than propagated, and both paths reach the developer at the same URL. Left unwired deliberately, unlike blockchain-maxis#357's CheckStellarCLI: there is no call site to attach it to yet — `signet link` performs no approval flow (that lands with the loopback server and the pairing endpoints), so wiring it now would mean inventing the flow rather than connecting to one. Both the package doc and cli/README say so plainly. go build/vet, gofmt, golangci-lint v2.13.2 (0 issues), go test -race ./... and check-docs all clean.
blockchain-maxis
added a commit
to manchesternews98-jpg/signet
that referenced
this pull request
Sep 2, 2026
This branch introduced its own internal/keys design (a Runner interface plus context-taking List/PublicKey/Resolve) while blockchain-maxis#345/blockchain-maxis#357/blockchain-maxis#358 built a different one on main — a package-level `run` seam, CheckStellarCLI version guard, exitcode sentinels, and secret redaction. Rather than pick a side and lose work, kept main's package and ported this PR's new capability onto it: - keys.List(binary) shells `stellar keys ls` through the same `run` seam and the same CheckStellarCLI guard, so a missing or too-old stellar is reported identically here. - keys.Resolve(binary, explicit, prompt) picks --source, else the sole identity, else the prompt; a nil prompt (CI, --json) yields ErrAmbiguousIdentity instead of hanging on stdin. Both new sentinels wrap exitcode.ErrNoIdentity, so they map to the documented exit code 4. - identity.go keeps its command and interactive selector, rewired to keys.Resolve/keys.ResolvePublicKey and registered on main's root (which carries blockchain-maxis#336's config resolution). - execrunner_test.go is dropped with the ExecRunner type it tested; it also declared a second TestMain, which broke the package build. - Ported six tests onto main's fixtures: List returns every identity, an explicit source never shells out, the sole identity is auto-picked, no identities and an ambiguous set each report their sentinel, and the prompt is offered the full list. Extended the fake stellar to answer `keys ls` (via FAKESTELLAR_IDENTITIES) and to resolve a second identity. golangci-lint flagged four unchecked writes in identity.go (errcheck); now checked, matching how link.go already returns its write error. Verified against the fake binary end to end: one identity resolves silently, several with no tty refuses rather than hanging, none reports the actionable message, and piping a selection picks that identity and prints its public key. Also grepped the whole cli/ tree — no `keys show`, no `--sign-with-key`, no secret parsing anywhere, which is what issue blockchain-maxis#253 is actually about. All 6 Go packages pass go test -race; gofmt, golangci-lint v2.13.2 (0 issues) and check-docs clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #262
Stacked on #335 (
feat: scaffold the cli/ Go module, closing #251) — this branch is built on top of that scaffold, since there was nocli/module to add a config file to before it. This PR's diff includes #335's commit until that one merges; the commit to actually review here is the top one (dd39804).Summary
Self-hosters and testnet users need to point the CLI at a deployment other than the default, and repeat runs shouldn't have to re-ask which identity to use.
Changes
cli/internal/config/config.go(new):File{BaseURL, Source}persisted as JSON underos.UserConfigDir()/signet/config.json.Load/Save/Dir/Pathfor reading and writing it (a missing file reads back as a zero-valueFile, no error — that's what makes the default deployment need no config file at all).RememberSourceupdates just theSourcefield, leavingBaseURLalone.Resolve(opts, file) Resolved: combines flag > env (SIGNET_URL,baseUrlonly — there's no env override for identity) > config file > built-in default (DefaultBaseURL = https://signet-web-pearl.vercel.app, the deployed instance from the README's Live demo section), decided independently per field.ResolveOptions.FlagURLSet/FlagSourceSetdistinguish "flag not passed" from "flag explicitly passed as empty".cli/internal/config/context.go(new):WithResolved/FromContextso the root command's resolution runs once and subcommands (once they exist) read the result back off the command's context instead of re-resolving it.cli/internal/cmd/root.go: added--url/--sourcepersistent flags;PersistentPreRunEloads the config file, resolves it against the flags andSIGNET_URL, attaches the result to the command context, and callsRememberSourcewhen--sourcewas explicitly passed — so the next invocation without--sourcepicks the same identity back up.cli/internal/cmd/root_test.go: added tests for the full resolution chain (default / config file / env / flag, in precedence order) and for the source-remembering round trip, run through the actual command (not just the library function) so the wiring itself is covered, not onlyResolve's logic. Also confirmed (empirically, via these tests) that Cobra never runsPersistentPreRunEfor--help/--version— they short-circuit before it — so those two didn't need config isolation.cli/internal/config/config_test.go: unit tests forLoad/Save/RememberSourceandResolve's precedence, isolated from the real user's config dir viat.Setenvon bothXDG_CONFIG_HOMEandAppData(whichever the current OS ignores is a no-op, so the same helper works on any dev machine and in CI).cli/README.md: documents the precedence order, the config file's location per OS, and its JSON shape.scripts/check-docs.mjs: addedSIGNET_URLtoENV_ALLOW— it's the CLI's own shell env var, not part of the pnpm workspace's.env, so it doesn't belong in.env.example.Verification
go build ./.../go vet ./.../go test ./...— all pass (21/21 tests acrossinternal/cmdandinternal/config).golangci-lint run ./...— 0 issues.node scripts/check-docs.mjs— passes (was failing on theSIGNET_URLreference before theENV_ALLOWaddition).--helplists--url/--source; with a clean config dir, noconfig.jsonexists and the defaultbaseUrlis used; running--source aliceonce createsconfig.jsonwith{"source":"alice"};SIGNET_URL=... ./signet --helpruns without error.