Skip to content
Development
Command

/al

Run AgentLint diagnostic across all projects. Use when: user says /al, 'check all projects', 'agent lint', or '体检'.

From plugin
agent-lint
652 skills2 commands1 hook
> /plugin marketplace add 0xmariowu/AgentLint
> /plugin install agent-lint@agent-lint

Command definition

al.md
description: "Run AgentLint diagnostic across all projects. Use when: user says /al, 'check all projects', 'agent lint', or '体检'."
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Glob(*), Grep(*), Agent(*)

/al — AgentLint

Diagnose, plan, fix. One command. User presses Enter twice at most.

Flow

Step 1: Module Selection

AskUserQuestion with **defaults pre-selected** (user can press Enter to accept):

AgentLint — which checks to run?

Core (deterministic, no AI calls) — default ON:
  ☑ Findability         — can AI find what it needs?
  ☑ Instruction Quality — are your rules well-written?
  ☑ Workability         — can AI build and test?
  ☑ Continuity          — can next session pick up?
  ☑ Safety              — are secrets and CI locked down?
  ☑ Harness             — are Claude Code hooks/permissions safe?

Extended (opt-in, runtime-dependent):
  ☐ Deep Analysis       — find contradictions, dead weight, vague rules (uses AI)
  ☐ Session Analysis    — discover issues from your Claude Code session logs

[Enter to run with defaults]

**Default: all 6 core dimensions.** Extended analyzers are optional and will show as `n/a` in the output unless explicitly checked. User presses Enter → runs immediately.

Record the normalized choices in shell variables for the config write in Step 2. Core is currently all-or-nothing and defaults on; Deep/Session are the only runtime-selectable modules.

RUN_CORE=true
RUN_DEEP=false     # set true only if Deep Analysis was selected
RUN_SESSION=false  # set true only if Session Analysis was selected

Step 2: Init (first run only)

If `${CLAUDE_PLUGIN_DATA}/config.json` doesn't exist, ask with default:

Where are your projects? [~/Projects]: ↵

Press Enter → uses `~/Projects`. Save to `${CLAUDE_PLUGIN_DATA}/config.json`. Never ask for the projects root again.

After Step 1, always persist the selected scan options back into the same config file. The scan and verify steps must read this file instead of relying on stale shell variables; otherwise the config is dead state and Deep/Session choices are ignored.

CONFIG_DIR="${CLAUDE_PLUGIN_DATA:-$HOME/.al}"
CONFIG_FILE="$CONFIG_DIR/config.json"
mkdir -p "$CONFIG_DIR"

if [ ! -f "$CONFIG_FILE" ]; then
  PROJECTS_ROOT_INPUT="${PROJECTS_ROOT_INPUT:-$HOME/Projects}"
  node -e '
    const fs = require("fs");
    const file = process.argv[1];
    const projectsRoot = process.argv[2];
    fs.writeFileSync(file, JSON.stringify({
      projects_root: projectsRoot,
      modules: { core: true, deep: false, session: false }
    }, null, 2) + "\n");
  ' "$CONFIG_FILE" "$PROJECTS_ROOT_INPUT"
fi

CONFIG_TMP="$(mktemp "$CONFIG_DIR/config.XXXXXX")"
node -e '
  const fs = require("fs");
  const [file, out, core, deep, session] = process.argv.slice(1);
  const cfg = JSON.parse(fs.readFileSync(file, "utf8"));
  cfg.modules = {
    ...(cfg.modules || {}),
    core: core === "true",
    deep: deep === "true",
    session: session === "true"
  };
  fs.writeFileSync(out, JSON.stringify(cfg, null, 2) + "\n");
' "$CONFIG_FILE" "$CONFIG_TMP" "$RUN_CORE" "$RUN_DEEP" "$RUN_SESSION"
mv "$CONFIG_TMP" "$CONFIG_FILE"

Step 3: Core scan (no interaction, no scoring yet)

`scanner.sh`'s `--project-dir` is single-project. For `/al`'s multi-project flow, use the env-var path so the scanner auto-discovers every git repo under `PROJECTS_ROOT`:

CONFIG_FILE="${CLAUDE_PLUGIN_DATA:-$HOME/.al}/config.json"
PROJECTS_ROOT="$(jq -er '.projects_root' "$CONFIG_FILE")"
RUN_DEEP="$(jq -r '.modules.deep // false' "$CONFIG_FILE")"
RUN_SESSION="$(jq -r '.modules.session // false' "$CONFIG_FILE")"
AL_DIR="${CLAUDE_PLUGIN_ROOT}"
RUN_ROOT="${CLAUDE_PLUGIN_DATA:-$HOME/.al}/runs"
mkdir -p "$RUN_ROOT"
RUN_DIR="$(mktemp -d "$RUN_ROOT/$(date +%Y%m%d)-XXXXXX")"
PROJECTS_ROOT="$PROJECTS_ROOT" bash "$AL_DIR/src/scanner.sh" > "$RUN_DIR/scan.jsonl"

**Do NOT run scorer yet.** If Deep or Session modules were selected in Step 1, they produce additional JSONL records that must be merged with `scan.jsonl` before scoring. Scoring prematurely here would lock in a core-only score and force a re-score later, producing inconsistent intermediate reports.

`mkdir -p "$RUN_ROOT"` is required because `mktemp -d` fails if the parent directory doesn't exist — which is exactly the state on a user's first `/al` invocation after plugin install.

`RUN_DIR` replaces the old `/tmp/al-*.jsonl` paths so concurrent Claude sessions on the same machine don't overwrite each other's runs.

Step 3b: Extended analyzers (conditional)

If `RUN_DEEP` read from `${CLAUDE_PLUGIN_DATA}/config.json` is `true`, run the Deep Analysis flow now (see "Deep Analysis" section further below) to produce `$RUN_DIR/deep.jsonl`.

If `RUN_SESSION` read from `${CLAUDE_PLUGIN_DATA}/config.json` is `true`, run the Session Analysis flow to produce `$RUN_DIR/session.jsonl`.

Neither produces output when not selected — that's fine, the merge step handles a missing file gracefully.

Step 3c: Merge + score + plan (no interaction)

: > "$RUN_DIR/combined.jsonl"
cat "$RUN_DIR/scan.jsonl" >> "$RUN_DIR/combined.jsonl"
[ -f "$RUN_DIR/deep.jsonl" ]    && cat "$RUN_DIR/deep.jsonl"    >> "$RUN_DIR/combined.jsonl"
[ -f "$RUN_DIR/session.jsonl" ] && cat "$RUN_DIR/session.jsonl" >> "$RUN_DIR/combined.jsonl"

node "$AL_DIR/src/scorer.js" "$RUN_DIR/combined.jsonl" > "$RUN_DIR/scores.json"
node "$AL_DIR/src/plan-generator.js" "$RUN_DIR/scores.json" > "$RUN_DIR/plan.json"

Scoring happens **once**, after every selected analyzer has written its JSONL. `score_scope` is `core+extended` exactly when at least one of `deep.jsonl` / `session.jsonl` is present, and `core` otherwise — no coercion, no re-scoring.

Step 4: Present Scores (no interaction)

Read `$RUN_DIR/scores.json` and present. The `(core)` suffix on the total line appears when Deep/Session did not run — it signals that the score is averaged over the 6 core dimensions only. Extended dimens

Read more
@0xmariowu
Ships withagent-lint

The linter for your agent harness. Works with Claude Code, Codex, and Cursor.

Stars on GitHub

Momentum

stars in total
65
Star history of 0xmariowu/AgentLint on GitHub, a chart by star-history.com

Other commands on agent-lint.

setup

setup

Command

Bootstrap a repository with AI-native CI/CD, hooks, and templates in one command.

@0xmariowu@0xmariowuInstall Command

More commands from other plugins.

build
Auto-invoked

build

Command

Implement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.

@addyosmani@addyosmaniInstall Command