/ README.adoc
README.adoc
  1  // SPDX-License-Identifier: AGPL-3.0-or-later
  2  = bitfuckit
  3  :toc: macro
  4  :toclevels: 3
  5  :icons: font
  6  :source-highlighter: rouge
  7  
  8  *Fire-and-Fuck-GET (and more)* with Bitbucket.
  9  
 10  Bitbucket CLI tool written in Ada. They didn't make it...so I did!
 11  
 12  Bitbucket's answer to GitHub's `gh`, GitLab's `glab`, or Codeberg's `tea`.
 13  
 14  image:https://img.shields.io/badge/language-Ada-blue[Ada]
 15  image:https://img.shields.io/badge/SPARK-verified-green[SPARK]
 16  image:https://img.shields.io/badge/GraphQL-API-e10098[GraphQL]
 17  image:https://img.shields.io/badge/license-AGPL--3.0--or--later-blue[License]
 18  
 19  toc::[]
 20  
 21  == Overview
 22  
 23  `bitfuckit` fills the gap Atlassian left: a proper command-line interface for Bitbucket.
 24  While GitHub has `gh`, GitLab has `glab`, and Codeberg has `tea`, Bitbucket users have been left without an official CLI tool.
 25  
 26  This project provides:
 27  
 28  * Full Bitbucket repository management from the terminal
 29  * Ada/SPARK implementation for reliability and correctness
 30  * Interactive TUI mode with vim-style navigation
 31  * **GraphQL API server** - everything the CLI can do, exposed as GraphQL
 32  * Integration with forge-mirror for multi-forge workflows
 33  
 34  == Features
 35  
 36  === Authentication
 37  * `auth login` - Authenticate with Bitbucket app password
 38  * `auth status` - Show authentication status
 39  
 40  === Repository Operations
 41  * `repo create` - Create a new repository (public or private)
 42  * `repo list` - List all repositories in workspace
 43  * `repo delete` - Delete a repository (with confirmation)
 44  * `repo exists` - Check if repository exists
 45  
 46  === Mirroring
 47  * `mirror` - Mirror a repository from GitHub to Bitbucket
 48  
 49  === Interactive TUI
 50  * Launch with no arguments or `bitfuckit tui`
 51  * Vim-style navigation (j/k or arrows)
 52  * Color-coded interface with box drawing
 53  
 54  == Installation
 55  
 56  === Prerequisites
 57  
 58  [cols="1,3"]
 59  |===
 60  |Component |Installation
 61  
 62  |GNAT (Ada compiler)
 63  |`sudo dnf install gcc-gnat` (Fedora) +
 64  `sudo apt install gnat` (Debian/Ubuntu)
 65  
 66  |GPRbuild
 67  |`sudo dnf install gprbuild` (Fedora) +
 68  `sudo apt install gprbuild` (Debian/Ubuntu)
 69  
 70  |curl
 71  |Usually pre-installed
 72  |===
 73  
 74  === Build from Source
 75  
 76  [source,bash]
 77  ----
 78  git clone https://github.com/hyperpolymath/bitfuckit.git
 79  cd bitfuckit
 80  gprbuild -P bitfuckit.gpr
 81  ----
 82  
 83  The binary will be in `bin/bitfuckit`.
 84  
 85  === Install
 86  
 87  [source,bash]
 88  ----
 89  # User install
 90  cp bin/bitfuckit ~/.local/bin/
 91  
 92  # System install
 93  sudo cp bin/bitfuckit /usr/local/bin/
 94  ----
 95  
 96  === Packages
 97  
 98  [cols="1,2,1"]
 99  |===
100  |Format |Command |Status
101  
102  |Fedora/RHEL
103  |`sudo dnf install bitfuckit`
104  |Planned
105  
106  |Debian/Ubuntu
107  |`sudo apt install bitfuckit`
108  |Planned
109  
110  |Arch
111  |`yay -S bitfuckit`
112  |Planned
113  
114  |Nix
115  |`nix-env -iA nixpkgs.bitfuckit`
116  |Planned
117  
118  |Homebrew
119  |`brew install bitfuckit`
120  |Planned
121  |===
122  
123  == Usage
124  
125  === Authentication
126  
127  . Get an app password from https://bitbucket.org/account/settings/app-passwords/
128  . Required permissions:
129  ** `repository:read`
130  ** `repository:write`
131  ** `repository:delete`
132  . Authenticate:
133  
134  [source,bash]
135  ----
136  bitfuckit auth login
137  # Enter username, app password, and workspace
138  ----
139  
140  === Repository Operations
141  
142  [source,bash]
143  ----
144  # Create repositories
145  bitfuckit repo create my-new-repo
146  bitfuckit repo create my-private-repo --private
147  bitfuckit repo create my-repo --description "My awesome project"
148  
149  # List repositories
150  bitfuckit repo list
151  
152  # Check if repository exists
153  bitfuckit repo exists my-repo
154  
155  # Delete repository (requires confirmation)
156  bitfuckit repo delete my-repo
157  ----
158  
159  === Mirroring from GitHub
160  
161  [source,bash]
162  ----
163  # From within a git repository
164  cd my-github-repo
165  bitfuckit mirror my-repo
166  # Creates repo on Bitbucket if needed, pushes all branches
167  ----
168  
169  === Interactive TUI
170  
171  [source,bash]
172  ----
173  # Launch TUI
174  bitfuckit
175  # or
176  bitfuckit tui
177  ----
178  
179  TUI Controls:
180  
181  * `j` / `↓` - Move down
182  * `k` / `↑` - Move up
183  * `Enter` - Select
184  * `q` / `Esc` - Quit
185  * Single-letter shortcuts (shown in brackets)
186  
187  == Configuration
188  
189  Credentials are stored in `~/.config/bitfuckit/config`
190  
191  [source]
192  ----
193  [credentials]
194  username=your-username
195  app_password=your-app-password
196  workspace=your-workspace
197  ----
198  
199  == Architecture
200  
201  [source]
202  ----
203  bitfuckit/
204  ├── src/
205  │   ├── bitfuckit.adb          # Main CLI entry point
206  │   ├── config.ads/adb         # Configuration & credential storage
207  │   ├── bitbucket_api.ads/adb  # REST API client
208  │   ├── tui.ads/adb            # Terminal UI (SPARK verified spec)
209  │   └── graphql_server.ads/adb # GraphQL API server
210  ├── graphql/
211  │   └── schema.graphql         # Full GraphQL schema
212  ├── bitfuckit.gpr              # GPRbuild project file
213  └── bin/                       # Build output
214  ----
215  
216  === SPARK Verification
217  
218  The TUI specification (`tui.ads`) uses SPARK Mode for formal verification:
219  
220  [source,ada]
221  ----
222  package TUI
223     with SPARK_Mode => On
224  is
225     -- Formally verified interface
226  end TUI;
227  ----
228  
229  == GraphQL API
230  
231  *Fire-and-Fuck-GET (and more)* - everything the CLI can do, the GraphQL API can do too.
232  
233  === Starting the GraphQL Server
234  
235  [source,bash]
236  ----
237  # Start GraphQL server on default port 4000
238  bitfuckit graphql serve
239  
240  # Custom port
241  bitfuckit graphql serve --port 8080
242  
243  # With playground enabled
244  bitfuckit graphql serve --playground
245  ----
246  
247  === Example Queries
248  
249  [source,graphql]
250  ----
251  # List repositories
252  query {
253    repositories {
254      nodes {
255        slug
256        name
257        isPrivate
258        links { html }
259      }
260    }
261  }
262  
263  # Create a repository
264  mutation {
265    createRepository(input: {
266      name: "my-new-repo"
267      isPrivate: true
268      description: "Created via GraphQL"
269    }) {
270      success
271      repository {
272        slug
273        links { html }
274      }
275    }
276  }
277  
278  # Mirror from GitHub
279  mutation {
280    mirror(input: {
281      source: "https://github.com/user/repo"
282      targetName: "repo-mirror"
283      allBranches: true
284    }) {
285      success
286      branchesPushed
287    }
288  }
289  ----
290  
291  === CLI ↔ GraphQL Parity
292  
293  Every CLI command has a GraphQL equivalent:
294  
295  [cols="1,2"]
296  |===
297  |CLI Command |GraphQL Operation
298  
299  |`auth login`
300  |`mutation { login(...) }`
301  
302  |`auth status`
303  |`query { authStatus }`
304  
305  |`repo create`
306  |`mutation { createRepository(...) }`
307  
308  |`repo list`
309  |`query { repositories }`
310  
311  |`repo delete`
312  |`mutation { deleteRepository(...) }`
313  
314  |`repo exists`
315  |`query { repositoryExists(...) }`
316  
317  |`mirror`
318  |`mutation { mirror(...) }`
319  |===
320  
321  The full schema is in `graphql/schema.graphql`.
322  
323  == Integration with forge-mirror
324  
325  `bitfuckit` works seamlessly with the `forge-mirror` script for multi-forge workflows:
326  
327  [source,bash]
328  ----
329  # Check status of all forges
330  forge-mirror status
331  
332  # Push to all forges including Bitbucket
333  forge-mirror push my-repo --forges github,gitlab,bitbucket,codeberg,radicle
334  ----
335  
336  == API Reference
337  
338  === Bitbucket API v2.0
339  
340  `bitfuckit` uses the Bitbucket REST API v2.0:
341  
342  * Base URL: `https://api.bitbucket.org/2.0`
343  * Authentication: Basic Auth with app password
344  * Endpoints:
345  ** `GET /repositories/{workspace}` - List repos
346  ** `POST /repositories/{workspace}/{repo}` - Create repo
347  ** `DELETE /repositories/{workspace}/{repo}` - Delete repo
348  ** `GET /repositories/{workspace}/{repo}` - Get repo details
349  
350  == Roadmap
351  
352  === v0.1.0 (Current)
353  * [x] Authentication (login/status)
354  * [x] Repository CRUD operations
355  * [x] GitHub mirror
356  * [x] Interactive TUI
357  
358  === v0.2.0 (Planned)
359  * [ ] Pull request management
360  * [ ] Issue tracking
361  * [ ] Pipeline status
362  * [ ] Webhook management
363  
364  === v0.3.0 (Planned)
365  * [ ] Team management
366  * [ ] Branch permissions
367  * [ ] Deploy keys
368  * [ ] SSH key management
369  
370  == Contributing
371  
372  Contributions welcome! Please:
373  
374  . Fork the repository
375  . Create a feature branch
376  . Ensure code compiles with GNAT
377  . Submit a pull request
378  
379  == License
380  
381  SPDX-License-Identifier: AGPL-3.0-or-later
382  
383  Copyright (C) 2025 hyperpolymath
384  
385  This program is free software: you can redistribute it and/or modify
386  it under the terms of the GNU Affero General Public License as published
387  by the Free Software Foundation, either version 3 of the License, or
388  (at your option) any later version.
389  
390  == See Also
391  
392  * https://bitbucket.org/account/settings/app-passwords/[Bitbucket App Passwords]
393  * https://developer.atlassian.com/cloud/bitbucket/rest/intro/[Bitbucket REST API]
394  * https://github.com/hyperpolymath/forge-mirror[forge-mirror] - Universal git forge mirror script