Documentation
¶
Overview ¶
Package install wires a vault into the machine: it writes the per-vault contracts (.hebb/config.toml, the project-scoped .mcp.json), symlinks global skills and memory, and renders launchd jobs. Every operation is idempotent and parameterised by its target directories so it is fully testable and never hard-codes a home directory.
Index ¶
- Constants
- func AnyFailed(checks []Check) bool
- func AnyRemoved(r TeardownReport) bool
- func AssetName(version, goos, goarch string) string
- func BinaryFromArchive(targz []byte) ([]byte, error)
- func Bootout(label string)
- func Bootstrap(plistPaths []string, run bool) ([]string, error)
- func ClaudeProjectSlug(absPath string) string
- func DefaultClaudeDesktopConfigPath(home string) string
- func MCPToolNames() []string
- func MaterializeAssets(fsys fs.FS, dataDir string) (int, error)
- func MemoryDir(vaultPath string) string
- func NewerAvailable(current, latest string) bool
- func ParseVersion(s string) (maj, min, patch int, ok bool)
- func RemoveClaudeDesktopConfig(configPath, name string) (string, error)
- func RemoveCodexConfig(configPath, name string) (string, error)
- func RenderCodexServer(name, command, vaultPath string) string
- func RenderMCPJSON(serverName, command string) ([]byte, error)
- func ReplaceBinary(path string, data []byte) error
- func Slugify(s string) string
- func SymlinkMemory(vaultPath, claudeProjectsDir, projectSlug string) (string, error)
- func VaultJobs(vaultPath, slug, hebbBin, assetRoot, home string, port int, names []string, ...) []launchd.Job
- func VerifyChecksum(data []byte, checksums, assetName string) error
- func WriteClaudeDesktopConfig(configPath, name, command, vaultPath string) (string, error)
- func WriteCodexConfig(configPath, name, command, vaultPath string) (string, error)
- func WriteMCPJSON(vaultPath, serverName, command string) (bool, error)
- func WriteProjectSettings(vaultPath, serverName string) (bool, error)
- type Check
- type InstallMethod
- type Options
- type Report
- type Step
- type TeardownOptions
- type TeardownReport
- type TeardownStep
- type Updater
Constants ¶
const DefaultCodexStartupTimeoutSec = 20
DefaultCodexStartupTimeoutSec gives the pure-Go SQLite index time to open on a cold first run, above Codex's 10s default.
const DefaultMCPCommand = "hebb"
DefaultMCPCommand is the binary Claude launches for the MCP server. It is a bare name resolved on PATH (brew/npm install) rather than an absolute path, so the committed .mcp.json travels with a synced vault.
const DefaultMCPServerName = "hebb"
DefaultMCPServerName is the server key written into .mcp.json (and so the tool prefix Claude sees, e.g. mcp__hebb__search_vault).
const DefaultRepo = "cizer/hebb"
DefaultRepo is the GitHub repo hebb releases come from.
Variables ¶
This section is empty.
Functions ¶
func AnyRemoved ¶
func AnyRemoved(r TeardownReport) bool
AnyRemoved reports whether the report contains an action that removed (or would remove) something - useful for exit codes / messaging.
func AssetName ¶
AssetName is the release asset for a version/platform, matching GoReleaser and install.sh (e.g. hebb_0.1.1_darwin_arm64.tar.gz).
func BinaryFromArchive ¶
BinaryFromArchive extracts the file named "hebb" from a .tar.gz release asset.
func Bootout ¶
func Bootout(label string)
Bootout unloads a launchd job from the user's domain, best-effort: a job that is not loaded (or a machine without launchctl, e.g. Linux/CI) is fine.
func Bootstrap ¶
Bootstrap (re)loads the given plists into the user's launchd domain. When run is false it returns the commands it would execute without running them, so an install can preview the bootstrap. A failed bootout (the job was not loaded) is ignored; only bootstrap failures are returned as errors.
func ClaudeProjectSlug ¶
ClaudeProjectSlug reproduces Claude Code's per-project directory naming: every non-alphanumeric character in the absolute path becomes '-', with case preserved and no collapsing. So /Users/a.b/v becomes -Users-a-b-v.
func DefaultClaudeDesktopConfigPath ¶
DefaultClaudeDesktopConfigPath is the macOS location of the Claude Desktop config under the given home dir.
func MCPToolNames ¶
func MCPToolNames() []string
MCPToolNames are the tools the hebb MCP server exposes. They must match the tool names registered in package mcp.
func MaterializeAssets ¶
MaterializeAssets writes the embedded function assets (fsys) onto disk under dataDir, preserving the tree. It is idempotent (unchanged files are skipped) and returns the number of files written or updated. Files under automation/ are made executable, since go:embed does not preserve the executable bit.
func MemoryDir ¶
MemoryDir is the in-vault home for this vault's Claude Code memory. It lives under .hebb so agent memory still syncs and travels with the vault, but is hidden from Obsidian (a dotfolder) and excluded from the index (.hebb is in the default exclude list), so memory is never treated as vault content.
func NewerAvailable ¶
NewerAvailable reports whether latest is a strictly higher release than current. A dev build (version containing "dev") or any unparseable version returns false, so a dev binary is never auto-replaced by a release.
func ParseVersion ¶
ParseVersion parses vMAJOR.MINOR.PATCH (leading v optional; any pre-release or build suffix is ignored). ok is false for non-release strings (e.g. a dev build like "0.0.0-dev (abc123)"), so callers can refuse to compare them.
func RemoveClaudeDesktopConfig ¶
RemoveClaudeDesktopConfig deletes the mcpServers.<name> entry, preserving every other server and key. Returns "removed" or "absent".
func RemoveCodexConfig ¶
RemoveCodexConfig deletes the [mcp_servers.<name>] block from the Codex config at configPath, preserving every other server, comment, and key. Returns "removed" if a block was deleted, or "absent" if there was no config or no matching block. The inverse of WriteCodexConfig, used by `hebb reset`.
func RenderCodexServer ¶
RenderCodexServer returns the TOML block for a [mcp_servers.<name>] stdio entry pinned to vaultPath. env is an inline table so the whole entry is one contiguous block (no trailing sub-table a merge could orphan).
func RenderMCPJSON ¶
RenderMCPJSON returns the canonical project-scoped .mcp.json for a vault. args is just ["mcp"]: hebb resolves the vault from the directory it is launched in (the vault root, where this file lives), keeping the committed file free of machine-specific absolute paths.
func ReplaceBinary ¶
ReplaceBinary atomically replaces the file at path with data: it writes a temp file in the same directory, makes it executable, and renames it over the target. Replacing the path of a running binary is safe on Unix (the running process keeps the old inode).
func Slugify ¶
Slugify turns a vault name into a label-safe token (lowercase, alphanumerics and single hyphens), used in launchd labels and the memory symlink path.
func SymlinkMemory ¶
SymlinkMemory links <vault>/.hebb/memory into <claudeProjectsDir>/<projectSlug>/memory so Claude Code reads the vault's (synced) memory when opened there. The vault memory dir is created if absent. It is defensive: an existing real memory dir at the target is left untouched (status "conflict").
func VaultJobs ¶
func VaultJobs(vaultPath, slug, hebbBin, assetRoot, home string, port int, names []string, updateAuto bool) []launchd.Job
VaultJobs builds launchd job specs for the named jobs of a vault. The web and update-check jobs are built in (they run the hebb binary). The daily-digest and action-review jobs are only included when their script exists under <assetRoot>/automation, so no broken plists are written if the automation scripts are absent. updateAuto makes the update-check job install updates rather than only reporting them. Unknown names are skipped.
func VerifyChecksum ¶
VerifyChecksum checks the sha256 of data against the entry for assetName in a GoReleaser checksums.txt body (lines of "<hex> <name>").
func WriteClaudeDesktopConfig ¶
WriteClaudeDesktopConfig merges an mcpServers.<name> entry (pinned to vaultPath via HEBB_VAULT) into the Claude Desktop config, creating it if absent. Other servers and top-level keys are preserved. Idempotent; returns "wrote", "updated", or "unchanged".
func WriteCodexConfig ¶
WriteCodexConfig merges the hebb server block into the Codex config at configPath, creating the file (and parent dir) if absent. It is idempotent and non-destructive. Returns "created", "updated", or "unchanged".
func WriteMCPJSON ¶
WriteMCPJSON writes .mcp.json at the vault root, idempotently. It returns true if the file was created or its contents changed.
func WriteProjectSettings ¶
WriteProjectSettings merges hebb's MCP wiring into <vault>/.claude/settings.json: it enables the project-scoped MCP server and pre-approves its tools so the agent is not prompted for each call. Any existing settings are preserved; only the relevant arrays are extended. Returns true if the file was created or changed.
Types ¶
type InstallMethod ¶
type InstallMethod int
InstallMethod is how the running binary was installed, which decides whether `hebb update` may self-replace it.
const ( SelfManaged InstallMethod = iota // hebb owns the binary (e.g. install.sh) Homebrew // managed by `brew upgrade` GoInstall // managed by `go install ...@latest` )
func DetectInstallMethod ¶
func DetectInstallMethod(exePath string) InstallMethod
DetectInstallMethod classifies the binary at exePath (symlinks resolved).
func (InstallMethod) AdviseCommand ¶
func (m InstallMethod) AdviseCommand() string
AdviseCommand returns the command a user should run to update a binary hebb does not own, or "" when hebb may self-replace.
func (InstallMethod) String ¶
func (m InstallMethod) String() string
type Options ¶
type Options struct {
VaultPath string
MCPName string
MCPCommand string
Home string // base dir containing .claude (e.g. ~); "" disables memory wiring
HebbBin string // path to the hebb binary, for the web launchd job
LaunchdDir string // target LaunchAgents dir; "" disables launchd rendering
Load bool // if true, bootstrap rendered jobs via launchctl
MCPJSON bool // if true, write a per-vault .mcp.json + settings (plugin-less wiring)
// Asset source. The binary is standalone: Assets carries the embedded
// function content (automation/, vault-template/), materialised to DataDir on
// install so launchd jobs can find their scripts. AssetRoot is a development
// override - point it at a repo checkout to use its automation/ straight from
// source and skip materialisation.
Assets fs.FS
DataDir string
AssetRoot string
}
Options configures an install run. Directory fields are explicit so install is fully testable and never hard-codes a home directory. An empty Home disables the home-side wiring (vault-local steps still run).
type Report ¶
type Report struct {
Steps []Step
}
Report is the ordered list of actions an install performed.
func Run ¶
Run performs the file-level install for a vault and returns a report of every action. It does not build the index (the caller owns the engine/db). Steps:
- vault config: .hebb/config.toml (always)
- plugin-less wiring (if MCPJSON): .mcp.json + <vault>/.claude/settings.json (the hebb plugin normally provides the MCP server instead)
- assets: materialise embedded automation scripts to DataDir (unless --asset-root points at a live repo checkout), for launchd jobs
- memory (if Home): symlink <vault>/.hebb/memory into the Claude project dir
- launchd (if requested): render the vault's jobs
Skills are delivered by the hebb Claude Code plugin (see plugin/), not by install. Every step is idempotent.
func Scaffold ¶
Scaffold materialises the vault template tree (tmpl) into vaultPath, creating the directory if needed. It is defensive: it refuses to scaffold into a directory that already has contents, so it never clobbers an existing vault. An absent or empty target is fine. Returns a report of the action.
tmpl is the template filesystem rooted at its contents (e.g. the embedded assets sub-FS for "vault-template", or os.DirFS of a checkout's vault-template/). The per-vault contracts (.hebb/config.toml, .mcp.json) are not part of the template; install writes those afterwards.
func VaultLocal ¶
VaultLocal initialises the per-vault config (.hebb/config.toml, created with defaults if absent, never clobbered). It is idempotent. The project-scoped .mcp.json is written separately and only on request (Options.MCPJSON): the hebb plugin normally provides the MCP server.
type Step ¶
type Step struct {
Name string
Status string // created | exists | wrote | unchanged | symlinked | loaded ...
}
Step records the outcome of one install action for reporting.
type TeardownOptions ¶
type TeardownOptions struct {
VaultPath string
Home string // base dir holding .claude; "" disables the memory step
LaunchdDir string // "" -> <home>/Library/LaunchAgents
CodexConfig string // "" -> <home>/.codex/config.toml
DesktopConfig string // "" -> the macOS Claude Desktop config under Home
MCPName string // server/block name (default "hebb")
Force bool // false = dry run
KeepIndex bool // default false -> clear .hebb/index.db (cheap to rebuild)
}
TeardownOptions configures `hebb reset`: un-wire a vault from this machine. Directory fields are explicit so it is hermetically testable. Force=false is a dry run (report only, mutate nothing).
type TeardownReport ¶
type TeardownReport struct {
Forced bool
Steps []TeardownStep
}
TeardownReport is the outcome of Teardown.
func Teardown ¶
func Teardown(opts TeardownOptions) (TeardownReport, error)
Teardown removes only the machine-side wiring `hebb install` created. It NEVER touches vault content: markdown notes, .hebb/memory, and .hebb/config.toml are always left intact. Steps (each tolerant of being absent):
- memory symlink in <home>/.claude/projects/<slug>/memory (the link only)
- launchd plists local.hebb.<slug>.* (+ best-effort bootout)
- the [mcp_servers.<name>] block in ~/.codex/config.toml
- the opt-in per-vault .mcp.json (only if hebb-generated) and the hebb entry in <vault>/.claude/settings.json
- .hebb/index.db (derived; unless KeepIndex)
type TeardownStep ¶
type TeardownStep struct {
Target string // what
Status string // "removed" | "would remove" | "absent" | "skipped: <why>"
}
TeardownStep is one action in the teardown plan/report.
type Updater ¶
type Updater struct {
Repo string
APIBase string // default https://api.github.com
DownloadBase string // default https://github.com
HTTP *http.Client
UseGH bool
}
Updater fetches release metadata and assets. URLs are fields so tests can point them at a local server; defaults target GitHub. When UseGH is set and the gh CLI is available and authed, it is used (works for a private repo), mirroring install.sh.
func NewUpdater ¶
func NewUpdater() Updater
NewUpdater returns an Updater with GitHub defaults and gh enabled.
func (Updater) DownloadBinary ¶
DownloadBinary fetches the asset and checksums for tag/platform, verifies the checksum, and returns the extracted hebb binary.