Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .beads/dolt-fsqlite-ns-gate
Empty file.
Binary file added .beads/dolt-fsqlite-ns-use
Binary file not shown.
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source_env_if_exists .envrc.local

use flake
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ amp
.omo
.beads/issues.jsonl
.beads/interactions.jsonl
.envrc.local
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Creates `.himitsu.yaml.bak` backup before rewriting
- Auto-fold-on-read: secrets with the legacy `environment` proto field set will have that value automatically folded into `tags` on decode (non-mutating — the on-disk file is not modified by reads alone).
- TUI path expansion now accepts the `ctrl+x ctrl+=` leader chord
- `himitsu set <path> [value]` (alias `add`) can now take the secret's value from a local file with `--file <path>`; exactly one of the literal `<value>` argument or `--file` is accepted. The file is read as raw bytes with no MIME or filename metadata recorded -- binary content and trailing whitespace roundtrip byte-for-byte via `himitsu read` / `himitsu get`.
- New public pure reference-grammar parser `reference::ReferenceExpr` (`parse(&str)`): recognizes `tag:<name>`, `path:<path>`, bare slash paths, unresolved bare names, trailing-slash path prefixes (`personal/`, equivalent to `personal/*`), provider-qualified refs (`github:acme/secrets#path`), and explicit `store:provider:org/repo` refs. Rejects malformed input via the existing validators, including org/repo traversal and extra slug segments in qualified/store refs (`config::validate_remote_slug`). Parser-only (hm-zn6): no IO, no store lookup, bare-name tag-vs-path ambiguity is retained for the future resolver, and `himitsu exec` / `himitsu codegen` behavior is unchanged — nothing consumes the new parser yet.
- New store-local tag-definition storage API `himitsu::remote::tag_store` (hm-cw1, storage-only): `TagDefinition { description, keys }` persisted at `<store>/.himitsu/tags/<name>.yaml` with `create_tag` (no-clobber), `read_tag` (re-validates on read), `update_tag`/`delete_tag` (missing tag is a `TagNotFound` error), and `list_tags` (sorted; empty when the tags directory is missing). Every function takes an explicit caller-supplied store root — no global-store resolution convention. `keys` are reference strings (never secret values), validated with `crypto::tags::validate_tag` for names (plus `.`/`..`/path-escape rejection) and `reference::ReferenceExpr::parse` for entries; writes are atomic (temp-file + rename). Storage only — no resolver, CLI, TUI, or codegen change; nothing consumes the API yet and `himitsu` runtime behavior is unchanged.

### Deprecated
- Proto fields `SecretEntry.environment`, `SecretEnvelope.environment`, `StoreManifest.environments`: marked `[deprecated = true]`. Writing these fields is disabled. A follow-up release will replace them with `reserved`. Rollback to a pre-migration binary is NOT supported once secrets have been re-encrypted by the new binary.
Expand Down
6 changes: 3 additions & 3 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ These are the concepts the codebase uses. When naming modules, prefer these term
- **Store** — a git repo containing encrypted secrets and metadata at `.himitsu/`
- **Remote** — a named store slug (`org/repo`) registered in the user's global config
- **Secret** — one encrypted value stored as `.himitsu/secrets/<path>.yaml`
- **Env Key** — the environment-variable name a Secret takes when injected or generated; a property of the Secret itself (defaulting to its name), never of the group referencing it
- **Recipient** — an age public key that can decrypt secrets in a store
- **Output** — a named group of secrets defined in project config (`codegen:` block)
- **Selector** — a query over secrets: `tag:pci`, `prod/*`, `tag:A+tag:B`
- **Reference** — a string that identifies a secret: path, qualified ref (`github:org/repo/path`), or selector
- **Tag** — a named group of secrets; the only grouping entity (replaces the former Output/env/label concept). A Tag lives in a Store, exactly like a Secret. Its members are the secrets tagged with it plus what the Tag's own references resolve to, counted once. A Tag groups secrets, never other Tags — shared membership is co-tagging. Referenced bare (`web-prod`) or explicitly (`tag:web-prod`).
- **Reference** — a string that identifies secrets. Bare: a path (`prod/api-key`), a path prefix (`prod/`), or a tag name (`web-prod`; a path beats a tag on name collision). Forced: `tag:web-prod`, `path:prod/api-key`, `regex:<pattern>` (anchored match over paths), or a qualified cross-store ref (`github:org/repo#path`).
- **Identity** — an age x25519 private key, loaded from disk or macOS Keychain

## Architecture Terms (from 2026-06-08 review)
Expand Down
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,20 +378,29 @@ himitsu init --name you/secrets # headless, creates/restores a primary
himitsu init --name org/repo --url <url> # restore from a custom git remote
```

### `himitsu set <path> <value>`
### `himitsu set <path> [value]`

Encrypt and store a secret. Path is slash-delimited (`prod/API_KEY`).
Encrypt and store a secret. Path is slash-delimited (`prod/API_KEY`). The
value comes from the literal argument or from a local file via `--file` --
exactly one of the two must be given. `add` is an alias for `set`.

```bash
himitsu set prod/API_KEY "sk_live_abc123"
himitsu set dev/DB_PASSWORD "devpass" --no-push
himitsu set prod/STRIPE_KEY "sk_live_..." --tag pci --tag stripe
himitsu add prod/TLS_CERT --file certs/server.pem # value from a file
```

With `--file`, binary content and trailing whitespace are encrypted as-is
and roundtrip byte-for-byte. Read the bytes back with
`himitsu read <path>` (raw, no decoration) or `himitsu get <path>`.


Optional flags:

| Flag | Purpose |
|------|---------|
| `--file <path>` | Take the secret's value from the raw bytes of this local file. Exactly one of `<value>` or `--file` must be given. |
| `--description <text>` | Human-readable description, surfaced in `search` and the TUI viewer. |
| `--url <url>` | Associated dashboard URL. |
| `--totp <otpauth-or-base32>` | TOTP secret (URI or raw base32 ≥ 16 chars). |
Expand All @@ -401,10 +410,11 @@ Optional flags:

### `himitsu get <path>`

Decrypt and print a secret for humans.
Decrypt and print a secret for humans. Pass `-` to read the path from stdin:

```bash
himitsu get prod/API_KEY
echo 'prod/API_KEY' | himitsu get -
```

### `himitsu read <path>`
Expand Down Expand Up @@ -862,7 +872,7 @@ The full action list (with defaults) is in
[`rust/src/tui/keymap.rs`](rust/src/tui/keymap.rs):
`quit`, `help`, `command_palette`, `new_secret`, `switch_store`,
`copy_selected`, `copy_ref_selected`, `codegen` (legacy aliases: `outputs`, `envs`),
`collapse_paths`, `expand_paths`, `toggle_autocomplete`, `refine_tag`,
`collapse_paths`, `expand_paths`, `refine_tag`,
`sort_column`, `reveal`, `copy_value`, `copy_ref`, `rekey`, `edit`,
`delete`, `back`, `save_secret`, `next_field`, `prev_field`, `cancel`.

Expand Down
Loading
Loading