Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
# @suaveplan/crypto-bin - Suaveplan crypto bins: suaveplan-hash-password (Argon2id / blake2b password hash + verify CLI). Lives in its own package so the universal @suaveplan/crypto does not pull in @suaveplan/cli runtime deps.
## Summary
Suaveplan password-hashing CLI. Ships the `suaveplan-hash-password`
binary — Argon2id (default) and BLAKE2b password hashing + verification
with PHC/MCF-formatted output strings, distinct exit codes per failure
class, and an env-injected output adapter so the core is testable
without subprocess spawn.
This package lives separately from `@suaveplan/crypto` so the
universal crypto façade does not pull CLI runtime deps into
browser/server consumers that just want primitives.
<!-- begin:auto-docs -->
## Documentation tree
- [bin](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ - [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_
## Quickstart
```bash
# Hash a password (Argon2id by default)
$ suaveplan-hash-password --password "correct horse battery staple"
$argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>
# Verify (exit 0 = match, 1 = mismatch)
$ suaveplan-hash-password --password "correct horse battery staple" \
--verify '$argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>'
$ echo $?
0
```
## Algorithms
- **`--algo argon2id`** (default) — OWASP 2023-recommended password hash.
Output prefix `$argon2id$v=19$...`.
- **`--algo blake2b`** — opt-in alternative for environments that need
it. Output prefix `$blake2b$v=1$...`. Cost factor is configurable via
`--cost-factor <n>` (1–31).
The verify mode auto-detects the algorithm from the stored hash's prefix,
so callers do not have to track which algorithm was used at hash time.
## Exit codes
| Code | Meaning |
|------|------------------------------------------------------------|
| 0 | Success / verify matched |
| 1 | Verify mismatch (wrong password) |
| 2 | Bad arguments (missing/malformed flag value) |
| 3 | Unknown algorithm (unrecognised `--algo` or stored prefix) |
| 4 | Verify failed (stored hash is corrupt or unparseable) |
The `0` / `1` split matches the de-facto contract for shell pipelines —
`if suaveplan-hash-password --password ... --verify ...; then ...; fi`
works as expected, with `3+` reserved for operator errors so callers can
distinguish "wrong password" from "stored data is broken".
## Programmatic use
```ts
import { main } from "@suaveplan/crypto-bin";
const out: string[] = [];
const err: string[] = [];
const code = main(
["--password", "pw", "--algo", "blake2b", "--cost-factor", "10"],
{
write: (s) => out.push(s),
writeError: (s) => err.push(s),
},
);
if (code === 0) {
storeHash(out.join("").trim());
}
```
The `main()` function never throws — every error path is captured and
surfaced via `env.writeError(...)` and a non-zero return value. See
`src/hash-password/hash-password.md` for the full contract.
## Public surface
- `main` — testable CLI core.
- `parseArgs` — pure argv parser (throws `HashPasswordCliError`).
- `detectAlgo` — algorithm sniffer for stored hashes.
- `HashPasswordCliEnv` — output adapter interface.
- `HashPasswordCliError` — error class wrapping the stable code registry.
- `HASH_PASSWORD_CLI_CODES` — `BAD_ARGS` / `UNKNOWN_ALGO` /
`VERIFY_FAILED`.
## Dependencies
- `@suaveplan/crypto-hash` — Argon2id + BLAKE2b primitives.
- `@suaveplan/error` — `SuaveplanError` base + stable code registry.
- `@suaveplan/types` — shared cross-package contracts.
No dependency on `@suaveplan/cli` — argv parsing is hand-rolled (~40
lines) so the bin stays small.