Commit Graph
888 Commits
Author SHA1 Message Date
rootiest 0b4ab30b40 test(session): catch --help color regressions against the live theme
Adds two checks to the shared-palette section, extending the existing
colored list with the functions converted in this branch (config-help,
fish-deps, gi, git-clean, mkrep):

- Every listed function's --help must contain the session's own c_head
  and c_cmd escapes -- not just some escape sequence, which the existing
  presence check already covered but which a wrong-role bug (still some
  color, just not the right one) sails through undetected.
- Every escape sequence found in --help output must be one of
  c_reset/c_head/c_cmd/c_flag/c_arg/c_dim. c_warn/c_err/c_ok/c_accent/
  c_sel/c_hi are legitimate elsewhere but never in --help text; reaching
  for one there is always a bug, which is exactly what logs and
  smart_exit did (static c_accent green for the command name).

Verified against the pre-fix smart_exit.fish (58d5cf3~1): both checks
fail on it -- missing c_head on "Options:", and a disallowed \e[32m for
the command name -- confirming this isn't a tautological pass.
2026-09-21 01:49:34 -04:00
rootiest 58d5cf3fae fix(functions): correct palette roles in logs and smart_exit help text
Both had headings (Usage:/Options:/Keys in fzf:) left completely
uncolored, flags rendered in the argument color instead of the flag
color, and the command name hardcoded to a static ANSI green (c_accent)
instead of the theme-derived c_cmd -- the last of the raw, unconverted
color usage the audit turned up.
2026-09-21 01:44:14 -04:00
rootiest cbf1a0a9a2 fix(functions): color tool/flag names in config-help's pager fallback chain
ov, bat, man, less, and cat were plain text, and man -l's -l wasn't
styled as a flag, in an otherwise-converted help block.
2026-09-21 01:39:01 -04:00
rootiest 1dcbd6498c fix(functions): color the command name in config-help's USAGE section
The USAGE block's "help config" was left as plain text while every
other section (EXAMPLES) correctly colored it with c_cmd.
2026-09-21 01:36:30 -04:00
rootiest 610714476d feat(functions): derive the shared help palette from the fish theme
__fish_palette's c_cmd/c_flag/c_arg/c_dim now read fish's own highlighter
variables (fish_color_command/option/param/autosuggestion) when set, and
c_head reads the pager's fish_pager_color_prefix, so --help text matches
whatever the user's actual theme renders at the prompt instead of a fixed
guess at it. Each role keeps its previous static value as a fallback
(e.g. a --no-config script, or the theme variable being unset or empty).

Routes __fish_help_header's title/section colors and config-help's,
gi's, and git-clean's own hand-rolled --help blocks through the palette
instead of their hardcoded set_color calls, which fixes the
--help-vs-actual-prompt color mismatch across most of the config's
functions in one place (__fish_help_header backs the majority of
user-facing --help output).

Also fixes role mismatches found along the way: several already-palette
functions (dockup, fish-deps, pkg, play-media, dng2avif) were coloring
their <placeholder>/[bracket] argument text with c_dim instead of c_arg,
and scrub's "Aggressive Targets:" heading was still a hardcoded
set_color call sitting next to an otherwise-converted help block.
2026-09-21 01:19:38 -04:00
fishconfig-bot 02c060f9f1 chore(docs): regenerate manual, man page, and component registry 2026-09-19 04:56:58 +00:00
rootiest 348a0453a9 Merge pull request 'docs: rename "documentation website" heading to "project wiki"' (#157) from docs/rename-manual-heading-wiki into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m58s
CI / build-docs (push) Successful in 3m52s
Reviewed-on: #157
2026-09-19 04:51:11 +00:00
rootiest eb22b1f27f docs: rename "documentation website" heading to "project wiki"
Missed in the prior terminology-sync pass; updates both the manual
source heading and the matching keyword-index entries.
2026-09-19 00:50:08 -04:00
rootiest 6292b12eca Merge pull request 'docs: rename "documentation site" to "project wiki"' (#156) from docs/rename-documentation-wiki into main
Reviewed-on: #156
2026-09-19 01:01:21 +00:00
rootiest d9410701e3 docs: rename "documentation site" to "project wiki"
Consistent terminology across README, CONTRIBUTING, and CI step name.
2026-09-18 20:57:53 -04:00
fishconfig-bot b8e97d7223 chore(docs): regenerate manual, man page, and component registry 2026-09-16 23:45:42 +00:00
rootiest 00606ecdca Merge pull request 'fix(mkrep): make origin linking idempotent' (#155) from fix/mkrep-origin-idempotent into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m54s
CI / build-docs (push) Successful in 4m22s
Reviewed-on: #155
2026-09-16 23:39:28 +00:00
rootiest a09d3db800 fix(mkrep): make origin linking idempotent
Both link paths -- --remote and the --server/$GIT_SERVER link-existing
branch -- called `git remote add origin` bare. That fails with "remote
origin already exists" whenever the target is already linked, which is
the normal case for `mkrep .` against an existing checkout and for any
rerun against the same target. The failure took the whole call down with
exit 1.

Route both through a new _mkrep_add_origin helper: add when there is no
origin, accept and report when origin already points at the requested
URL, and refuse when it points elsewhere. A different URL is a different
repo, so repointing stays the caller's explicit decision rather than a
silent rewrite of a checkout mkrep may have been aimed at by mistake.
2026-09-16 19:36:34 -04:00
fishconfig-bot 30a3288141 chore(docs): regenerate manual, man page, and component registry 2026-09-16 23:25:57 +00:00
rootiest f901ec460f Merge pull request 'style(tests): satisfy fish_indent in the agents-vault suite' (#154) from fix/agents-vault-test-indent into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m15s
CI / build-docs (push) Successful in 4m0s
2026-09-16 23:19:41 +00:00
rootiest fb62005140 style(tests): satisfy fish_indent in the agents-vault suite
The gitignore-anchoring check quoted arguments fish_indent removes, so
run-tests.fish failed its indent lint and exited 1 on main even though all
753 assertions passed.
2026-09-16 19:15:30 -04:00
rootiest acbbd8d9e1 Merge pull request 'fix(agents-init): require a git repo to scaffold, and anchor the .gitignore fallback match' (#153) from fix/agents-init-nongit-and-gitignore-anchor into main
CI / github-mirror (push) Skipped
CI / test (push) Failing after 2m18s
CI / build-docs (push) Skipped
Reviewed-on: #153
2026-09-16 23:09:00 +00:00
rootiest 9c52e64373 fix(agents-init): anchor the .gitignore fallback match
The non-git fallback used a substring match, so a negation line such as
!AGENTS/foo counted as the pattern AGENTS/ already being ignored and the
real rule was never appended.
2026-09-16 19:06:47 -04:00
rootiest 63288d9fd6 fix(agents-init): only scaffold inside a git repository
Resolving the root to (pwd) meant running an agent CLI anywhere created an
AGENTS/ git repo, an AGENTS.md, two root symlinks, and a docs/ tree in that
directory. Scaffolding now requires a git repo or a pre-existing agent file
(AGENTS.md, CLAUDE.md, or AGENTS/); elsewhere it is a no-op.
2026-09-16 19:06:43 -04:00
fishconfig-bot 6aebf5e189 chore(docs): regenerate manual, man page, and component registry 2026-09-16 08:26:00 +00:00
rootiest a35ddf9e96 Merge pull request 'fix(mkrep): stop the test suite creating real repos, and confirm implicit ones' (#152) from fix/mkrep-implicit-remote-confirm into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m6s
CI / build-docs (push) Successful in 3m51s
Reviewed-on: #152
2026-09-16 08:20:01 +00:00
rootiest c67b5ebb35 fix(mkrep): stop the test suite creating real repos, and confirm implicit ones
Two related defects on the `$GIT_SERVER` auto-create path added in #150.

The test suite was creating repositories on a live forge. mkrep resolves a
server from `$GIT_SERVER` plus `$GITEA_URL`/`$GITEA_HOST`, and this repo
doubles as a real ~/.config/fish where all of them are exported, so the six
sections that call a bare `mkrep <dir>` took the auto-create branch and
contacted the server. That is how an empty `rootiest/repo` came to exist on
git.rootiest.dev on 2026-09-14 (since deleted). It also explains why those
cases looked flaky rather than broken: standalone they passed, because the
repo existed and mkrep linked instead of creating, while under
run-tests.fish they failed with `Error: no available login` — a throwaway
XDG_CONFIG_HOME leaves `tea` with no credentials. Passing for that reason is
worse than failing.

The suite now neutralizes all five variables once at setup, the same
shadow-to-empty pattern already used per-section for --check-existing, whose
comment flagged this exact hazard. Nothing depended on the ambient value:
every section wanting a server sets its own `set -lx GIT_SERVER`, and one
section asserts the opposite outright.

mkrep itself now confirms before an implicit create. Creating a repository
on a forge is the only outward-facing thing mkrep does, and on this path an
exported variable is all it takes to reach it, so `mkrep foo` — which reads
as purely local — would make a repo on a server without saying so. It asks
first, defaulting to no; declining leaves the local repo with no remote and
still exits 0. Provenance is what gates the prompt, not the resolved value:
--server, --remote and --new-remote all state outright what they will do, so
none of them prompts, and --yes skips the question. Where it cannot be asked
(a script, a pipe, any non-interactive shell) creation is skipped rather than
assumed, with a note on stderr naming the flags that would allow it.

Nine new assertions cover the skip, its stderr note, --yes, and --server not
prompting. The interactive read is verified by hand under a PTY, both
answers, but is not in the suite: that needs a pseudo-terminal, and the
answer parsing it guards is a single `string match`.
2026-09-16 04:16:35 -04:00
fishconfig-bot 311efdce68 chore(docs): regenerate manual, man page, and component registry 2026-09-16 08:05:10 +00:00
rootiest fc5ecb591b Merge pull request 'feat(md): add an md wrapper for MarkText, with an optional read-only sandbox' (#151) from feat/md-marktext-wrapper into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m20s
CI / build-docs (push) Successful in 4m19s
Reviewed-on: #151
2026-09-16 07:58:29 +00:00
rootiest f153a3db87 feat(deps): add marktext and firejail as optional dependencies
Both back the new `md` wrapper and nothing else, so both land in the
Optional tier, skipped by `fish-deps install`/`sync` unless `--optional`
(or `--all`) is passed.

firejail is a plain system package everywhere, so it needs no special
handling. marktext is not: upstream ships an AUR package and its own
GitHub release assets, and no distro carries it under a common name. Its
`_fdc_pm` entry is therefore deliberately empty, and a `marktext-release`
special offers the AUR package via paru/yay where one is present and
otherwise installs upstream's AppImage to ~/.local/bin/marktext.

The release assets embed their version in the filename, so there is no
stable /releases/latest/download URL to fetch -- `_fish_deps_marktext_appimage`
reads the download URL from the GitHub API instead. Upstream builds the
Linux AppImage for x86_64 only, and the helper says so rather than
downloading an unusable binary.

`fish-deps update` refreshes marktext through the AUR where available, and
otherwise only when ~/.local/bin/marktext exists -- a distro-packaged
marktext belongs to that package manager, and dropping an AppImage into
~/.local/bin would shadow it.
2026-09-16 03:56:48 -04:00
rootiest 8aa2d15ae8 feat(md): launch MarkText detached, with an optional read-only sandbox
`md` forwards every argument to marktext untouched except two flags of its
own: `--read-only`/`-r` and `--foreground`. By default it detaches via
`bkg`, so the shell stays usable and the editor outlives the window that
launched it.

MarkText has no read-only mode, so `-r` sandboxes it with firejail, binding
each named file read-only. The subtlety is that MarkText is single-instance:
a plain launch hands the file to an already-running, unsandboxed, writable
window and exits, silently defeating the sandbox. `-r` therefore also passes
a private `--user-data-dir`, which forces an independent instance the
read-only bind actually covers, plus `--no-sandbox`, since Electron's own
sandbox needs the user namespaces firejail has already taken away.

Flags whose entire purpose is terminal output (`--version`, `-v`/`--verbose`,
`--debug`) imply `--foreground`; backgrounding them would send the output
you asked for to /dev/null.

The function is autoloaded and so never shadows an `md` function or alias
defined elsewhere -- fish only looks in functions/ when nothing named `md`
exists. A real `md` *binary* would be shadowed, so the body hands off to it
verbatim whenever marktext is not installed. No conf.d file and no
opinionated guard: `md` is a novel name rather than a command shadow, the
same as `bkg` and `detach`.
2026-09-16 03:56:47 -04:00
fishconfig-bot f445ec5426 chore(docs): regenerate manual, man page, and component registry 2026-09-15 03:44:31 +00:00
rootiest 35b2d0a16c Merge pull request 'feat(git): add --server/--check-existing to mkrep for gitea/gitlab/github' (#150) from feat/mkrep-server-detection into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m5s
CI / build-docs (push) Successful in 3m53s
Reviewed-on: #150
2026-09-15 03:38:37 +00:00
rootiest 17721a1cf2 fix(git): don't push an unborn HEAD from mkrep's default remote templates
mkrep only ever runs git init, never a commit, so a freshly created
repo has no HEAD yet. The gitea/gitlab default templates chained
`git push -u origin HEAD` unconditionally after linking the remote,
which fails immediately regardless of the remote ("src refspec HEAD
does not match any") -- reproduced by a real user hitting it on the
first mkrep --server call. Guard the push on HEAD actually resolving
to a commit; skipping it is the correct outcome (nothing to push yet),
and a real push failure once a commit exists still propagates.
2026-09-14 23:22:52 -04:00
rootiest 0a3b332d79 fix(git): prepend https:// to *_HOST vars in mkrep server detection
$GITEA_HOST/$GITLAB_HOST are bare hostnames (git.example.com); only
$GITEA_URL/$GITLAB_URL are expected to carry a scheme. mkrep was using
_HOST values as-is, producing a schemeless clone URL when only the
_HOST var was set.
2026-09-14 23:11:12 -04:00
rootiest 1a07e94002 feat(git): add --server/--check-existing to mkrep for gitea/gitlab/github
mkrep can now pick a git host from --server, $GIT_SERVER, and
$GITEA_URL/$GITEA_HOST/$GITLAB_URL/$GITLAB_HOST (base URL only -- type
must come from --server/$GIT_SERVER, so setting those URL vars for an
unrelated tool can't silently turn a plain mkrep call into a
remote-creating one). Before creating anything it checks via
gh/glab/tea whether the repo already exists and links instead of
recreating it; --check-existing runs just that check and reports
without touching remotes.
2026-09-14 21:06:28 -04:00
fishconfig-bot 9821e64ae4 chore(docs): regenerate manual, man page, and component registry 2026-09-14 23:04:56 +00:00
rootiest dfb5de5768 Merge pull request 'fix(docs): render function entries per-section for the Starlight site' (#149) from claude/starlight-doc-parsing-fix-voyyvi into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m1s
CI / build-docs (push) Successful in 3m32s
Reviewed-on: #149
2026-09-14 22:59:26 +00:00
Claude 2c1aa52871 fix(docs): render function entries per-section for the Starlight site
Function entry pages previously reused the man-page pipeline's single
indented block plus its paragraph-guessing heuristics (_is_prose's
per-line word count, _as_table's 2+ row minimum), so whether a
Description, Arguments, or Exit Status section landed as flowing
prose, a table, or an unhighlighted code block depended on incidental
shape -- a short wrapped line, a single argument, a narrow column --
rather than which section it was. `cat`, `copy`, and `ltr` each ended
up formatted differently for no functional reason.

Add render_entry_site, a site-only renderer that builds each entry
straight from the parsed function header instead of re-deriving
structure from indented text: every present section (Synopsis,
Description, Arguments, Exit Status, Returns, Notes, Example) gets its
own `###` heading, Arguments/Exit Status become a table via the new
_kv_rows column parser (which also fixes narrow single-space columns
and name-only rows with wrapped continuations), and everything else is
unwrapped into normal paragraphs. The man-page/pandoc path
(render_entry, build_concat) is untouched.
2026-09-14 18:56:25 -04:00
rootiest 0736de384a Merge pull request 'feat(git): add pre-push hook to reject unsigned commits' (#148) from chore/pre-push-signature-check into main 2026-09-13 00:58:15 +00:00
rootiest 6c35dc4337 docs(contributing): document the pre-push signature hook opt-in
Contributors need to know .githooks/pre-push exists and how to point
their clone at it, since it isn't wired up automatically.
2026-09-12 20:56:48 -04:00
rootiest 35f024c159 feat(git): add pre-push hook to reject unsigned commits
Gittyup commits via libgit2 directly and never invokes gpg, silently
ignoring commit.gpgsign — root cause of an unsigned commit reaching
main. Adds a tracked .githooks/pre-push that rejects any push
carrying a commit with no signature or a bad signature, bypassable
with --no-verify. Wiring core.hooksPath to it is a per-machine
concern, done separately in user-dots, not shipped here.
2026-09-12 20:51:19 -04:00
rootiest 5444532b5a docs: correct formatting error in documentation
- Removes a formatting error that broke the visual of
the --remote flag in both the documentation and
the function's help output.

-----

Impacted files:
functions/mkrep.fish
2026-09-12 20:41:29 -04:00
rootiest 679a703ab2 Merge pull request 'fix(ci): base64-encode the bot GPG key secret' (#147) from fix/ci-gpg-key-base64 into main 2026-09-10 04:00:24 +00:00
fishconfig-bot ecfcea5106 chore(docs): regenerate manual, man page, and component registry 2026-09-10 03:58:16 +00:00
rootiest 4da176d507 fix(ci): base64-encode the bot GPG key secret
Raw multi-line armored key piped through 'echo | gpg --import' came out
CRC-corrupted (Invalid keyring) on the first real run -- something in the
secret/env round-trip mangles embedded newlines. Regenerated the bot key
(old one is unrecoverable, secrets are write-only) and store it
base64-encoded, decoded with base64 -d before import.
2026-09-09 23:52:40 -04:00
rootiest cc9531f19f Merge pull request 'fix(agy): map -r/--resume with session id to --conversation' (#146) from fix/agy-resume-conversation-syntax into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m53s
CI / build-docs (push) Failing after 3m38s
Reviewed-on: #146
2026-09-10 03:37:58 +00:00
rootiest 4ab52329e1 fix(agy): map -r/--resume with session id to --conversation
agy uses different resume syntax than claude: -c/--continue always
resumes the most-recent session, while --conversation takes a
specific session id. Previously -r/--resume was blanket-mapped to
-c/--continue, breaking `agy --resume <id>` and `agy -r=<id>` style
invocations. Now bare -r/--resume (no id following) maps to
-c/--continue; -r/--resume given an id (via =id or a following
non-flag word) maps to --conversation(=id).
2026-09-09 23:24:29 -04:00
rootiest 2597b3ccd3 Merge pull request 'fix(ci): sign docs-regen commits with dedicated bot GPG key' (#145) from fix/ci-commit-signing into main 2026-09-10 02:48:51 +00:00
rootiest a751124b8b fix(ci): sign docs-regen commits with dedicated bot GPG key
actions@gitea was never a verified email on any Gitea account, so the
CI docs-regen commit (git commit && git push, done client-side in the
runner) could never show as verified regardless of server-side
[repository.signing] config -- Gitea only signs commits it generates
itself (merge button, web editor, wiki), never ones a client pushes.

Import a dedicated passphrase-less key for a new fishconfig-bot
account (verified email, no login) from the CI_GPG_PRIVATE_KEY repo
secret and sign with it instead.
2026-09-09 22:16:13 -04:00
rootiest 6732a71eb7 Merge pull request 'fix(git-clean): strip the '+' other-worktree marker too' (#144) from fix/clean-worktree-branch-marker into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m58s
CI / build-docs (push) Successful in 3m37s
2026-09-10 01:15:42 +00:00
rootiest e6c6d2533d fix(git-clean): strip the '+' other-worktree marker too
git branch -vv marks column 1 with '+' (not '*') for a branch checked
out in another linked worktree. Only '*' was stripped from $1, so a
gone branch shown with '+' left a bogus "+" entry in $gone_branches
that then failed to delete: error: branch '+' not found.

Add a regression case reproducing the '+'-marked gone-branch line via
the existing git-clean mock handler in tests/test-network-fish.fish.
2026-09-09 21:14:04 -04:00
Gitea Actions 6199caf0d0 chore(docs): regenerate manual, man page, and component registry 2026-09-10 01:11:47 +00:00
rootiest d93cb286ef Merge pull request 'feat(mkrep): add directory + git-repo scaffolding command' (#142) from feat/mkrep-command into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m49s
CI / build-docs (push) Successful in 3m35s
2026-09-10 01:01:37 +00:00
rootiest 3c621db727 Merge pull request 'test: expand test coverage across core functions, enforce strict fish_indent linting, and add network isolation harnesses' (#143) from test/network-edge-case-coverage into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 2m2s
CI / build-docs (push) Successful in 3m34s
2026-09-10 01:00:45 +00:00