Skip to content

Select the rule packs that judge writes in this repository - #4

Closed
CheckPickerUpper wants to merge 68 commits into
masterfrom
chore/ai-lab-select-rule-packs
Closed

CheckPickerUpper wants to merge 68 commits into
masterfrom
chore/ai-lab-select-rule-packs

Conversation

@CheckPickerUpper

Copy link
Copy Markdown
Owner

A repository with no selection is judged by the universal packs alone, so every
language rule stays silent and an unjudged write is reported exactly like a clean
one. This names the packs that apply to what this repository is written in.

Found by sweeping every checkout on one machine: 25 repositories were in this
state. The cause was .ai-lab/ sitting in the global gitignore, which hid
plugins.toml while it was there to hide generated client output. That rule is
now .ai-lab/* with !.ai-lab/plugins.toml.

Verified against the published evaluator, same write before and after:

export function parse(input: any): any { return input; }
before  {} allowed
after   WriteRefused

Replaces OSC 6 (iTerm2-only, never worked on WT) with OSC 4 index 264
(FRAME_BACKGROUND) which sets just the tab color strip in Windows
Terminal. Uses rgb:RR/GG/BB hex format matching Hanselman's working
implementation. Reset via OSC 104;264. Silently ignored by terminals
that don't support it.
Repos can now declare an `aliases` field with alternative names.
`rj ninja` resolves to nro if nro has aliases = ["ninja", "ninja-revival"].
Lookup checks the primary key first, then walks all repos' aliases.
Works for jump, open, color, and edit commands.
Replaces stdout/stderr emission with direct writes to CONOUT$ (Windows)
and /dev/tty (Unix). PowerShell captures stdout in subshells and prompt
functions, so escape sequences never reached the terminal. Writing
directly to the console handle bypasses all shell capture mechanics and
works in every context — PowerShell, bash, cmd, VS Code terminal, etc.
Checks config file health, shell integration presence (rj/ro/prompt hook),
and whether all registered repo paths exist on disk. Each failed check
prints an actionable hint. Also adds full publish checklist to agent notes.
Shell integration sets REPORTAL_LOADED=1 on profile load; doctor checks
for this env var and tells the user to reload if missing. This catches
the exact scenario where rj/ro are in the profile file but the current
terminal hasn't sourced it yet.
Shell integration now lives in ~/.reportal/integration.ps1 (or .sh);
the profile gets a single stable source line that never changes between
versions. Removes rep upgrade — rep init is idempotent and handles both
fresh installs and updates. Doctor now checks integration file version
and session load state.
Every rep command now checks if the integration script version matches
the binary version; if not, it silently rewrites the file. This means
cargo install, scoop update, or brew upgrade just work — no rep init
or rep upgrade needed after the initial setup.
…finder (v0.5.4)

rep list now renders the swatch block in each repo's configured color
(gray default for repos with no color). Fuzzy finder labels in jump and
open now show aliases and use em-dash separator. Added as_rgb_bytes()
to HexColor and swatch_style_for_repo_color() to terminal_style.
Updated README roadmap with planned edit overhaul and AI CLI launcher.
New rep ai command fuzzy-selects a repo and launches an AI CLI
(AI tool, AI, aider) with interactive passthrough. Config
supports [ai_tools.*] registry and default_ai_tool setting; new
configs ship with ai, ai, aider pre-registered. Also
extracted repeated clap fields into shared Args structs.
720-line monolith split into 7 focused files under src/reportal_config/:
hex_color, tag_filter, global_settings, ai_tool_entry, repo_entry,
reportal_config_root, and a pure re-export mod.rs. Added per-field
setters on RepoEntry; removed old update_repo_metadata 5-param method.
Made edit alias optional in preparation for the edit UX overhaul.
Zero behavior changes — purely structural.
Fuzzy-select a repo and open its remote URL in the default browser.
Converts SSH remotes to HTTPS automatically. Falls back to git remote
when the config remote field is empty. Shell alias: rw.
…on.rs

The fuzzy-finder logic and OSC tab title/color emission were duplicated
across jump, open, ai, and web. Now all four delegate to select_repo()
and emit_repo_terminal_identity() via param structs.
- git_commands.rs: GitCommandOutcome + GitCommandParams + run_git_command()
  used by status and sync (was fully duplicated between both)
- prompts.rs: prompt_for_text(), parse_comma_separated_tags(),
  prompt_for_color(), prompt_for_color_edit() used by add and edit
- path_display.rs: print_selected_path_if_visible() used by jump and open
rep edit with no argument now shows the fuzzy finder instead of
erroring with "Repo '' not found". Also adds --tag filter support.
CheckPickerUpper and others added 26 commits April 15, 2026 12:02
Reportal now owns [workspaces.<name>] as the single source of truth
for VSCode/Cursor workspaces. The .code-workspace file on disk is a
derived artifact regenerated from the member repos' current paths
whenever they change, so moving a repo automatically updates every
workspace that references it.

Commands:
- rep workspace list / show / create / delete
- rep workspace add-repo / remove-repo / open
- rep edit now exposes a Path field that regenerates every
  containing workspace on mutation
- rep remove refuses to unregister a repo that is still a member
  of any workspace (RepoIsWorkspaceMember error)

Parse-merge-write for .code-workspace files uses jsonc-parser's CST
API so unknown top-level fields (settings, extensions, launch,
tasks) and JSONC comments round-trip byte-stable across
regeneration — reportal only touches the folders array.

Structural refactors unblocked by the new feature:
- Split repo_entry.rs into repo_entry / tab_title / repo_color /
  repo_registration_builder to satisfy the 1-primary-type-per-file
  rule, enabling the new set_raw_path setter
- Extract rep edit helpers into repo_edit_mutator.rs so the
  command file stays within its free-function budget

Tests (19 total):
- Builder validation (empty name, whitespace, empty repo list,
  valid construction, member order preservation)
- JSONC folder parsing (ordered extraction, missing property,
  non-object root, missing/non-string path, comments)
- CST round-trip preservation of settings / extensions / launch
  and JSONC comments across regeneration
rep list now groups repos by workspace membership as the tree root.
Workspaces answer "what am I working on" (explicit user grouping),
tags answer "what kind of repo is this" (classification) — they are
orthogonal axes that compose as an AND intersection via --tag and
--workspace filters.

Correctness decisions:
- Multi-workspace repos render under every containing workspace, not
  deduped. Deduping would silently hide user-declared multi-membership.
- The summary line reports distinct repo count (not sum of sections)
  so multi-workspace repos do not exaggerate the total.
- Repos in zero workspaces render under a synthetic (unassigned)
  section at the bottom so no repo is ever hidden.
- --workspace <name> suppresses the unassigned section because the
  query is scoped to one workspace; unknown names error with
  WorkspaceNotFound rather than silent empty output.
- Within each section, repos render in the order declared in the
  workspace's `repos` field — the sidebar order the user chose.

New files:
- reportal_config/workspace_filter.rs — WorkspaceFilter enum
- cli_args/workspace_filter_args.rs — shared --workspace flag
- reportal_commands/repo_tree_grouping.rs — tree construction
- reportal_commands/repo_tree_workspace_section.rs — section struct
- reportal_commands/repo_listing_renderer.rs — tree render surface
  (split from repo_listing.rs to keep grouping unit-testable without
  a terminal, and to let the render format evolve independently of
  the tree-building invariants)

Tests (8 new, 27 total):
- unassigned placement
- multi-workspace rendering + distinct count
- workspace filter scoping
- unknown workspace name error
- tag filter restricting members within workspaces
- empty-workspace-after-tag-filter omission
- member order preservation
- tag + workspace filter AND intersection
Adds `aliases` field to workspaces and makes every `rep workspace`
subcommand resolve alias→canonical before downstream file ops, so
short names like `rep workspace open vn` work without building
`vn.code-workspace`.

The lookup logic for repos and workspaces is now one shared
`resolve_canonical_key` over a `HasAliases` trait — no more duplicate
"try key then walk aliases" loops. Fixes a latent footgun where
`get_repo_mut` accepted canonical keys only while `get_repo` already
accepted aliases.

Cross-namespace alias collisions (workspace alias vs. repo name/alias
or vs. another workspace's name/alias) are rejected at config load
and on `add_workspace` via a new `WorkspaceAliasConflict` error.
Workspaces can now mix registered-repo references with inline
filesystem paths. The TOML form `{ path = "..." }` declares a
member that bypasses the repo registry entirely — useful when the
user drives a workspace through reportal but does not want the
individual folders registered as top-level repos.

Existing configs whose `repos` array holds bare strings continue
to load unchanged via an untagged serde representation on the new
`WorkspaceMember` enum.

Trade-off: inline-path members are immune to the path-change
reverse index, so moving an inline-path folder requires editing
the config by hand. The dangling-reference validator and the
`rep remove` guard skip inline-path members for the same reason.
….14.3)

`rj <alias>` and `ro <alias>` now fall through to workspace aliases
when no repo matches:
- rj venoble cd's to the workspace file's parent dir (common-ancestor folder)
- ro venoble launches the editor against the .code-workspace file

Unknown aliases still surface as RepoNotFound because that's the
user-facing concept the shell wrapper advertises. Real I/O errors
from either registry propagate rather than being silently folded
into "not found".

New `rep workspace jump` subcommand + `rjw` / `row` shell wrappers
for the workspace-only variant, for cases where the user wants to
force workspace resolution and refuse any repo-alias match.

v0.14.1's cross-namespace collision validator already guarantees
there's never a repo and workspace sharing an alias, so the fall-
through order is a documentation concern, not a correctness one.
`rj` / `ro` no-arg fuzzy finder now lists workspaces alongside
repos so the user's "go somewhere" mental model works across both
namespaces. Workspace rows are distinguished visually by a ▣▣
prefix swatch and a trailing [workspace] suffix.

`rjw` / `row` without arguments fuzzy-select over workspaces only
instead of erroring on missing arg — mirrors the no-arg behavior
of `rj` / `ro`.

New `workspace_selection` and `target_selection` helpers keep the
fuzzy rendering logic in one place each, so repo-only `rep ai` /
`rep edit` / `rep web` don't accidentally gain workspace rows.

Workspace rows skip the fuzzy list when `--tag` is used because
workspaces do not carry tags and including them in a tag-filtered
list would imply they match the filter.
Stray trailing semicolon on format!() in bash_integration_content()
made the function return () instead of String. Rust 1.95 now flags
this as a hard error, breaking `cargo install reportal`.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
BREAKING: `rep init <shell>` now requires a shell argument and prints
shell code to stdout instead of writing files and prompting.
Users add `eval "$(rep init zsh)"` to their rc file, matching the
starship/zoxide/direnv/mise pattern.

- Config bootstrapped lazily on first command (no more "run init" error)
- Removed ~/.reportal/integration.sh disk writes and profile prompt
- Works identically in TTY shells, CI, sandboxes, WSL

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
Replace cargo-dist's templated installers with our own. The custom
installers drop the binary, then auto-append the `eval "$(rep init
<shell>)"` line to the user's shell rc file with a fenced idempotency
marker. Matches the starship/mise/rustup/zoxide distribution pattern.

cargo-dist continues to build cross-platform archives and checksums;
only the installer layer is ours. Release workflow stages our two
scripts into artifacts/ under the historical asset names so existing
curl-piped install URLs keep working.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
When a user cargo-installs reportal (or otherwise skips the shell
installer), the first invocation of any rep subcommand now detects
an unsourced integration and silently appends the fenced eval block
to the user's shell rc file. Idempotent via the existing marker,
silent when already loaded, skipped for `rep init` itself.

Closes the cargo-install zero-touch gap.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
Before: a workspace was metadata + a loose .code-workspace JSON file
in ~/.reportal/workspaces/. `rjw` cd'd to that metadata directory —
useless for terminal workflows.

After: `rep workspace create <name>` materializes a real directory
at ~/dev/workspaces/<name>/ containing the .code-workspace file plus
one symlink (Unix) or directory junction (Windows) per member repo.
`rjw` now cds there, so `ls` and `ai` both see every member as
a subdir, and git/cargo/IDE operations transparently reach the real
repo through the link.

- New `default_workspace_root` setting (default ~/dev/workspaces)
- New `rep workspace rebuild <name>` to regenerate links
- `rep workspace delete --purge` removes the dir too
- Platform-split link creation via the `junction` crate on Windows
- Transparent auto-migration of pre-v0.15.2 workspaces on first jump
- New `rep prompt --shell <bash|zsh|powershell>` subcommand emits a
  colored identity badge (wrapped with the shell's non-printing-escape
  markers) for inline use inside PS1 / PROMPT / prompt function.
- `rep init` auto-wires the badge into the prompt and coexists with
  any framework (p10k, starship, oh-my-zsh) via strip-and-prepend plus
  end-of-chain self-registration — the hook never touches framework
  content, only bytes it wrote itself.
- `.code-workspace` files generated by `rep workspace rebuild` now
  stamp `window.title` and `workbench.colorCustomizations` from the
  workspace's `title` + `color` config, giving editor and terminal a
  single identity signal.
- `rep color` is now workspace-aware: CWD under `~/dev/workspaces/<n>/`
  resolves to the workspace's identity before falling back to repo
  longest-prefix match.
- New config fields (backward-compatible via serde defaults):
  `[workspaces.<n>]` now accepts `title` and `color`.

Rename sweep (enforced by naming-clarity hooks):
- Args → Arguments (cli_args module + all subcommand arg structs)
- Params → Parameters (all CommandParams / LayoutParams types)
- repo_color.rs → repository_color.rs (both config and commands)
- InitShell / run_init → InitializeShell / run_initialize
- ColorCommandParams.repo_alias → ColorCommandParameters.repository_alias

All existing tests pass (54/54). No config-file breaking changes.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a `shell_alias = true` field to repo / workspace / command
config entries. When set, `rep init <shell>` emits a top-level
shell function for the entry's canonical key (and each declared
alias for repos / workspaces) so users can invoke `vna` directly
instead of `rj vna`, or `uc` directly instead of `rep run --cmd
uc`. Names are emitted with the `function name() { ... }` form
and preceded by `unalias name 2>/dev/null` so a pre-existing
zsh / bash alias does not block the function definition. Built-in
collisions (`rj`, `ro`, `rjw`, `row`, `rw`, `rr`) and names
outside `[A-Za-z0-9_-]` are silently skipped.

`RepoRegistrationBuilder` and `WorkspaceRegistrationBuilder` now
walk `$PATH` and reject any alias / canonical name that resolves
to an existing executable, so `rep add` refuses names like `mc`,
`git`, `ls` that would shadow real commands once shell-alias
export is opted in. Existing config entries are not re-validated
on load — legacy hand-edited shadows continue to work as `rj
<alias>` targets.

`rep doctor` adds a "Shell Alias Shadows" section that probes
every opted-in name and reports any that shadow a system command
on the running machine, with a hint to either rename or drop the
opt-in.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes a class of bug where REPORTAL_LOADED=1 was exported and inherited by
child processes that never sourced the integration. Affected child shells
(non-interactive zsh -c, scripts, certain terminal-host setups) showed up
as 'loaded' even though rj / ro / etc. weren't defined, so 'rep doctor'
lied and the user got 'command not found' with no diagnostic.

The integration scripts now stamp REPORTAL_LOADED with the shell's own
PID ($\$ in bash/zsh, $PID on PowerShell). The rep binary compares the
marker against its parent process id via rustix::process::getppid on Unix
and sysinfo::System on Windows. Match means real loaded session; mismatch
means inherited from a grandparent. Legacy '=1' values are still treated
as loaded so users mid-upgrade don't see false negatives.

Auto-wire and 'rep doctor' both consume the new typed
AutoWireOperationLoadedState. The auto-wire helpers moved from
shell_integration.rs into a new shell_integration_autowire.rs to satisfy
the project's free-fn ceiling and pub-type-companion guards.

Co-Authored-By: AI Opus 4.7 (1M context) <noreply@anthropic.com>
- Add `.serena/` to root .gitignore — local serena MCP cache, memories,
  and project config are user-local and should not be tracked.
- Mark the 2026-04-15 workspaces VSCode integration agent state as
  completed (stale-auto-close, 2026-04-20).
…rUpper/reportal

# Conflicts:
#	agent-state/client surfaces/agent-agent state/agent states/master/2026-04-15-0249-workspaces-vscode-integration.json
#	.gitignore
Bump release metadata to 0.18.4.

Fixes #1.
Declare the guarded shell and PowerShell installers as extra artifacts so release.yml can stay generated.
Use bash in the published Unix installer command and keep cleanup safe under set -u.
A repository with no selection is judged by the universal packs alone, so every
language rule stays silent and an unjudged write is reported the same way as a
clean one. This names the packs that apply to what this repository is written in.
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Visual recap — skipped

The visual recap job did not run for this pull request. This is informational only and does not block the PR.

Recap skipped for 8825be6: VISUAL_RECAP_API_KEY not configured (openai-compatible backend).

@CheckPickerUpper
CheckPickerUpper deleted the chore/ai-lab-select-rule-packs branch August 12, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant