The extracted release archive is the install and your own git repository; every binary ships prebuilt, no Go or Rust needed.
What the quick start leaves out: components, ports, profiles, unattended installs, skill values, deployment, releases. Every setting: Settings; the installed server: Config server.
Get smine-<version>-darwin-arm64.tar.gz (Apple silicon) or -darwin-amd64 (Intel) from the latest release and extract it to any folder. It unpacks as smine/: the source tree plus every binary prebuilt under bin/ (bin/PAYLOAD carries the version).
The binaries are unsigned, and macOS marks everything it downloads as quarantined: Gatekeeper kills a quarantined unsigned binary on launch, the installer included. Clear the flag once before the first run; the installer clears it from the rest of the folder itself.
xattr -dr com.apple.quarantine smine
Needs git and nothing else. It asks for a preset (Minimal, Full, Custom), the components, the skills (all, none, or a numbered list of the repo's skills to toggle) and whether to keep that skill selection. A kept selection skips the skill question next install; -reset-skills or the Profile page's Installer tick asks again.
It checks only what the selection needs (a headless token for Routines or the Mining pipeline), shows every step and applies after your yes through bin/configserver -install, which also sets up git: safe.bareRepository explicit, the skillcue merge driver and the pre-commit hook.
cd smine && ./bin/installer
On macOS the server runs as LaunchAgent com.smine.configserver on :6001, logs in ~/Library/Logs/; on Linux the installer prints the start command. The first install prints the access token once, the browser's HTTP Basic password; only its SHA-256 digest is stored.
To rotate it, run the command below. The running server follows the file; an open page reloads and asks for the new token.
./bin/configserver -new-credential
Routines and the Mining pipeline need one thing, a token: the installer offers the one from claude setup-token, or add labeled per-account tokens on the Profile page (Account tokens, ~/.config/claude-routine/tokens/<label>) and pick one per routine in the Configure widget's Token setting. Operations manual: Routines.
The selection lives in ~/.claude/smine/install.json. Change it under Profile → Installation: Preview changes lists the steps, Apply selection stores the selection over the record and runs them.
Apply keeps every setting override and skill row. Unticking a component puts its dependents in suspended until it is ticked again. An unchanged selection re-runs whatever is missing.
Later re-deploys run from the Overview's Sync widget: settings, hooks or skills alone over the stored selection, or all of them (the whole installation apply).
| Command or flag | Does |
|---|---|
| ./bin/installer -components minimal -skills all -yes | Installs without asking. |
| -preview | Prints the steps, writes nothing. |
| -yes without -components | Keeps the stored selection; Minimal if none. |
| -reset-skills -yes | Only clears the kept skill selection. |
| -addr, -peek-port, -peek-control-port, -heartbeat-port | Ports, stored as settings in ~/.claude/smine/install.json (Multiple macOS profiles). |
./install.sh is the development path: it needs go (and cargo when agentwt or heartbeat is selected), runs the Go installer with go run and builds every binary from the checkout. The same flags apply. A checkout without bin/PAYLOAD is a development checkout: the apply engine and every later Sync build its binaries with go build there.
./install.sh
A one-shot bootstrap mines this machine's past sessions: the Welcome page's Bootstrap button, the /smine-bootstrap skill in a session, or bin/routine bootstrap (installed copy smine-routine bootstrap). Run it from the main checkout on main, with a clean tree and the smine peek entry in ~/.claude.json.
Needs BOOTSTRAP_TOKEN_FILE; optional BOOTSTRAP_SINCE=YYYY-MM-DD or BOOTSTRAP_N. BOOTSTRAP_DRY_RUN=1 prints the stage commands and runs nothing. Four stages:
| # | Stage |
|---|---|
| 1 | A headless claude cell runs /smine-style. |
| 2 | A second cell runs /smine --nightly, mining stages through consolidate. |
| 3 | A third cell runs /smine-orchestrate bootstrap. |
| 4 | Context packs deploy to the registered repos. |
The install dir is not connected to the GitHub repo; to push anywhere, add your own remote: git remote add origin <url>. Updates never run git, so commit local changes before updating.
Download it from the latest release and run it. The wizard lays the full source tree and prebuilt binaries into the chosen folder (default %USERPROFILE%\smine) and hands the rest to configserver.exe -install.
The setup exe is unsigned, so SmartScreen may warn on first run. Choose More info → Run anyway, or unblock it in PowerShell:
Unblock-File smine-setup.exe
The first install shows the config server's access token once in a message box (Ctrl+C copies it); the browser asks for it as the password.
Or restart the config server, so the routine runtime picks up the new PATH entry: %LOCALAPPDATA%\smine\bin with the smine-*.exe binaries, jq.exe, peek-mcp.exe and the claude shim.
A fresh folder becomes a standalone git repository with no remote. An existing install updates in place: commit local changes first, review the update with git status.
| Install path | Needs | Bundled or handled |
|---|---|---|
| smine-setup.exe | Git for Windows (the wizard offers winget), a Claude runtime. | No Go, no Rust. jq.exe, peek-mcp.exe, every smine binary (agentwt.exe and heartbeat.exe included), the bin\PAYLOAD marker and the repo files ship in the installer. |
| From source (install.ps1) | Git for Windows and Go, installed via winget after a consent prompt; cargo for agentwt and heartbeat. | Runs the Go installer (cmd/installer): builds the binaries, asks for the selection, delegates to configserver.exe -install. |
Run .\install.bat from the repo root: a thin launcher running install.ps1 under -ExecutionPolicy Bypass, since a PowerShell script cannot lift the default Restricted policy itself. install.ps1 passes every argument unchanged to the Go installer: -components, -skills, -yes, -preview, -addr, -peek-port, -peek-control-port, -heartbeat-port.
.\install.bat
The install logic both paths share:
Register-ScheduledTask needs an elevated token); the task itself runs at logon as your plain user.%LOCALAPPDATA%\smine\bin on your User PATH and copies the smine-*.exe binaries there.safe.bareRepository explicit, the skillcue merge driver and the pre-commit hook, as on macOS.install.json) and registers the logon tasks: the config server, and heartbeat when selected (\smine\com.smine.heartbeat, log %LOCALAPPDATA%\claude-routine\logs\heartbeat.log).Claude Desktop or the claude CLI (native installer or npm).
| Case | Result |
|---|---|
A claude visible from Git Bash | Wins. |
| None visible | The installer deploys a shim at %LOCALAPPDATA%\smine\bin\claude that re-resolves Claude Desktop's bundled claude.exe per call; Desktop updates need no re-install. |
| Neither found | A warning, not an error: the install completes; routines won't run until a runtime appears. |
| Routine token | install.ps1 offers the routine OAuth token once when Routines or the Mining pipeline is selected; setup.exe prints a note instead. Skipped: routines exit 78 until a token exists. |
Git Bash is the one Git for Windows supplies; no WSL. The server, the routine wrapper and the heartbeat daemon run fully detached (windowsgui subsystem): no console window, no Quick-Edit freezes.
| Log in %LOCALAPPDATA%\claude-routine\logs\ | Holds |
|---|---|
| configserver.log | The config server. |
| heartbeat.log | The heartbeat daemon (--log-file). |
| <routine label>.out.log, <routine label>.err.log | One routine. |
Follow a log live with Get-Content <log> -Wait.
As on macOS: no connection to the GitHub repo; add your own remote with git remote add origin <url>, and commit local changes before updating.
All user profiles share the machine's loopback port space, so each install needs its own four ports.
The second profile's config server finds the first's peek on the shared port and refuses it: the log names the foreign homes, and the session column stays disabled rather than show another user's sessions. The second heartbeat cannot bind; its sessions' hooks reach the first profile's daemon, which rejects them as a foreign claude home and marks its own hooks sensor degraded.
Install each profile with explicit ports:
./bin/installer -addr 127.0.0.1:6002 -peek-port 4243 -peek-control-port 42443 -heartbeat-port 6102
| Setting | Default | Flag | What listens |
|---|---|---|---|
| config-server.port | 6001 | -addr | The config server. |
| peek.port | 4242 | -peek-port | The central peek MCP server; heartbeat's peek address follows it. |
| peek.control_port | 42442 | -peek-control-port | peek's control dashboard and OTLP telemetry receiver. |
| heartbeat.port | 6101 | -heartbeat-port | The heartbeat daemon. |
The ports are install-record settings, so plain re-runs and a Profile apply keep them. peek.control_port also fills {{PEEK_CONTROL_PORT}} in the settings template, so each profile's Claude Code exports telemetry to its own peek. peek.claude_home and peek.codex_home point the spawned peek at non-default agent homes.
~/.claude/smine/install.json holds only overrides, under settings; every other value is the catalog default. Schema 2: an older schema is refused, never imported.
| Setting | Meaning |
|---|---|
| config-server.port, peek.port, peek.control_port, heartbeat.port | This install's ports (-addr, -peek-port, -peek-control-port, -heartbeat-port). |
| config-server.init_welcome, routines.count_tokens | Installer flags. |
| peek.claude_home, peek.codex_home, config-server.server_path | Optional; empty takes the default home or the installer's PATH. |
Change a setting on the config server's Smine tab or with smine-rules settings set <component>.<key> <value>. Kind, default and help per setting: Settings.
The record's skills object holds the skill rows.
| Row | Maps | Holds |
|---|---|---|
| skills.variables | SKILL_<SKILL>_<KEY> → value | Install-wide default of a repo-scoped variable, or pinned value of an install-scoped one (Skill model § Interfaces and environment). |
| skills.providers | PROVIDER_<ID> → program | A row per provider whose program this install overrides, e.g. PROVIDER_SMINE_RULES. |
| skills.defaults | interface id → value | Global default of a repo-scoped kind (Per-repo values). |
The skills sync fills each install-scoped capability into the skill's deployed copy; the first source with a value wins.
| # | Source | Detail |
|---|---|---|
| 1 | Process environment variable named like the row | Overrides the row for every deploy that process runs; a long-running config server keeps its launch environment. |
| 2 | The record's SKILL_* row | That one capability of that one skill. |
| 3 | PROVIDER_* environment variable or row | Moves every capability of the provider's program at once. A provider implements the capability's interface in skills/interfaces.cue. |
| 4 | Catalog program of an installed component | smine-rules, smine-agentwt, smine-heartbeat, smine-routine, toolpolicy: bare names on PATH, copied into the smine bin dir on every platform (~/go/bin, %LOCALAPPDATA%\smine\bin as smine-<name>.exe on Windows). The routine runner and bootstrap prepend that dir to the scheduler's minimal PATH; the container image sets it. |
The deploy asks each provider <program> interfaces once per run. A capability stays unset when the answer lacks its interface version, the program does not resolve, a path does not exist or the value breaks the value rules; the deploy log and the skill page name the cause.
The skill page's Environment section edits the defaults and, in its advanced disclosure, the provider and capability overrides; it refuses a bad value. A row no skill or provider declares stays, listed as an orphan with a Forget button; configserver -install prints orphan row kept: <key>.
Command and path capabilities, and acdsl, have no provider program and are repo-scoped. Their SKILL_* row is only the default for repos that set nothing on the skill's page. A multi-line command keeps its line breaks in the record.
SKILL_FIMPLEMENT_CHECK="make audit" SKILL_FIMPLEMENT_BUILD="go build ./..." SKILL_PACKAGECOMMIT_PROJECT_STRIP="bin/acdsl"
bin/acdsl is each ACDSL (Context Linting) repo's own copy, never a PATH program. A vendoring repo tracks it; a repo holding the acdsl source (cmd/acdsl, this checkout) gets it built by the worktree hook on worktree creation and after a base move.
A repo-scoped value fills at invocation, never at deploy: the deployed SKILL.md reads SKILL_<SKILL>_<KEY> from the session's environment. An unset required one aborts the invocation with a sentence naming the variable, an example and the fix.
| Level | Set on | Stored in |
|---|---|---|
| Repo value | A repo chip in the skill page's Environment section (same widget on the Skills Environment tab), commands one per line. | The env map of the repo's row in ~/.claude/smine/repos.json. Nothing goes into the repository; a save needs no deploy. |
| Skill default | The same section's default view. | skills.variables |
| Global default | The Environment tab's global defaults card: one value per kind a selected skill reads (test, build, check, lint, the acdsl programs, the plans archive). | skills.defaults, keyed by interface id, for every skill on every repo. |
Per variable the strongest set value wins: repo value, else skill default, else global default. Example: railroad-review's build and test commands are the repo's SKILL_RAILROADREVIEW_BUILD and _TEST values on its skill page.
The skillenv hook belongs to the Skill environment component, its own row under Session hooks; without that component it is off. Two modes:
| Event | What it does |
|---|---|
| SessionStart, CwdChanged | Resolves the session's main checkout to its registry row and appends export SKILL_…='…' lines to the harness's CLAUDE_ENV_FILE: the resolved repo-scoped values plus the record's install-scoped SKILL_ rows. An unregistered repo gets the defaults alone. |
A typed /<skill> (UserPromptExpansion), the agent's Skill call (PreToolUse) | Reads the deployed skill's env.json, the repo values its body reads. An unset required one blocks the command or denies the call, so the body never expands and its guard never runs. The reason names the variable, its purpose, an example, the repo's skill page link, a hint to start a new session after setting it, and the #disable inject:env way out. Otherwise one context line per value. |
skillenv: <NAME> = "<value>" (<source>) skillenv: <NAME> not set — optional, its steps are left out
-repos names the registry, -env-file overrides the target file, -claude-home the Claude home. #disable inject:env turns both modes off for a session. Without the hook (a standalone skill, a bundle user, a session with #disable inject:env) the shell's own exports reach the skill the same way.
Deployment runs one way: the repo is the source of truth, nothing is read in place.
| Source | Target | Written by |
|---|---|---|
| skills/ | ~/.claude/skills/ and ~/.codex/skills/, one dir per skill and per alias | the skills sync |
| skills/**/agents/*.md | ~/.claude/agents/ | the skills sync |
| install.json skills.variables | install-scoped values in ~/.claude/skills/ | the skills sync |
| settings/claude_code/base.json + components/*.json | ~/.claude/settings.json and ~/.claude.json (mcpServers) | configserver -apply |
| cmd/<name>/ (14 Go hook binaries) | ~/.claude/hooks/bin/ | configserver -apply |
| cmd/rules, cmd/agentwt, cmd/heartbeat, cmd/routine | The smine bin dir: ~/go/bin/smine-*, %LOCALAPPDATA%\smine\bin\smine-*.exe on Windows | configserver -apply, per selected component |
| settings/codex/config.toml | ~/.codex/config.toml | configserver -apply |
| context/ | AGENTS.md and the context dirs of the target project repos | configserver /context/sync |
Applies the stored selection (~/.claude/smine/install.json) through internal/install, per component: hook binaries, PATH binaries, settings entries, MCP registration, Codex config, LaunchAgents or logon tasks, routines. A release archive (bin/PAYLOAD present) copies the prebuilt binaries; a development checkout builds them with go build.
| Part | Rule |
|---|---|
| Hook binaries | toolpolicy, skillhelp, worktreecreate, sessiontitle, readgate, globalcontext, skillcontext, planmodecontext, acdslhook, skillinvokegate, worktreewriteguard, skillenv, playsound (the sound hook: afplay on macOS, PlaySoundW on Windows), heartbeatfeed (posts SessionStart to the daemon, no curl). |
| Settings entries | From settings/claude_code/base.json plus components/*.json, own entries only; base keys added only where absent. |
| Hook groups | Matched by smineId; replaced when its semantic smineVersion exceeds the live one (a legacy integer counts as its major release). An unselected component's groups park in hooks.disabled.json with smineReason. Only the repo's retire list (settings/claude_code/retired-hooks.json) removes a group. |
| Owned files | ~/.codex/config.toml and every copied file are rewritten only while unchanged since smine wrote them. |
| Trash | Every overwritten or removed file keeps its previous bytes in ~/.claude/smine/trash/, shown on the config server's Trash page. |
The Go skills sync (internal/skills, also run in process by the config server) writes skills to ~/.claude/skills/ and ~/.codex/skills/, agent definitions to ~/.claude/agents/.
| Part | Rule |
|---|---|
| Selection | Like the install engine, renders the selected skills for the record's component set and skill rows (skills.variables, skills.providers, skills.defaults). Skipped unavailable: a skill whose requires the set misses. Skipped unconfigured: one with an unset required install-scoped variable. |
| Repo-scoped variables | In ~/.claude/skills: invocation placeholders (Per-repo values). In ~/.codex/skills: filled from the deploy environment, the record row, the global default (skills.defaults), then the provider. |
| Rendered files | SKILL.md, help-test.md, title.json, enforce.json, env.json, answer.md, rendered in process from the model file <leaf>.cue beside the .smine-deployed marker. env.json needs the Skill environment component and a body reading a repo value; ~/.claude/skills only. |
| Filled variables | Install-scoped ones, in SKILL.md, every copied sibling text file (workflows/, schemas/, context-map.json) and the agents/ files. |
| Never shipped | <leaf>.cue, payloads/, eval/, smoke/. |
| Pruning | Skills gone from the repo are kept and listed. -sync-prune, and every sync the install engine or the config server runs, moves marked dirs outside the selection into the trash. |
| Foreign dirs | An unmarked or locally modified dir under a deployed name is stashed whole before the write. |
internal/contextdocs runs from the Context page's sync form and is replayed by routine bootstrap. It builds one overlay per registered repo under ~/.claude/smine/context/<name>/.
| File | Holds |
|---|---|
| context.json | The source index cut by each entry's Reach: and its scope's language binding, a deploy record first. The repo's own entries (files under its context folder without the synced header) are merged in. |
| aspects.json | The aspects file, beside it. |
| overlay.patch | Adds both files under the context folder; git apply-able, passed by reviews and evals as overlay-patch:. |
Only the form's Write to Repo box writes into the repository's working tree; nothing is ever committed. It writes the two files. "project markdown" adds the expanded AGENTS.md, the actions chapters, the rules guides and the facts files, and removes a leftover CLAUDE.md -> AGENTS.md symlink. "sync acdsl" adds the reach-covered gate slice via acdsl.Dist: rules, registry subset, policy, prebuilt bin/acdsl and verifier binaries.
| Case | Result |
|---|---|
| A repo-owned file under a baseline name | Aborts the run. |
| A repo-owned entry that fails validation | Aborts the run. |
| A rewritten baseline file | Previous bytes kept in the trash. |
| The always pack | Refreshed by every sync: rewritten only when its content changed, the previous pack stashed. A pack file without the smine header is kept, with an error. |
Tagged releases (v*.*.*) run through GitHub Actions (.github/workflows/ci.yml). Every push runs test, test-windows, audit, darwin-payload, windows-payload and installer; on a tag, publish waits for test, darwin-payload and installer and attaches every asset in one shot.
One payload, built by make payload-bin GOOS=<os> GOARCH=<arch> VERSION=x.y.z for every platform: configserver, routine, acdsl, rules, installer, every verifier binary, the fourteen hook binaries and the bin/PAYLOAD marker holding the version. The marker is what makes an extracted archive take its binaries from bin/ instead of building them.
| Platform | Release assets |
|---|---|
| darwin | smine-<version>-darwin-arm64.tar.gz and -darwin-amd64.tar.gz: the source tree at the tag as smine/ with the payload plus agentwt and heartbeat (make payload-rust, cargo cross targets) under smine/bin/. A macOS job builds one per arch; make payload GOOS=darwin GOARCH=arm64 VERSION=x.y.z is the same build locally into dist/. |
| windows |
A linux job cross-builds the windows payload ( A windows job then builds |
Every payload job, and go build ./... on a windows runner, runs on every push and pull request (version 0.0.0 off-tag), so a broken archive, installer script or *_windows.go file fails CI before a tag exists. make installer-check is the Inno Setup compile locally, against a dummy payload via a dockerized iscc.