Files
pbakaus_impeccable/crates/detect/src/lib.rs
T
Paul BakausandClaude Fable 5.1 0547ed6a63 reorg C: the open Rust runtime joins this repo as one Cargo workspace
The engine no longer lives in a separate repo. `crates/` is a snapshot of the
open crates (foundation, core, common, context, live, hook, skills, comp,
comp-verbs, html, browser, detect, cli) plus `Cargo.lock`, taken as a git
archive of the engine repo at the commit that finished the boundary split.
None of that repo's history comes with it, and none of it should: the closed
half stays private.

The closed half is the rule engine. It ships as a prebuilt native archive per
target, `libimpeccable_detector.a`, published as a `detector-v<X>` GitHub
Release on this repo. `crates/core/build.rs` resolves and links it three ways:
`IMPECCABLE_DETECTOR_LIB=<dir>` for a local detector build, else the
`~/.impeccable/detector/<version>/<target>/` cache, else a download verified
against its `.sha256` sidecar. `crates/core` is a thin shim over a three-symbol
C ABI; nothing above it knows the boundary exists.

What changed versus the engine repo copy:

- Every crate manifest moves from `license-file.workspace` to
  `license.workspace` (this workspace declares Apache-2.0), and the workspace
  gains the `postcard` dependency the boundary encoding needs.
- The launcher contract test reads `skill/scripts/impeccable{,.cmd}` instead of
  a sibling `launcher/` dir, and `engine_binary` downloads from
  `github.com/pbakaus/impeccable/releases/download/engine-v<version>/` instead
  of the retired dist repo. No oracle golden carried the old URL, so no
  re-recording was owed.
- The tests that hunted for a public repo through `IMPECCABLE_PUBLIC_REPO`,
  `../impeccable-second` or a hardcoded home directory now resolve the root as
  `CARGO_MANIFEST_DIR/../..`, because they are in it. The env var stays as an
  override for an out-of-tree checkout.
- The in-page bundle (`detect-antipatterns-browser.js`, 2 MB of generated wasm
  glue) is no longer tracked. `crates/core/build.rs` resolves it beside the
  archive, hands the path to `impeccable_core::browser::IN_PAGE_BUNDLE_JS`, and
  live mode serves that. `scripts/check-detector-release.mjs` now requires it
  and its `.sha256` in a detector release.
- The live crate embeds `skill/scripts/live-browser*.js` and
  `modern-screenshot.umd.js` directly rather than through vendored copies, so
  the binary and the installed skill cannot drift.
- `crates/browser/assets/` (an unused second copy of the bundle) is gone.
- `tests/lib/engine-bin.mjs` also accepts `target/release/impeccable`, so a
  plain `cargo build --release -p impeccable` is enough to run `bun run test`.

Verified with the archive from a local detector build: `cargo test --workspace`
267 pass, oracle 795 pass / 0 fail / 0 missing, `bun run build` clean, the
default suite green, and the launcher's `engine-probe` handshake answering
through `skill/scripts/impeccable`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY
2026-09-01 15:31:26 -07:00

81 lines
3.1 KiB
Rust

//! impeccable-detect: `impeccable detect` orchestration and the non-DOM
//! engines, ported from `cli/bin/cli.js`, `cli/engine/cli/main.mjs`,
//! `cli/engine/node/file-system.mjs`, `cli/lib/impeccable-config.mjs`,
//! `cli/engine/engines/regex/detect-text.mjs`, `cli/engine/design-system.mjs`,
//! `cli/engine/profile/profiler.mjs`, and `cli/bin/commands/ignores.mjs`.
//!
//! Engine seams: [`engines::HtmlEngine`] (static HTML, crates/html) and
//! [`engines::UrlEngine`] (browser, crates/browser). This crate never depends
//! on those crates; the `cli` binary wires them in through
//! [`engines::Engines`]. crates/html depends on this crate for the design
//! system types and helpers ([`design_system`]).
pub mod cli;
pub mod config;
pub mod design_system;
pub mod detect_text;
pub mod engines;
pub mod file_system;
pub mod ignores;
pub mod jsp;
pub mod profiler;
pub mod regex_matchers;
pub mod skills;
pub mod util;
use impeccable_common::Io;
pub use engines::{
Engines, HtmlEngine, MissingHtmlEngine, MissingUrlEngine, ScanOptions, UrlEngine,
};
/// `impeccable detect [args]` (`detectCli`). Returns the exit code.
pub fn run_detect(args: &[String], io: &mut Io, engines: &Engines) -> i32 {
cli::run_detect(args, io, engines)
}
/// `impeccable ignores [args]`.
pub fn run_ignores(args: &[String], io: &mut Io) -> i32 {
ignores::run(args, io)
}
/// `impeccable skills [args]` and the top-level `help|install|link|update|check`.
pub fn run_skills(args: &[String], io: &mut Io) -> i32 {
skills::run(args, io)
}
/// JS: cli.js#looksLikeDetectTarget
pub fn looks_like_detect_target(arg: &str, cwd: &str) -> bool {
let is_flag = arg.starts_with('-');
let is_url = {
let lower = arg.to_ascii_lowercase();
lower.starts_with("http://") || lower.starts_with("https://")
};
let is_path_shaped = arg.contains('/') || arg.contains('\\') || arg.contains('.');
let is_existing = util::exists(&jsp::resolve(cwd, &[arg]));
is_flag || is_url || is_path_shaped || is_existing
}
/// The root `impeccable --help` text (`cli.js`).
pub const ROOT_USAGE: &str = "Usage: impeccable <command> [options]
Commands:
detect [file-or-dir-or-url...] Scan for UI anti-patterns and design quality issues
ignores Manage detector ignore rules, files, and values
help List all available skills and commands
install Install impeccable skills into your project or global harness
link Symlink skills from a local checkout or submodule
update Update skills to the latest version
check Check if skill updates are available
Options:
--help Show this help message
--version Show version number
Compatibility:
impeccable skills <command> Legacy namespace; still supported.
";
/// The `impeccable init` mistake message (`cli.js`).
pub const INIT_MESSAGE: &str = "\"init\" is not a CLI command. Type /impeccable init in your AI coding agent's chat (Claude Code, Cursor, Codex, ...), not in this terminal.\n";