microgit-cli 0.0.0-stage → 0.1.1

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.
Files changed (42) hide show
  1. package/README.md +257 -2
  2. package/package.json +26 -4
  3. package/src/api/index.js +111 -0
  4. package/src/api/index.js.map +1 -0
  5. package/src/cli/index.js +32 -0
  6. package/src/cli/index.js.map +1 -0
  7. package/src/cli/repl.js +312 -0
  8. package/src/cli/repl.js.map +1 -0
  9. package/src/commands/auth.js +305 -0
  10. package/src/commands/auth.js.map +1 -0
  11. package/src/commands/config.js +91 -0
  12. package/src/commands/config.js.map +1 -0
  13. package/src/commands/git.js +159 -0
  14. package/src/commands/git.js.map +1 -0
  15. package/src/commands/registry.js +139 -0
  16. package/src/commands/registry.js.map +1 -0
  17. package/src/commands/repos.js +256 -0
  18. package/src/commands/repos.js.map +1 -0
  19. package/src/config/index.js +124 -0
  20. package/src/config/index.js.map +1 -0
  21. package/src/config/settings.js +34 -0
  22. package/src/config/settings.js.map +1 -0
  23. package/src/error/index.js +14 -0
  24. package/src/error/index.js.map +1 -0
  25. package/src/git/index.js +163 -0
  26. package/src/git/index.js.map +1 -0
  27. package/src/help/index.js +52 -0
  28. package/src/help/index.js.map +1 -0
  29. package/src/index.js +9 -0
  30. package/src/index.js.map +1 -0
  31. package/src/theme/banner.js +44 -0
  32. package/src/theme/banner.js.map +1 -0
  33. package/src/theme/index.js +5 -0
  34. package/src/theme/index.js.map +1 -0
  35. package/src/theme/logo.js +36 -0
  36. package/src/theme/logo.js.map +1 -0
  37. package/src/theme/palette.js +32 -0
  38. package/src/theme/palette.js.map +1 -0
  39. package/src/ui/index.js +100 -0
  40. package/src/ui/index.js.map +1 -0
  41. package/src/util/index.js +30 -0
  42. package/src/util/index.js.map +1 -0
package/README.md CHANGED
@@ -1,3 +1,258 @@
1
- # Temporary Holding Version
1
+ # microgit-cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `microgit` — **your own git server — clone, push, host**.
4
+
5
+ A small command line client for the [microgit](npm@microgit) server. It keeps the API
6
+ session in a local config file, creates and deletes repositories, and wraps the
7
+ usual `git` commands so push/pull work with the account credentials.
8
+
9
+ It is a separate TypeScript project with **no runtime dependencies** (Node's
10
+ built-in `fetch`, `readline` and `git` are enough).
11
+
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install -g microgit-cli
17
+ ```
18
+
19
+ Without a global install, run the built entry point directly:
20
+
21
+ ```bash
22
+ node src/index.js --help
23
+ ```
24
+
25
+ ## Interactive shell
26
+
27
+ Run `microgit` with no arguments (or `microgit shell`) to open the shell:
28
+
29
+ ```
30
+ ● ━━━ ●
31
+ ┣━━━ ● microgit-cli • gitserver v0.1.0
32
+ ┗━━━ ● your own git server — clone, push, host
33
+
34
+ # server http://{HOST_NAME}:{PORT}
35
+ # account alice · 7d left
36
+
37
+ ✓ ready · type help to list the commands
38
+ # one-shot microgit --help
39
+
40
+ alice@microgit:~/repos$ new app
41
+ ```
42
+
43
+ Starting the shell clears the screen and the scrollback first, so the banner is
44
+ the only thing on the page. The prompt shows the signed-in account and the
45
+ current folder. Commands are the same words as the one-shot CLI, and the shell
46
+ adds:
47
+
48
+ | Keys / command | What it does |
49
+ | --- | --- |
50
+ | `↑` / `↓` | History, kept in `~/.microgit/history` |
51
+ | `Tab` | Complete command names, `config` actions and `--options` |
52
+ | `Ctrl+C` | Clear the line; on an empty line it leaves the shell |
53
+ | `Ctrl+D` | Leave the shell |
54
+ | `help` | The command list |
55
+ | `clear` | Clear the screen and redraw the banner |
56
+ | `exit` / `quit` | Leave the shell |
57
+
58
+ Errors never close the shell. A command that asks something (`login`,
59
+ `commit`, `delete`, `new`) asks inside the same prompt.
60
+
61
+ ## Quick start
62
+
63
+ ```bash
64
+ # 1. Point the CLI at the server and sign in. Use the host and port the
65
+ # server actually listens on, or its domain behind a reverse proxy.
66
+ microgit login --url http://{HOST_NAME}:{PORT}
67
+
68
+ # 2. Create a repository and a local checkout with a first commit,
69
+ # then push it.
70
+ microgit new app --init
71
+
72
+ # 3. Work as usual; commit also pushes.
73
+ cd app
74
+ echo "hello" > hello.txt
75
+ microgit commit -m "Add hello.txt"
76
+
77
+ # 4. Check the session or list repositories.
78
+ microgit whoami
79
+ microgit list
80
+ ```
81
+
82
+ Signing in again reuses a valid stored session, so the username and password are
83
+ only asked for once. Add `--force` to sign in as another account.
84
+
85
+ ## Commands
86
+
87
+ | Command | What it does |
88
+ | --- | --- |
89
+ | `microgit login` | Sign in, store the API token and optionally the git password |
90
+ | `microgit register` | Create an account (when the server allows registration) and sign in |
91
+ | `microgit logout` | Revoke the server session, remove the local token and password |
92
+ | `microgit whoami` | Show the signed-in account, server and expiry |
93
+ | `microgit new <name>` | Create a repository; asks public/private, plus `--private`, `--public`, `--clone`, `--init` |
94
+ | `microgit list` | List repositories; `--owner`, `--name`, `--public`, `--private` |
95
+ | `microgit delete <name\|owner/name>` | Delete a repository; asks before doing it |
96
+ | `microgit clone <name\|owner/name> [dir]` | Clone using the clone URL from the server |
97
+ | `microgit init [dir]` | Local only: project folder, `git init` and an empty `README.md` |
98
+ | `microgit status` | `git status --short --branch` |
99
+ | `microgit commit -m "message"` | `git add -A`, commit, then push |
100
+ | `microgit push [git args]` | Push with stored credentials |
101
+ | `microgit pull [git args]` | Pull with stored credentials |
102
+ | `microgit config` | Show the config file, server and session |
103
+
104
+ Every command accepts `-h` / `--help`. Commands that print API data also accept
105
+ `--json` where it makes sense (`whoami`, `list`, `new`, `delete`, `clone`,
106
+ `login`, `register`, `logout`, `config`).
107
+
108
+ ### Creating repositories
109
+
110
+ Without `--private` or `--public` the CLI asks for the visibility, and Enter
111
+ creates a public repository:
112
+
113
+ ```bash
114
+ microgit new app # asks: public or private
115
+ microgit new secret --private
116
+ microgit new app --public
117
+ microgit new app --clone # create it and clone the empty repository
118
+ microgit new app --init # create it, README, first commit and push
119
+ microgit new app --init --dir ./projects/app
120
+ ```
121
+
122
+ The request sent to the server is `{"name":"app","private":false}` (or `true`).
123
+
124
+ `new` prints the server's clone URL. Existing repositories are not an error:
125
+ the API returns `created: false` and the CLI says it already exists.
126
+
127
+ ### Starting a local repository
128
+
129
+ `microgit init` is local only — it does not talk to the server:
130
+
131
+ ```bash
132
+ microgit init app # creates ./app, .git on main, empty README.md
133
+ microgit init # initialise the current folder
134
+ microgit init --dir ./projects/app
135
+ ```
136
+
137
+ It refuses to run inside an existing repository, and reuses the saved account
138
+ name for `user.name` / `user.email` when git has none configured.
139
+
140
+ ### Deleting repositories
141
+
142
+ ```bash
143
+ microgit delete app # asks for confirmation
144
+ microgit delete app --yes # non-interactive
145
+ microgit delete bob/app --yes # administrators can delete for another owner
146
+ ```
147
+
148
+ ### Listing repositories
149
+
150
+ ```bash
151
+ microgit list
152
+ microgit list --owner alice
153
+ microgit list --private --limit 20
154
+ microgit list --public --page 2 --json
155
+ ```
156
+
157
+ ## Authentication and git credentials
158
+
159
+ The JSON API uses the session token returned by `login`. The CLI sends it as
160
+ `Authorization: Bearer <token>` and stores it in the config file. Git uses HTTP
161
+ Basic with the **account username and password**, not the API token.
162
+
163
+ For that reason `login` only stores the token by default. Add
164
+ `--save-password` to also store the password, which makes `push`, `pull`,
165
+ `clone` of a private repository and `new --init` work without another prompt:
166
+
167
+ ```bash
168
+ microgit login --save-password
169
+ ```
170
+
171
+ The password is stored in plain text in the config file. The file is created
172
+ with mode `600` on Unix; on Windows the user profile permissions apply. If you
173
+ do not want to store it, leave `--save-password` off and let `git` ask when it
174
+ needs credentials, or set `MICROGIT_PASSWORD` for one command:
175
+
176
+ ```bash
177
+ MICROGIT_PASSWORD='alicepass1' microgit push
178
+ ```
179
+
180
+ Logging in again keeps a saved password when the username is unchanged; pass
181
+ `--forget-password` to remove it.
182
+
183
+ The CLI passes credentials to git as an `http.extraHeader`, so they are **not**
184
+ written into `.git/config` and are not part of the clone URL.
185
+
186
+ The server's message of the day, when it publishes one, is printed after
187
+ `login`, `register` and `whoami`.
188
+
189
+ ## Config file
190
+
191
+ Default location: `~/.microgit/config.json`. Use `MICROGIT_CONFIG` to point at a
192
+ different file, for example one per server:
193
+
194
+ ```bash
195
+ MICROGIT_CONFIG=~/.microgit/work.json microgit login --url https://git.example.com
196
+ ```
197
+
198
+ The shell keeps its history next to it, in `~/.microgit/history`.
199
+
200
+ Show it with:
201
+
202
+ ```bash
203
+ microgit config
204
+ microgit config set url https://git.example.com
205
+ microgit config set username alice
206
+ microgit config unset password
207
+ microgit config clear
208
+ ```
209
+
210
+ Environment variables override the file for one command:
211
+
212
+ | Variable | Meaning |
213
+ | --- | --- |
214
+ | `MICROGIT_URL` | Server URL |
215
+ | `MICROGIT_TOKEN` | API token, instead of the stored one |
216
+ | `MICROGIT_USERNAME` | Account name, also used for git |
217
+ | `MICROGIT_PASSWORD` | Git password, also used for git |
218
+ | `MICROGIT_CONFIG` | Config file path |
219
+ | `NO_COLOR` | Disable colours |
220
+
221
+ ## Renaming the CLI
222
+
223
+ Package name, command name, banner, tagline, label, version, environment prefix
224
+ and config folder all live in [`src/settings.ts`](src/settings.ts). Change them
225
+ there and update `name` / `bin` in `package.json` to match.
226
+
227
+ ## Domains
228
+
229
+ The server's `domain` / `publicUrl` setting changes the clone URL it returns.
230
+ `microgit clone` and `microgit new --init` use that URL, so the name must resolve
231
+ from the machine running the CLI. If the public domain is only reachable from
232
+ outside, log in with the internal URL instead; the repository still works, but a
233
+ `domain` configured on the server wins when it builds the clone URL.
234
+
235
+ ## Exit codes
236
+
237
+ - `0` success
238
+ - `1` expected failure (bad input, server error, git failure)
239
+
240
+ Errors are printed once without a stack trace. `--json` output is still the
241
+ server's JSON (or, for `whoami`/`config`, a small object with the same fields).
242
+
243
+ ## Troubleshooting
244
+
245
+ - **`You are not signed in`** — run `microgit login`; the token expires after the
246
+ server's `sessionDays`.
247
+ - **`login` keeps signing in as the old account** — the stored session is still
248
+ valid; pass `--force` or run `microgit logout` first.
249
+ - **`Authentication failed` on push** — `login --save-password`, or set
250
+ `MICROGIT_PASSWORD`; the username/password is your account, not the API token.
251
+ - **`No 'origin' remote`** — use `microgit clone <owner/name>` or add a remote
252
+ with git.
253
+ - **`Directory is not empty`** — `--clone`/`--init` refuse to overwrite files;
254
+ choose another `--dir`.
255
+ - **`Already a git repository`** — `microgit init` skips folders that already
256
+ have `.git`.
257
+ - **Server unreachable** — pass `--url` or set `MICROGIT_URL`; check the server's
258
+ `host`, `port` and reverse proxy.
package/package.json CHANGED
@@ -1,6 +1,28 @@
1
1
  {
2
2
  "name": "microgit-cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Command line client for a self-hosted git server (microgit)",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "microgit": "src/index.js"
9
+ },
10
+ "engines": {
11
+ "node": ">=20"
12
+ },
13
+ "scripts": {
14
+ "start": "node src/index.js"
15
+ },
16
+ "files": [
17
+ "src",
18
+ "README.md"
19
+ ],
20
+ "keywords": [
21
+ "git",
22
+ "git-cli",
23
+ "microgit",
24
+ "self-hosted"
25
+ ],
26
+ "author": "levent INAN",
27
+ "license": "MIT"
28
+ }
@@ -0,0 +1,111 @@
1
+ import { CliError } from '../error/index.js';
2
+ import { BIN } from '../config/settings.js';
3
+ /** A non-2xx response from the server. */
4
+ export class ApiError extends Error {
5
+ status;
6
+ constructor(status, message) {
7
+ super(message);
8
+ this.name = 'ApiError';
9
+ this.status = status;
10
+ }
11
+ }
12
+ /** Minimal typed client for the JSON API; the token goes in a Bearer header. */
13
+ export class ApiClient {
14
+ baseUrl;
15
+ token;
16
+ constructor(baseUrl, token) {
17
+ this.baseUrl = baseUrl;
18
+ this.token = token;
19
+ }
20
+ endpoint(pathname) {
21
+ return `${this.baseUrl}${pathname}`;
22
+ }
23
+ repoPath(owner, name) {
24
+ return `/api/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`;
25
+ }
26
+ async request(method, pathname, body) {
27
+ const headers = { Accept: 'application/json' };
28
+ if (this.token)
29
+ headers.Authorization = `Bearer ${this.token}`;
30
+ if (body !== undefined)
31
+ headers['Content-Type'] = 'application/json';
32
+ let response;
33
+ try {
34
+ response = await fetch(this.endpoint(pathname), {
35
+ method,
36
+ headers,
37
+ body: body === undefined ? undefined : JSON.stringify(body),
38
+ signal: AbortSignal.timeout(20_000),
39
+ });
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ throw new CliError(`Cannot reach ${this.baseUrl}: ${message}`);
44
+ }
45
+ const text = await response.text();
46
+ let data = null;
47
+ if (text.trim() !== '') {
48
+ try {
49
+ data = JSON.parse(text);
50
+ }
51
+ catch {
52
+ data = text;
53
+ }
54
+ }
55
+ if (!response.ok) {
56
+ let message = `HTTP ${response.status}`;
57
+ if (data !== null &&
58
+ typeof data === 'object' &&
59
+ 'error' in data &&
60
+ typeof data.error === 'string') {
61
+ message = data.error;
62
+ }
63
+ if (response.status === 401 && this.token) {
64
+ message += `\nRun \`${BIN} login\` to start a new session.`;
65
+ }
66
+ throw new ApiError(response.status, message);
67
+ }
68
+ if (data === null || typeof data !== 'object') {
69
+ throw new CliError(`${this.endpoint(pathname)} did not return JSON. Is ${this.baseUrl} a git-server?`);
70
+ }
71
+ return data;
72
+ }
73
+ login(username, password) {
74
+ return this.request('POST', '/api/login', { username, password });
75
+ }
76
+ register(username, password) {
77
+ return this.request('POST', '/api/register', { username, password });
78
+ }
79
+ logout() {
80
+ return this.request('POST', '/api/logout');
81
+ }
82
+ me() {
83
+ return this.request('GET', '/api/me');
84
+ }
85
+ listRepos(options = {}) {
86
+ const query = new URLSearchParams();
87
+ if (options.owner)
88
+ query.set('owner', options.owner);
89
+ if (options.name)
90
+ query.set('name', options.name);
91
+ if (options.private !== undefined && options.private !== null) {
92
+ query.set('private', options.private ? 'true' : 'false');
93
+ }
94
+ if (options.page !== undefined)
95
+ query.set('page', String(options.page));
96
+ if (options.limit !== undefined)
97
+ query.set('limit', String(options.limit));
98
+ const suffix = query.toString() === '' ? '' : `?${query.toString()}`;
99
+ return this.request('GET', `/api/repos${suffix}`);
100
+ }
101
+ repo(owner, name) {
102
+ return this.request('GET', this.repoPath(owner, name));
103
+ }
104
+ newRepo(name, isPrivate = false) {
105
+ return this.request('POST', '/api/new', { name, private: isPrivate });
106
+ }
107
+ deleteRepo(owner, name) {
108
+ return this.request('DELETE', this.repoPath(owner, name));
109
+ }
110
+ }
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { CliError } from '../error/index.js';
2
+ import { printHelp, printVersion } from '../help/index.js';
3
+ import { dispatch } from '../commands/registry.js';
4
+ import { startShell } from './repl.js';
5
+ /** Only start the shell when a person is actually looking at the terminal. */
6
+ export function isInteractive() {
7
+ return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
8
+ }
9
+ export async function main(argv) {
10
+ const [command, ...rest] = argv;
11
+ if (command === undefined) {
12
+ // Bare `microgit` opens the shell; piped runs still get the help output.
13
+ if (isInteractive())
14
+ return startShell();
15
+ printHelp();
16
+ return;
17
+ }
18
+ if (command === 'help' || command === '--help' || command === '-h' || command === '?') {
19
+ return printHelp();
20
+ }
21
+ if (command === '--version' || command === '-v' || command === 'version') {
22
+ return printVersion();
23
+ }
24
+ if (command === 'shell' || command === 'repl') {
25
+ return startShell();
26
+ }
27
+ if (command === '--') {
28
+ throw new CliError('Expected a command after `--`. Type `help` to list the commands.');
29
+ }
30
+ await dispatch([command, ...rest]);
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,8EAA8E;AAC9E,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc;IACvC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAEhC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,yEAAyE;QACzE,IAAI,aAAa,EAAE;YAAE,OAAO,UAAU,EAAE,CAAC;QACzC,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;QACtF,OAAO,SAAS,EAAE,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACzE,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC9C,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,QAAQ,CAAC,kEAAkE,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,QAAQ,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC"}