oauth-tty 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,57 +1,686 @@
1
- <p align="center">
2
- <a href="http://oauth.net/core/1.0/" target="_blank" rel="noopener">
3
- <img width="124px" src="https://github.com/oauth-xx/oauth-ruby/raw/main/docs/images/logo/Oauth_logo.svg?raw=true" alt="OAuth 1.0 Logo by Chris Messina, CC BY-SA 3.0, via Wikimedia Commons">
4
- </a>
5
- <a href="https://www.ruby-lang.org/" target="_blank" rel="noopener">
6
- <img width="124px" src="https://github.com/oauth-xx/oauth-ruby/raw/main/docs/images/logo/ruby-logo-198px.svg?raw=true" alt="Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5">
7
- </a>
8
- </p>
1
+ [![Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0][🖼️galtzo-i]][🖼️galtzo-discord] [![ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5][🖼️ruby-lang-i]][🖼️ruby-lang] [![oauth Logo by Chris Messina, CC BY-SA 3.0][🖼️oauth-tty-i]][🖼️oauth-tty]
9
2
 
10
- # OAuth::TTY
3
+ [🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
4
+ [🖼️galtzo-discord]: https://discord.gg/3qme4XHNKN
5
+ [🖼️ruby-lang-i]: https://logos.galtzo.com/assets/images/ruby-lang/avatar-192px.svg
6
+ [🖼️ruby-lang]: https://www.ruby-lang.org/
7
+ [🖼️oauth-tty-i]: https://logos.galtzo.com/assets/images/oauth/avatar-192px.svg
8
+ [🖼️oauth-tty]: https://github.com/ruby-oauth/oauth-tty
11
9
 
12
- A TTY Command Line Interface for interacting with OAuth 1.0 services.
10
+ # 🖥️ OAuth::TTY
13
11
 
14
- This library was written originally by [Thiago Pinto](https://github.com/thiagopintodev) in 2016 and bundled with the oauth gem.
15
- It was extracted into a separate library by [Peter Boling](https://railsbling.com) in 2022 as part of the move to a stable version 1.0 for the oauth gem.
12
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
16
13
 
17
- ## Installation
14
+ `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
15
+
16
+ ---
17
+
18
+ `if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
19
+
20
+ [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
21
+
22
+ ## 🌻 Synopsis
23
+
24
+ OAuth 1.0a is an industry-standard protocol for authorization.
25
+ It is an update to the original OAuth 1.0 protocol, and is used by many popular services.
26
+
27
+ This RubyGem provides a CLI for OAuth 1.0 or 1.0a _clients_ and _servers_ in Ruby applications.
28
+
29
+ All dependencies of this gem are signed, so it can be installed with a `HighSecurity` profile.
30
+
31
+ * [OAuth 1.0 Spec][oauth1-spec]
32
+ * [oauth sibling gem][sibling-gem] for OAuth 1.0 / 1.0a client and server implementations in Ruby.
33
+ * [oauth2 sibling gem][sibling2-gem] for OAuth 2.0 / 2.1, & OIDC client implementations in Ruby.
34
+
35
+ [oauth1-spec]: http://oauth.net/core/1.0/
36
+ [sibling-gem]: https://gitlab.com/ruby-oauth/oauth
37
+ [sibling2-gem]: https://gitlab.com/ruby-oauth/oauth2
38
+
39
+ ## 💡 Info you can shake a stick at
40
+
41
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
42
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
43
+ | Works with JRuby | ![JRuby 9.1 Compat][💎jruby-9.1i] ![JRuby 9.2 Compat][💎jruby-9.2i] ![JRuby 9.3 Compat][💎jruby-9.3i] <br/> [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
44
+ | Works with Truffle Ruby | ![Truffle Ruby 22.3 Compat][💎truby-22.3i] ![Truffle Ruby 23.0 Compat][💎truby-23.0i] <br/> [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
45
+ | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
46
+ | Works with MRI Ruby 2 | [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
47
+ | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
48
+ | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
49
+ | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
50
+ | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![Compatible with Apache Software Projects: Verified by SkyWalking Eyes][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
51
+ | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
52
+ | Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
53
+ | `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼‍♂️aboutme-img]][💖💁🏼‍♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
54
+
55
+ ### Compatibility
56
+
57
+ Compatible with MRI Ruby 2.3.0+, and concordant releases of JRuby, and TruffleRuby.
58
+
59
+ | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
60
+ |------------------------------------------------|--------------------------------------------------------|
61
+ | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
62
+
63
+ ### Federated DVCS
64
+
65
+ <details>
66
+ <summary>Find this repo on federated forges (Coming soon!)</summary>
67
+
68
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
69
+ |-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
70
+ | 🧪 [ruby-oauth/oauth-tty on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
71
+ | 🧊 [ruby-oauth/oauth-tty on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
72
+ | 🐙 [ruby-oauth/oauth-tty on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
73
+ | 🤼 [OAuth Ruby Google Group][⛳gg-discussions] | "Active" | ➖ | ➖ | ➖ | ➖ | [💚][⛳gg-discussions] |
74
+ | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
75
+
76
+ </details>
77
+
78
+ [gh-discussions]: https://github.com/ruby-oauth/oauth-tty/discussions
79
+
80
+ ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/oauth-tty)](https://tidelift.com/subscription/pkg/rubygems-oauth-tty?utm_source=rubygems-oauth-tty&utm_medium=referral&utm_campaign=readme)
81
+
82
+ Available as part of the Tidelift Subscription.
83
+
84
+ <details>
85
+ <summary>Need enterprise-level guarantees?</summary>
86
+
87
+ The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
88
+
89
+ [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
90
+
91
+ - 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies
92
+ - 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
93
+ - 💡Tidelift pays maintainers to maintain the software you depend on!<br/>📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
94
+
95
+ Alternatively:
96
+
97
+ - [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
98
+ - [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork]
99
+ - [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor]
100
+
101
+ </details>
102
+
103
+ ## ✨ Installation
18
104
 
19
105
  Install the gem and add to the application's Gemfile by executing:
20
106
 
21
- $ bundle add oauth-tty
107
+ ```console
108
+ bundle add oauth-tty
109
+ ```
22
110
 
23
111
  If bundler is not being used to manage dependencies, install the gem by executing:
24
112
 
25
- $ gem install oauth-tty
113
+ ```console
114
+ gem install oauth-tty
115
+ ```
116
+
117
+ ### 🔒 Secure Installation
118
+
119
+ <details>
120
+ <summary>For Medium or High Security Installations</summary>
121
+
122
+ This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
123
+ [stone_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
124
+ by following the instructions below.
125
+
126
+ Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
127
+
128
+ ```console
129
+ gem cert --add <(curl -Ls https://raw.github.com/galtzo-floss/certs/main/pboling.pem)
130
+ ```
131
+
132
+ You only need to do that once. Then proceed to install with:
133
+
134
+ ```console
135
+ gem install oauth-tty -P HighSecurity
136
+ ```
137
+
138
+ The `HighSecurity` trust profile will verify signed gems, and not allow the installation of unsigned dependencies.
139
+
140
+ If you want to up your security game full-time:
141
+
142
+ ```console
143
+ bundle config set --global trust-policy MediumSecurity
144
+ ```
145
+
146
+ `MediumSecurity` instead of `HighSecurity` is necessary if not all the gems you use are signed.
147
+
148
+ NOTE: Be prepared to track down certs for signed gems and add them the same way you added mine.
149
+
150
+ </details>
151
+
152
+ ## ⚙️ Configuration
153
+
154
+ The oauth-tty gem is a thin CLI over the oauth gem. You supply your consumer credentials, token credentials (when applicable), a target URI, and optional parameters, and the tool signs requests or helps you complete an OAuth 1.0/1.0a 3-legged flow.
155
+
156
+ What you can configure
157
+ - Locations for OAuth parameters:
158
+ - --header (default): send OAuth params in Authorization header
159
+ - --body: send OAuth params in the request body
160
+ - --query-string: send OAuth params on the query string
161
+ - HTTP method: --method GET|POST|PUT|DELETE|… (default: POST)
162
+ - Signature method: --signature-method HMAC-SHA1|RSA-SHA1|PLAINTEXT (default: HMAC-SHA1)
163
+ - OAuth version: --version 1.0 (default: 1.0) or --no-version to omit
164
+ - Nonce/timestamp: auto-generated by default; can be overridden via --nonce and --timestamp
165
+ - Verbose output: --verbose prints the full signing breakdown, headers, and signature base string
166
+ - XMPP mode: --xmpp emits OAuth as an XMPP stanza instead of HTTP artifacts
167
+
168
+ Required inputs (by command)
169
+ - sign, query: --consumer-key, --consumer-secret, --token, --secret, and --uri
170
+ - authorize: --consumer-key, --consumer-secret, the OAuth endpoints below, and --uri (service resource you’re authorizing for)
171
+
172
+ Authorization endpoints (for oauth authorize)
173
+ - --request-token-url URL
174
+ - --authorize-url URL
175
+ - --access-token-url URL
176
+ - Optional: --callback-url URL (for 1.0a), --scope SCOPE (provider-specific)
177
+
178
+ Providing options
179
+ - CLI flags (preferred for quick usage)
180
+ - Options file: use -O or --options to read additional arguments from a file. The file is tokenized by whitespace; put the same flags you’d pass on the command line, spread across lines as needed.
181
+
182
+ Example options file (oauth.opts)
183
+ ```text
184
+ --consumer-key ck_123
185
+ --consumer-secret cs_456
186
+ --token at_789
187
+ --secret ats_abc
188
+ --method GET
189
+ --uri https://api.example.com/v1/profile
190
+ --parameters foo:bar
191
+ --parameters "status=active"
192
+ --header
193
+ ```
194
+ Run with: oauth sign -O oauth.opts
195
+
196
+ Defaults at a glance
197
+ - scheme: header
198
+ - method: POST
199
+ - signature method: HMAC-SHA1
200
+ - oauth_version: 1.0 (omit with --no-version)
201
+ - nonce, timestamp: auto-generated each run
202
+
203
+ Tips
204
+ - For parameters you can use either key:value or already-escaped pairs like key=value. Repeat --parameters to add multiple pairs.
205
+ - When using --body, only methods that support bodies should be used (e.g., POST/PUT/PATCH).
206
+ - Some providers require exact parameter ordering and inclusion; use --verbose to see normalized parameters and the signature base string.
207
+
208
+ ## 🔧 Basic Usage
209
+
210
+ In a shell run `oauth` to start the console.
211
+
212
+ Quick help and version
213
+ ```console
214
+ oauth --help
215
+ oauth --version # or oauth -v
216
+ ```
217
+
218
+ Sign a request (minimal)
219
+ Print just the OAuth signature value for a GET request:
220
+ ```console
221
+ oauth sign \
222
+ --consumer-key ck \
223
+ --consumer-secret cs \
224
+ --token at \
225
+ --secret ats \
226
+ --method GET \
227
+ --uri "https://api.example.com/v1/resource?limit=10"
228
+ ```
229
+
230
+ Sign a request (verbose, header output)
231
+ ```console
232
+ oauth sign \
233
+ --consumer-key ck \
234
+ --consumer-secret cs \
235
+ --token at \
236
+ --secret ats \
237
+ --method POST \
238
+ --uri https://api.example.com/v1/resource \
239
+ --parameters "status=active" \
240
+ --header \
241
+ --verbose
242
+ ```
243
+ This prints OAuth parameters, normalized parameters, signature base string, Authorization header, and both raw and escaped signatures.
26
244
 
27
- NOTE: You might see a warning like:
245
+ Query a protected resource
246
+ Performs the signed HTTP request and prints the HTTP status and body.
247
+ ```console
248
+ oauth query \
249
+ --consumer-key ck \
250
+ --consumer-secret cs \
251
+ --token at \
252
+ --secret ats \
253
+ --method GET \
254
+ --uri https://api.example.com/v1/profile \
255
+ --parameters "fields=id,name"
28
256
  ```
29
- oauth-tty's executable "oauth" conflicts with oauth
30
- Overwrite the executable? [yN] y
257
+ Notes:
258
+ - The CLI will append any --parameters to the request URI’s query string and sign the request.
259
+ - Use --body or --header/--query-string to influence where OAuth params go; query also constructs OAuth via the consumer internally.
260
+
261
+ Start an OAuth 1.0a authorization flow
262
+ Guides you to obtain an access token and token secret from a provider.
263
+ ```console
264
+ oauth authorize \
265
+ --consumer-key ck \
266
+ --consumer-secret cs \
267
+ --request-token-url https://provider.example.com/oauth/request_token \
268
+ --authorize-url https://provider.example.com/oauth/authorize \
269
+ --access-token-url https://provider.example.com/oauth/access_token \
270
+ --callback-url https://yourapp.example.com/oauth/callback
31
271
  ```
32
- The `oauth` executable from this gem *is* the extracted and repackaged executable from the `oauth` gem, so you *should* overwrite it.
272
+ What happens:
273
+ - You’ll be shown an authorization URL to open in a browser.
274
+ - After approving, the provider shows a verifier (PIN). Paste it back into the prompt.
275
+ - The tool prints the access token and secret under “Response:”. Save those and use them with sign/query.
33
276
 
34
- ## Usage
277
+ Using an options file
278
+ ```console
279
+ oauth sign -O oauth.opts
280
+ ```
281
+ You can still add/override flags after -O; later flags win.
282
+
283
+ For more examples
284
+ - Run any command without args to see its specific help.
285
+ - Browse the specs under spec/oauth/tty for additional scenarios and edge cases.
35
286
 
36
287
  In a shell run `oauth` to start the console.
37
288
 
38
289
  For now, please see the tests for other usage.
39
290
 
40
- ## Development
291
+ ## 🦷 FLOSS Funding
292
+
293
+ While ruby-oauth tools are free software and will always be, the project would benefit immensely from some funding.
294
+ Raising a monthly budget of... "dollars" would make the project more sustainable.
295
+
296
+ We welcome both individual and corporate sponsors! We also offer a
297
+ wide array of funding channels to account for your preferences
298
+ (although currently [Open Collective][🖇osc] is our preferred funding platform).
299
+
300
+ **If you're working in a company that's making significant use of ruby-oauth tools we'd
301
+ appreciate it if you suggest to your company to become a ruby-oauth sponsor.**
302
+
303
+ You can support the development of ruby-oauth tools via
304
+ [GitHub Sponsors][🖇sponsor],
305
+ [Liberapay][⛳liberapay],
306
+ [PayPal][🖇paypal],
307
+ [Open Collective][🖇osc]
308
+ and [Tidelift][🏙️entsup-tidelift].
309
+
310
+ | 📍 NOTE |
311
+ |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
312
+ | If doing a sponsorship in the form of donation is problematic for your company <br/> from an accounting standpoint, we'd recommend the use of Tidelift, <br/> where you can get a support-like subscription instead. |
313
+
314
+ ### Open Collective for Individuals
315
+
316
+ Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ruby-oauth#backer)]
317
+
318
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
319
+
320
+ <!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
321
+ No backers yet. Be the first!
322
+ <!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
323
+
324
+ ### Open Collective for Organizations
325
+
326
+ Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/ruby-oauth#sponsor)]
327
+
328
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
329
+
330
+ <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
331
+ No sponsors yet. Be the first!
332
+ <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
333
+
334
+ [kettle-readme-backers]: https://github.com/ruby-oauth/oauth-tty/blob/main/exe/kettle-readme-backers
335
+
336
+ ### Another way to support open-source
337
+
338
+ > How wonderful it is that nobody need wait a single moment before starting to improve the world.<br/>
339
+ >—Anne Frank
340
+
341
+ I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions — totaling 79 hours of FLOSS coding over just the past seven days, a pretty regular week for me. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈‍ cats).
342
+
343
+ If you work at a company that uses my work, please encourage them to support me as a corporate sponsor. My work on gems you use might show up in `bundle fund`.
344
+
345
+ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed to empower open-source developers like myself to get paid for the work we do, in a sustainable way. Please give it a look.
346
+
347
+ **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
348
+
349
+ [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
350
+
351
+ ## 🔐 Security
352
+
353
+ See [SECURITY.md][🔐security].
354
+
355
+ ## 🤝 Contributing
356
+
357
+ If you need some ideas of where to help, you could work on adding more code coverage,
358
+ or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues][🤝gh-issues], or [PRs][🤝gh-pulls],
359
+ or use the gem and think about how it could be better.
360
+
361
+ We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
362
+
363
+ See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
364
+
365
+ ### 🚀 Release Instructions
366
+
367
+ See [CONTRIBUTING.md][🤝contributing].
368
+
369
+ ### Code Coverage
370
+
371
+ [![Coverage Graph][🏀codecov-g]][🏀codecov]
372
+
373
+ [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
374
+
375
+ [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
376
+
377
+ ### 🪇 Code of Conduct
378
+
379
+ Everyone interacting with this project's codebases, issue trackers,
380
+ chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
381
+
382
+ ## 🌈 Contributors
383
+
384
+ [![Contributors][🖐contributors-img]][🖐contributors]
385
+
386
+ Made with [contributors-img][🖐contrib-rocks].
387
+
388
+ Also see GitLab Contributors: [https://gitlab.com/ruby-oauth/oauth-tty/-/graphs/main][🚎contributors-gl]
389
+
390
+ <details>
391
+ <summary>⭐️ Star History</summary>
392
+
393
+ <a href="https://star-history.com/#ruby-oauth/oauth-tty&Date">
394
+ <picture>
395
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=ruby-oauth/oauth-tty&type=Date&theme=dark" />
396
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=ruby-oauth/oauth-tty&type=Date" />
397
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=ruby-oauth/oauth-tty&type=Date" />
398
+ </picture>
399
+ </a>
400
+
401
+ </details>
402
+
403
+ ## 📌 Versioning
404
+
405
+ This Library adheres to [![Semantic Versioning 2.0.0][📌semver-img]][📌semver].
406
+ Violations of this scheme should be reported as bugs.
407
+ Specifically, if a minor or patch version is released that breaks backward compatibility,
408
+ a new version should be immediately released that restores compatibility.
409
+ Breaking changes to the public API will only be introduced with new major versions.
410
+
411
+ > dropping support for a platform is both obviously and objectively a breaking change <br/>
412
+ >—Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
413
+
414
+ I understand that policy doesn't work universally ("exceptions to every rule!"),
415
+ but it is the policy here.
416
+ As such, in many cases it is good to specify a dependency on this library using
417
+ the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
418
+
419
+ For example:
420
+
421
+ ```ruby
422
+ spec.add_dependency("oauth-tty", "~> 1.0")
423
+ ```
424
+
425
+ <details>
426
+ <summary>📌 Is "Platform Support" part of the public API? More details inside.</summary>
427
+
428
+ SemVer should, IMO, but doesn't explicitly, say that dropping support for specific Platforms
429
+ is a *breaking change* to an API.
430
+ It is obvious to many, but not all, and since the spec is silent, the bike shedding is endless.
431
+
432
+ To get a better understanding of how SemVer is intended to work over a project's lifetime,
433
+ read this article from the creator of SemVer:
434
+
435
+ - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
436
+
437
+ </details>
438
+
439
+ See [CHANGELOG.md][📌changelog] for a list of releases.
440
+
441
+ ## 📄 License
442
+
443
+ The gem is available as open source under the terms of
444
+ the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
445
+ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
446
+
447
+ ### © Copyright
448
+
449
+ <ul>
450
+ <li>
451
+ Copyright (c) 2021-2022, 2025 Peter H. Boling, of
452
+ <a href="https://discord.gg/3qme4XHNKN">
453
+ Galtzo.com
454
+ <picture>
455
+ <img src="https://logos.galtzo.com/assets/images/galtzo-floss/avatar-128px-blank.svg" alt="Galtzo.com Logo (Wordless) by Aboling0, CC BY-SA 4.0" width="24">
456
+ </picture>
457
+ </a>, and oauth-tty contributors.
458
+ </li>
459
+ <li>
460
+ Copyright (c) 2016-2017 Thiago Pinto
461
+ </li>
462
+ </ul>
463
+
464
+ ## 🤑 A request for help
465
+
466
+ Maintainers have teeth and need to pay their dentists.
467
+ After getting laid off in an RIF in March and filled with many dozens of rejections,
468
+ I'm now spending ~60+ hours a week building open source tools.
469
+ I'm hoping to be able to pay for my kids' health insurance this month,
470
+ so if you value the work I am doing, I need your support.
471
+ Please consider sponsoring me or the project.
41
472
 
42
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
473
+ To join the community or get help 👇️ Join the Discord.
43
474
 
44
- To install this gem onto your local machine, run `bundle exec rake install`.
45
- To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
475
+ [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
46
476
 
47
- ## Contributing
477
+ To say "thanks!" ☝️ Join the Discord or 👇️ send money.
48
478
 
49
- Bug reports and pull requests are welcome on GitHub at [https://gitlab.com/oauth-xx/oauth-tty/-/issues](https://gitlab.com/oauth-xx/oauth-tty/-/issues). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://gitlab.com/oauth-xx/oauth-tty/-/blob/main/CODE_OF_CONDUCT.md).
479
+ [![Sponsor ruby-oauth/oauth-tty on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay-img] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal-img]
50
480
 
51
- ## License
481
+ ### Please give the project a star ⭐ ♥.
52
482
 
53
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
483
+ Thanks for RTFM. ☺️
54
484
 
55
- ## Code of Conduct
485
+ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
486
+ [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611
487
+ [⛳liberapay]: https://liberapay.com/pboling/donate
488
+ [🖇osc-all-img]: https://img.shields.io/opencollective/all/ruby-oauth
489
+ [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth
490
+ [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/ruby-oauth
491
+ [🖇osc-backers]: https://opencollective.com/ruby-oauth#backer
492
+ [🖇osc-backers-i]: https://opencollective.com/ruby-oauth/backers/badge.svg?style=flat
493
+ [🖇osc-sponsors]: https://opencollective.com/ruby-oauth#sponsor
494
+ [🖇osc-sponsors-i]: https://opencollective.com/ruby-oauth/sponsors/badge.svg?style=flat
495
+ [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/ruby-oauth?style=for-the-badge
496
+ [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth?style=for-the-badge
497
+ [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/ruby-oauth?style=for-the-badge
498
+ [🖇osc]: https://opencollective.com/ruby-oauth
499
+ [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github
500
+ [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github
501
+ [🖇sponsor]: https://github.com/sponsors/pboling
502
+ [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
503
+ [🖇polar]: https://polar.sh/pboling
504
+ [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
505
+ [🖇kofi]: https://ko-fi.com/O5O86SNP4
506
+ [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
507
+ [🖇patreon]: https://patreon.com/galtzo
508
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
509
+ [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
510
+ [🖇buyme]: https://www.buymeacoffee.com/pboling
511
+ [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
512
+ [🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A
513
+ [🖇paypal]: https://www.paypal.com/paypalme/peterboling
514
+ [🖇floss-funding.dev]: https://floss-funding.dev
515
+ [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding
516
+ [✉️discord-invite]: https://discord.gg/3qme4XHNKN
517
+ [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
518
+ [✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
519
+ [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
56
520
 
57
- Everyone interacting in the OAuth::TTY project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/oauth-xx/oauth-tty/-/blob/main/CODE_OF_CONDUCT.md).
521
+ [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
522
+ [⛳️gem-namespace]: https://github.com/ruby-oauth/oauth-tty
523
+ [⛳️namespace-img]: https://img.shields.io/badge/namespace-Oauth::Tty-3C2D2D.svg?style=square&logo=ruby&logoColor=white
524
+ [⛳️gem-name]: https://rubygems.org/gems/oauth-tty
525
+ [⛳️name-img]: https://img.shields.io/badge/name-oauth--tty-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
526
+ [⛳️tag-img]: https://img.shields.io/github/tag/ruby-oauth/oauth-tty.svg
527
+ [⛳️tag]: http://github.com/ruby-oauth/oauth-tty/releases
528
+ [🚂maint-blog]: http://www.railsbling.com/tags/oauth-tty
529
+ [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
530
+ [🚂maint-contact]: http://www.railsbling.com/contact
531
+ [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
532
+ [💖🖇linkedin]: http://www.linkedin.com/in/peterboling
533
+ [💖🖇linkedin-img]: https://img.shields.io/badge/PeterBoling-LinkedIn-0B66C2?style=flat&logo=newjapanprowrestling
534
+ [💖✌️wellfound]: https://wellfound.com/u/peter-boling
535
+ [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
536
+ [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
537
+ [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
538
+ [💖🐘ruby-mast]: https://ruby.social/@galtzo
539
+ [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo
540
+ [💖🦋bluesky]: https://bsky.app/profile/galtzo.com
541
+ [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
542
+ [💖🌳linktree]: https://linktr.ee/galtzo
543
+ [💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree
544
+ [💖💁🏼‍♂️devto]: https://dev.to/galtzo
545
+ [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white
546
+ [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling
547
+ [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white
548
+ [💖🧊berg]: https://codeberg.org/pboling
549
+ [💖🐙hub]: https://github.org/pboling
550
+ [💖🛖hut]: https://sr.ht/~galtzo/
551
+ [💖🧪lab]: https://gitlab.com/pboling
552
+ [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share
553
+ [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
554
+ [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
555
+ [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
556
+ [🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-oauth-tty?utm_source=rubygems-oauth-tty&utm_medium=referral&utm_campaign=readme
557
+ [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
558
+ [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
559
+ [💁🏼‍♂️peterboling]: http://www.peterboling.com
560
+ [🚂railsbling]: http://www.railsbling.com
561
+ [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
562
+ [📜src-gl]: https://gitlab.com/ruby-oauth/oauth-tty/
563
+ [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
564
+ [📜src-cb]: https://codeberg.org/ruby-oauth/oauth-tty
565
+ [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
566
+ [📜src-gh]: https://github.com/ruby-oauth/oauth-tty
567
+ [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
568
+ [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
569
+ [📜gl-wiki]: https://gitlab.com/ruby-oauth/oauth-tty/-/wikis/home
570
+ [📜gh-wiki]: https://github.com/ruby-oauth/oauth-tty/wiki
571
+ [📜gl-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
572
+ [📜gh-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
573
+ [👽dl-rank]: https://rubygems.org/gems/oauth-tty
574
+ [👽dl-ranki]: https://img.shields.io/gem/rd/oauth-tty.svg
575
+ [👽oss-help]: https://www.codetriage.com/ruby-oauth/oauth-tty
576
+ [👽oss-helpi]: https://www.codetriage.com/ruby-oauth/oauth-tty/badges/users.svg
577
+ [👽version]: https://rubygems.org/gems/oauth-tty
578
+ [👽versioni]: https://img.shields.io/gem/v/oauth-tty.svg
579
+ [🏀qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/oauth-tty
580
+ [🏀qlty-mnti]: https://qlty.sh/gh/ruby-oauth/projects/oauth-tty/maintainability.svg
581
+ [🏀qlty-cov]: https://qlty.sh/gh/ruby-oauth/projects/oauth-tty/metrics/code?sort=coverageRating
582
+ [🏀qlty-covi]: https://qlty.sh/gh/ruby-oauth/projects/oauth-tty/coverage.svg
583
+ [🏀codecov]: https://codecov.io/gh/ruby-oauth/oauth-tty
584
+ [🏀codecovi]: https://codecov.io/gh/ruby-oauth/oauth-tty/graph/badge.svg
585
+ [🏀coveralls]: https://coveralls.io/github/ruby-oauth/oauth-tty?branch=main
586
+ [🏀coveralls-img]: https://coveralls.io/repos/github/ruby-oauth/oauth-tty/badge.svg?branch=main
587
+ [🖐codeQL]: https://github.com/ruby-oauth/oauth-tty/security/code-scanning
588
+ [🖐codeQL-img]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/codeql-analysis.yml/badge.svg
589
+ [🚎1-an-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/ancient.yml
590
+ [🚎1-an-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/ancient.yml/badge.svg
591
+ [🚎2-cov-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/coverage.yml
592
+ [🚎2-cov-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/coverage.yml/badge.svg
593
+ [🚎3-hd-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/heads.yml
594
+ [🚎3-hd-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/heads.yml/badge.svg
595
+ [🚎4-lg-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/legacy.yml
596
+ [🚎4-lg-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/legacy.yml/badge.svg
597
+ [🚎5-st-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/style.yml
598
+ [🚎5-st-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/style.yml/badge.svg
599
+ [🚎6-s-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/supported.yml
600
+ [🚎6-s-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/supported.yml/badge.svg
601
+ [🚎7-us-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/unsupported.yml
602
+ [🚎7-us-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/unsupported.yml/badge.svg
603
+ [🚎8-ho-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/hoary.yml
604
+ [🚎8-ho-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/hoary.yml/badge.svg
605
+ [🚎9-t-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/truffle.yml
606
+ [🚎9-t-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/truffle.yml/badge.svg
607
+ [🚎10-j-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/jruby.yml
608
+ [🚎10-j-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/jruby.yml/badge.svg
609
+ [🚎11-c-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/current.yml
610
+ [🚎11-c-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/current.yml/badge.svg
611
+ [🚎12-crh-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/dep-heads.yml
612
+ [🚎12-crh-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/dep-heads.yml/badge.svg
613
+ [🚎13-🔒️-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/locked_deps.yml
614
+ [🚎13-🔒️-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/locked_deps.yml/badge.svg
615
+ [🚎14-🔓️-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/unlocked_deps.yml
616
+ [🚎14-🔓️-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/unlocked_deps.yml/badge.svg
617
+ [🚎15-🪪-wf]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/license-eye.yml
618
+ [🚎15-🪪-wfi]: https://github.com/ruby-oauth/oauth-tty/actions/workflows/license-eye.yml/badge.svg
619
+ [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
620
+ [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
621
+ [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
622
+ [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
623
+ [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
624
+ [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
625
+ [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white
626
+ [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
627
+ [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
628
+ [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
629
+ [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
630
+ [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
631
+ [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
632
+ [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
633
+ [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
634
+ [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
635
+ [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=red
636
+ [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=red
637
+ [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=red
638
+ [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red
639
+ [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
640
+ [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
641
+ [🤝gh-issues]: https://github.com/ruby-oauth/oauth-tty/issues
642
+ [🤝gh-pulls]: https://github.com/ruby-oauth/oauth-tty/pulls
643
+ [🤝gl-issues]: https://gitlab.com/ruby-oauth/oauth-tty/-/issues
644
+ [🤝gl-pulls]: https://gitlab.com/ruby-oauth/oauth-tty/-/merge_requests
645
+ [🤝cb-issues]: https://codeberg.org/ruby-oauth/oauth-tty/issues
646
+ [🤝cb-pulls]: https://codeberg.org/ruby-oauth/oauth-tty/pulls
647
+ [🤝cb-donate]: https://donate.codeberg.org/
648
+ [🤝contributing]: CONTRIBUTING.md
649
+ [🏀codecov-g]: https://codecov.io/gh/ruby-oauth/oauth-tty/graphs/tree.svg
650
+ [🖐contrib-rocks]: https://contrib.rocks
651
+ [🖐contributors]: https://github.com/ruby-oauth/oauth-tty/graphs/contributors
652
+ [🖐contributors-img]: https://contrib.rocks/image?repo=ruby-oauth/oauth-tty
653
+ [🚎contributors-gl]: https://gitlab.com/ruby-oauth/oauth-tty/-/graphs/main
654
+ [🪇conduct]: CODE_OF_CONDUCT.md
655
+ [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg
656
+ [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
657
+ [📌semver]: https://semver.org/spec/v2.0.0.html
658
+ [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat
659
+ [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
660
+ [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
661
+ [📌changelog]: CHANGELOG.md
662
+ [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
663
+ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
664
+ [📌gitmoji]:https://gitmoji.dev
665
+ [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
666
+ [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
667
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.296-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
668
+ [🔐security]: SECURITY.md
669
+ [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
670
+ [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
671
+ [📄license]: LICENSE.txt
672
+ [📄license-ref]: https://opensource.org/licenses/MIT
673
+ [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg
674
+ [📄license-compat]: https://dev.to/galtzo/how-to-check-license-compatibility-41h0
675
+ [📄license-compat-img]: https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache
676
+ [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
677
+ [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
678
+ [🚎yard-current]: http://rubydoc.info/gems/oauth-tty
679
+ [🚎yard-head]: https://oauth-tty.galtzo.com
680
+ [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
681
+ [💎SHA_checksums]: https://gitlab.com/ruby-oauth/oauth-tty/-/tree/main/checksums
682
+ [💎rlts]: https://github.com/rubocop-lts/rubocop-lts
683
+ [💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
684
+ [💎appraisal2]: https://github.com/appraisal-rb/appraisal2
685
+ [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
686
+ [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/