forgemap 0.1.0-dev.23-9e4d2ae β†’ 0.1.0-dev.26-b896caf

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- # 🧰 forgemap
3
+ # πŸ—ΊοΈ forgemap
4
4
 
5
5
  **One consistent local layout for every repo you clone β€” across every forge**
6
6
 
@@ -29,9 +29,11 @@ That's it. Every repo lands at a predictable `<root>/<forge.dir>/<owner>/<repo>`
29
29
  - **πŸ” Fuzzy search** β€” `forgemap search <term>` finds local repos by owner or repo name (powered by [Fuse.js](https://www.fusejs.io/)).
30
30
  - **πŸ€– Forge-aware** β€” `type: 'github'` shells out to `gh`; `type: 'git'` uses plain `git clone` with no extra dependencies.
31
31
  - **πŸ” Mass sync + status** β€” `forgemap sync` fetches every clone in parallel, `forgemap status` shows branch / dirty / ahead / behind per repo.
32
+ - **πŸ“₯ Import existing trees** β€” `forgemap import <path>` adopts a folder already laid out as `<server>/<owner>/<repo>`, reconciles each repo against its git remote (spotting moved or deleted remotes), and derives a config.
33
+ - **🧹 Safe cleanup** β€” `forgemap cleanup` deletes long-idle local clones, but only the ones that are clean, fully pushed, and still exist on their remote β€” so nothing unbacked-up is ever lost.
32
34
  - **πŸ›‘οΈ Preflight validate** β€” `forgemap validate` checks the config schema and required CLIs before you discover a problem mid-clone.
33
- - **🧰 Typed config** β€” `forgemap.config.ts` with `defineForgeMapConfig()` and walk-up discovery.
34
- - **πŸš€ Shell-friendly** β€” `forgemap cd <slug>` (via `shell-init`) actually changes directory.
35
+ - **🧰 Typed config** β€” `forgemap.config.ts` with `defineForgeMapConfig()`, parent walk-up discovery, and a global fallback.
36
+ - **πŸš€ Shell-friendly** β€” `forgemap shell-init --install` wires up real `forgemap cd <slug>` **and** tab-completion in one step.
35
37
 
36
38
  ## πŸ“¦ Installation
37
39
 
@@ -58,9 +60,10 @@ Hacking on forgemap itself? See [CONTRIBUTING.md β†’ Trying the CLI locally](CON
58
60
  cd ~/projects
59
61
  forgemap config init
60
62
 
61
- # 2. Wire up the shell integration once β€” adds real `forgemap cd`.
62
- eval "$(forgemap shell-init)" # zsh/bash, add to ~/.zshrc to persist
63
- # fish: forgemap shell-init fish | source
63
+ # 2. Wire up the shell integration once β€” real `forgemap cd` + tab-completion.
64
+ forgemap shell-init --install # appends loaders to ~/.zshrc (or bashrc/fish)
65
+ source ~/.zshrc # re-source once, then it's automatic
66
+ # Prefer manual? eval "$(forgemap shell-init)" Β· fish: forgemap shell-init fish | source
64
67
 
65
68
  # 3. Clone β€” any slug form works.
66
69
  forgemap clone kirchDev/laravel-pbac
@@ -109,6 +112,33 @@ forgemap status # tree: branch / dirty / ahead↑ / behind
109
112
  forgemap status --format json # structured for jq + scripts
110
113
  ```
111
114
 
115
+ All tree output (`status`, `search`, `import`) groups as `forge β†’ owner β†’ repo`. Network operations (`sync`, `import`, `cleanup`) run with a hard timeout and non-interactive SSH, so an unreachable host can never wedge a run.
116
+
117
+ ### Adopt an existing layout β€” `import`
118
+
119
+ Already have a folder full of repos laid out as `<server>/<owner>/<repo>`? Adopt it without re-cloning:
120
+
121
+ ```bash
122
+ forgemap import ~/projects # reconcile + derive/write forgemap.config.ts
123
+ forgemap import ~/projects --no-remote-check # offline: folder-vs-origin only (instant)
124
+ forgemap import ~/projects --fix # move folders / fix origin URLs to match the remote
125
+ forgemap import ~/projects --no-write-config # only report, don't touch the config
126
+ forgemap import ~/projects --format json
127
+ ```
128
+
129
+ For each repo `import` compares the folder's `<owner>/<repo>` against the git `origin`, checks whether the remote still exists or was moved/renamed (GitHub via a batched `gh` GraphQL query, other forges via `git ls-remote`), and derives `root` + one forge per server directory. Read-only by default β€” `--fix` is the only thing that touches the filesystem.
130
+
131
+ ### Reclaim disk β€” `cleanup`
132
+
133
+ ```bash
134
+ forgemap cleanup # list deletable clones, then type "yes" to confirm
135
+ forgemap cleanup --dry-run # show candidates + why every other idle repo is kept
136
+ forgemap cleanup --days 540 # idle threshold in days (default 365)
137
+ forgemap cleanup --include-dirty --include-unpushed # also delete repos with local-only work (lost!)
138
+ ```
139
+
140
+ A repo is only deleted when it is idle for `--days`+ days (by last **local** commit), has a clean working tree, has nothing unpushed, **and** its remote still exists β€” so everything removed is provably backed up. Repos without a remote (or with a gone/unreachable one) are never touched; empty owner directories left behind are pruned automatically. Deletion needs an explicit typed `yes` (or `--yes`).
141
+
112
142
  ### Preflight your config
113
143
 
114
144
  ```bash
@@ -118,6 +148,24 @@ forgemap validate --json | jq # machine-readable for pre-commit hooks
118
148
 
119
149
  Validates the schema, required CLI tools (`git` always, `gh` when a `type: 'github'` forge is configured), `gh auth status`, and that the configured root exists.
120
150
 
151
+ ### Shell integration & completion
152
+
153
+ ```bash
154
+ forgemap shell-init --install # cd wrapper + completion β†’ your rc file (idempotent)
155
+ forgemap completion --install # completion only, if you don't want the cd wrapper
156
+ forgemap shell-init # print the wrapper (manual: eval "$(…)")
157
+ forgemap completion bash # print the completion script for bash/zsh/fish
158
+ ```
159
+
160
+ `--install` appends a marker-guarded block to the right rc file (`~/.zshrc`, `~/.bashrc`, or `~/.config/fish/config.fish`) β€” re-source it once and you're done. Tab-completion suggests every subcommand, and slugs for the commands that take one (`cd`, `clone`, `open`, …).
161
+
162
+ ### Inspect the config
163
+
164
+ ```bash
165
+ forgemap config init # write a starter forgemap.config.ts
166
+ forgemap config show # print the resolved config + which file it came from
167
+ ```
168
+
121
169
  ## βš™οΈ Configuration
122
170
 
123
171
  `forgemap config init` writes a `forgemap.config.ts` like this:
@@ -153,7 +201,10 @@ export default defineForgeMapConfig({
153
201
  | `forges.<name>.dir` | Subdirectory under `root` where this forge's clones live. |
154
202
  | `forges.<name>.protocol` | `git`-type only. `'ssh'` (default) or `'https'`. Override per call with `--ssh` / `--https`. |
155
203
 
156
- The config file is discovered by walking up from your current directory. Override with `--config <path>` or the `FORGEMAP_CONFIG` env var.
204
+ The config file is discovered by walking **up** from your current directory (so `forgemap cd` works from inside any clone, not just the root), then falling back to a global `$XDG_CONFIG_HOME/forgemap/forgemap.config.*` (i.e. `~/.config/forgemap/`) so commands work from anywhere. Override with `--config <path>` or the `FORGEMAP_CONFIG` env var.
205
+
206
+ > [!TIP]
207
+ > Already have a directory full of repos? Skip writing this by hand β€” `forgemap import <path>` derives `root` + `forges` from the existing layout.
157
208
 
158
209
  ## πŸ—‚οΈ Layout
159
210