Documentation menu

Other commands

Beyond run, resume, -c, fork and sessions, locac has five commands: one for configuration, one for skills, one for the dashboard, one for evaluation, and one that verifies a build.

locac config

locac config init      # write a template config, if none exists
locac config path      # print the resolved config file path
locac config show      # print the effective settings

init writes ~/.locac/config.json with tightened permissions and this template:

{
  "provider": "anthropic",
  "model": "claude-opus-4-8",
  "budget": { "maxTokens": 500000 }
}

Iterations are unlimited by default; the token budget is the cost guard. If the file already exists, init leaves it alone and says so.

--config <path> makes all three verbs operate on a different file.

config show prints the effective configuration, and that includes a literal apiKey if one is stored in the file. Prefer "$ANTHROPIC_API_KEY" over an inlined secret, and do not paste this output into a bug report.

Every field is documented in Configuration.

locac skills

Skills are markdown playbooks injected into the system prompt. locac ships a bundled set; you can add your own under $LOCAC_HOME/skills.

locac skills list
locac skills add <path-or-url> [name] [--all] [--yes]
locac skills update <name>|--all [--yes]
locac skills remove <name>          # `rm` also works
locac skills edit <name>

list shows both sources, tagged, and a user skill installed from a URL carries the source and the commit it was fetched at:

  archive-extraction [user] — traversal and zip-slip in archive handlers
      ↳ https://github.com/anthropics/skills @ b29e7cf
  deserialization [bundled] — untrusted deserialization sources and gadget reachability

A user skill overrides a bundled one of the same name, because the user directory is searched first.

Installing from a path

add accepts a SKILL.md file or a directory containing one, and copies it into the user skills directory. Installing over an existing skill of the same name replaces it.

Installing from a URL

add also takes an https URL. Four shapes are understood:

URLResolves to
https://github.com/owner/repothe repo's default branch, every skill in it
https://github.com/owner/repo/tree/main/skills/pdfthat directory, on that ref
https://github.com/owner/repo/blob/main/skills/pdf/SKILL.mdthe directory holding it, not the file alone
https://example.com/some-skill.mda single SKILL.md, fetched directly

A blob URL installs the enclosing directory on purpose: a skill's bundled scripts/ and reference.md are part of it, and taking the file alone would silently drop them.

Anything else https is treated as a bare git repo URL. Non-https schemes are refused outright.

Nothing remote installs without --yes. The exact name and description that will enter the system prompt are printed first, stripped of control characters, and the command stops:

about to install "pdf" from https://github.com/anthropics/skills
  Use this skill whenever the user wants to do anything with PDF files…

this text goes into the system prompt. re-run with --yes to install.

A URL carrying several skills prints its index and installs nothing until one is named:

18 skills available — name one to install:
  pdf (skills/pdf) — Use this skill whenever the user wants to do anything with PDF files…
  pptx (skills/pptx) — Use this skill any time a .pptx or .potx file is involved…
  …

  locac skills add https://github.com/anthropics/skills <name> --yes
  locac skills add https://github.com/anthropics/skills --all --yes

That index is the marketplace. There is no curated registry to trust: what a repo contains is what you see, and you approve it before any of it reaches the prompt.

--all takes the whole repo under one gate rather than one invocation and one clone per skill. The disclosure is unchanged - every name and description is still printed before anything installs - only the count changes. A skill that fails to install is reported and skipped; the rest still land.

The in-repo path is shown next to the name when the two differ, and either string works as the picker, so a skill nested under an examples/ directory is still unambiguously nameable.

Updating

An installed skill records where it came from, so it can be re-fetched:

locac skills update pdf
locac skills update --all

update replays the recorded source, ref and in-repo path. When the fresh commit matches the recorded one, nothing is written:

"pdf" is up to date (b29e7cf).
"pptx" updated (b29e7cf → e4a1d02).

A changed name or description stops for --yes and prints both versions first, because that text is what gets pasted unfenced into the trusted system prompt - a skill quietly becoming a different skill is exactly the event the gate exists to catch. A changed body is a routine update and passes silently:

"pdf" would change what enters the system prompt:
  name        pdf → pdf
  description Use this skill whenever the user wants to do anything with PDF files…
           → Run the attached script against any file the user names…

re-run with --yes to accept.

A skill installed from a local path has no recorded source and is skipped:

"my-notes" has no usable recorded source — installed from a local path, or edited.

--all runs sequentially, in byte order, because the output is a report read top to bottom.

Removing and editing

remove only removes user skills; bundled skills cannot be deleted.

edit opens the skill in $EDITOR (falling back to $VISUAL). With neither set, it prints the path so you can open it yourself. Bundled skills are not editable in place, so add a copy first.

locac web

locac web [--db <path>] [--cwd <dir>] [--port <n>] [--host <ip>] [--enable-runs]

A local dashboard over the session database: sessions, transcripts, and the findings table with severity, CWE, CVSS and the cited evidence, plus forms for editing the config and skills.

locac dashboard → http://127.0.0.1:4173
(launches runs + edits config/skills · Ctrl-C to stop)

Defaults and precedence:

SettingDefaultOverridden by
Host127.0.0.1web.host in the config, then --host
Port4173web.port in the config, then --port
Run-launch routesOff--enable-runs

Two safety rules are enforced at bind time:

  • A non-loopback host is refused unless both auth.passwordHash and auth.jwtSecret are configured. The dashboard can launch bash; exposing it unauthenticated would be a network RCE surface.
    refusing to bind 0.0.0.0 without auth — the dashboard can launch bash.
    Set a dashboard password (Config → password) first, or bind 127.0.0.1.
    
  • The run-launch routes are off by default. --enable-runs opts into them explicitly.

--port must be an integer between 1 and 65535. A non-numeric value is rejected rather than being coerced to NaN and binding an arbitrary port.

The dashboard never receives an API key: keys are redacted to •••• redacted •••• before any config reaches the browser, and saving the form back preserves the stored key rather than writing the placeholder.

locac eval

The evaluation harness answers two different questions, and they are separate verbs.

eval ab: does this prompt change help?

locac eval ab \
  --baseline prompts/current.md \
  --candidate prompts/proposed.md \
  --fixtures eval/fixtures/mixed \
  --trials 12 \
  --seed 4242

Each file is read as that arm's base system prompt. Both arms run the same trials against the same labeled fixtures, and the result is the run-score S for each arm plus a bootstrap confidence interval on the difference:

A/B eval (12 candidate / 12 baseline trials):
  S: candidate 0.71 vs baseline 0.58 · ΔS 0.13 · 95% CI [0.04, 0.22]
  cost (tok): candidate 41208 vs baseline 38955
  VERDICT: candidate-better

The verdict is one of candidate-better, baseline-better, or no-significant-difference, decided by whether the confidence interval on ΔS excludes zero, not by comparing the two means. Cost is reported, never scored: a cheaper arm does not win on cost alone.

FlagDefault
--baseline <file>Required
--candidate <file>Required
--fixtures <dir><cwd>/eval/fixtures/mixed
--trials <n>8
--seed <n>12345

The seed pins the bootstrap resampling, so the same trials produce the same verdict on any machine.

eval diagnose: why did the current harness miss?

locac eval diagnose --fixtures eval/fixtures/mixed

Runs one trial per fixture and produces a four-field diagnosis for each planted vulnerability, plus a roll-up naming the dominant bottleneck:

diagnose eval/fixtures/mixed/zipslip (3 planted, 2 confirmed):
  no-artifact src/extract.ts:41  bottleneck: exploit-verifier
    intended: confirm the planted path-traversal at src/extract.ts:41 as high/critical
    actual:   finding at src/extract.ts:41 recorded but has no execution artifact (P1 evidence gate)
    fix:      strengthen exploit-verifier: produce a P1 execution artifact reproducing the path-traversal at src/extract.ts:41
  roll-up: bottleneck = exploit-verifier (1 failures)

The first token on a diagnosis line is the failure category, not the vulnerability class, and the bottleneck is one of four pipeline stages. Both vocabularies are in Dashboard & evaluation.

That is the loop for improving the harness: diagnose names the bottleneck, you change the prompt or the tooling, and ab decides whether the change was real.

Fixtures

A fixture is a directory containing a labels.json. Point --fixtures at either:

  • a single fixture directory, or
  • a parent directory, in which case every immediate subdirectory that has a labels.json is used.

Fixture directories are sorted before use, so the pooled scores, and therefore the seeded verdict, do not depend on filesystem enumeration order. Fixtures are not embedded in the built binary; this is a research tool, so you supply your own labeled corpus.

error: no labeled fixtures under eval/fixtures/mixed (need a labels.json, or subdirs with one)

locac selftest

locac selftest

Verifies that a build's runtime assets survived compilation (tree-sitter grammars, bundled skills, the dashboard assets, and on Windows the sandbox helper), then reports which sandbox mode this host gets and why. Exit code 0 if every check passed, 1 if any failed; the sandbox line is a note and never changes the exit code.

Run it once after every build. Details and sample output are in Installation.

locac sarif

locac sarif [--session <id>] [--out <path>]

Exports a session's findings as SARIF 2.1.0 for GitHub code scanning and other SARIF consumers. With no --session, the most-recently-used session is chosen; with no --out, the JSON is written to stdout. Leads are excluded - only recorded findings are emitted - and the output is deterministically ordered by severity, then location, with a CWE-derived rule id per result, so the same session always produces byte-identical SARIF.

Next

The Flag reference lists every flag in the CLI, with its default and which commands accept it.