- Go 86.2%
- HTML 7.9%
- CSS 5.3%
- JavaScript 0.6%
|
|
||
|---|---|---|
| .github | ||
| cmd | ||
| docs | ||
| internal | ||
| templates | ||
| .DS_Store | ||
| .gitignore | ||
| go.mod | ||
| harbor-hub.service | ||
| hub.config.lob | ||
| README.md | ||
| setup.md | ||
| SKILL.md | ||
Harbor
Harbor is a workspace-first version control prototype.
Git is excellent at tracking file history, but large multi-component workspaces often need a higher-level view of the whole project. Harbor treats the workspace itself as the main unit of state. A snapshot captures the files, component graph, contracts, and enough operation history to inspect, undo, sync, and repair the workspace later.
Harbor is ready for careful dogfooding on real projects with backups. It is not production-ready yet.
What works today
Harbor currently supports:
- local repositories with
.harbor.dmetadata, - snapshots, logs, status, diffs, rollback, and undo,
- local branch refs,
- component manifests and dependency graphs,
- nested component workspaces for colocated multi-repo projects,
- compatibility contract metadata,
- filesystem and HTTP/HTTPS remotes with publish, fetch, sync, and clone,
- clone-time materialization filters for sparse workspaces,
- local ignore/include/exclude rules,
- object inspection,
- operation history,
doctorand conservative repair flows.
The portable HTTP remote contract for Harbor-compatible hubs lives in docs/harbor-hub.md.
Build it
You need Go 1.26.2 or newer.
go build -o bin/harbor ./cmd/harbor
go build -o bin/harbor-hub ./cmd/harbor-hub
Or run directly while developing:
go run ./cmd/harbor --help
go run ./cmd/harbor-hub --config hub.config.lob --check-config
Start a workspace
On the first interactive Harbor command, Harbor asks for your name and email if global identity config is missing. It saves them in harbor/config.lob under your OS user config directory and reuses that identity for snapshot authors. Non-interactive commands do not block for prompts; they keep using environment defaults.
From an existing project directory:
harbor init
harbor status
harbor snapshot "initial import"
harbor init creates .harbor.d and a root .harbor manifest. harbor snapshot records the current workspace as immutable objects and moves the current branch ref to that new workspace snapshot.
If you already have a tree on disk and want Harbor to accept it as the current state without writing a message, use:
harbor adopt
Harbor snapshots use portable defaults without extra config: regular file bytes are stored exactly as written, text files must use LF line endings, unsafe cross-platform path names are rejected, case-insensitive path collisions are rejected, symlinks are not snapshotted by default, and file permissions are normalized to ordinary file or executable file.
Daily local workflow
harbor status
harbor diff
harbor snapshot "change terrain loader"
harbor log
harbor oplog
status and diff compare the worktree to Harbor HEAD. log shows first-parent snapshot history. oplog shows operations such as snapshot, fetch, sync, rollback, undo, clone, repair, branch changes, and component updates.
If you make a mistake:
harbor rollback HEAD_OR_WORKSPACE_ID
harbor undo
rollback moves to a specific workspace snapshot. undo walks operation history and restores the previous effective workspace state for HEAD-changing operations.
Branches
harbor branch feature-a
harbor branch list
harbor branch switch feature-a
harbor branch delete feature-a
Branches are workspace refs. Switching branches requires a clean worktree and restores that branch's workspace snapshot and manifest graph.
Remotes
Filesystem remotes can publish and fetch:
harbor remote add origin /srv/harbor/my-project
harbor publish origin
harbor fetch origin
harbor sync origin
publish copies missing typed objects and updates the remote workspace ref. Incremental publish uses the current remote branch head as a boundary, so unchanged history and unchanged blobs are skipped when the remote can be read. Remote-backed nested component pins must already exist at their component source before the parent publishes; publish never silently publishes child workspace work for you. fetch copies objects and records a local remote ref without changing your worktree. sync fetches and materializes the remote workspace into a clean local worktree.
HTTP and HTTPS remotes use the same object/ref contract against Harbor-compatible hubs. Core Harbor does not depend on a server, and hub implementations should follow docs/harbor-hub.md; Harbor also provides an optional bundled hub server as a conforming implementation.
Harbor's object compatibility contract starts at the canonical payload: object IDs are always sha256(object-type || 0x00 || canonical-payload), never hashes of compressed or stored bytes.
Run a local hub
The bundled hub server lives in cmd/harbor-hub. It hosts the portable .harbor.d remote contract at /<owner>/<repo>/.harbor.d/..., serves external templates/assets loaded at startup, writes file-backed metadata under its configured data root, supports browser setup/login/registration/repository creation, real user/group owner profiles, configurable registration/RBAC gates, and username/PAT Basic auth for CLI clone/publish access. HTTPS is preferred for deployed hubs; plain HTTP is useful for local development.
The root example config uses templates/ as template root and templates/assets/ as replaceable asset root:
go run ./cmd/harbor-hub --config hub.config.lob --check-config
go run ./cmd/harbor-hub --config hub.config.lob
--check-config validates the Lobster config and prints resolved paths. Real serving loads templates/assets and creates storage directories. Flat mockup pages in templates/*.html are offline design files; live hub routes use stored users, groups, repositories, and hosted Harbor objects.
Clone
harbor clone /srv/harbor/my-project my-project
Clone initializes the target, restores origin, records the remote ref, materializes files, hydrates declared nested component workspaces from recorded pins, and writes a clone operation.
You can choose what materializes at clone time:
harbor clone --full SOURCE target
harbor clone --component engine SOURCE target
harbor clone --include src/ SOURCE target
harbor clone --exclude assets/raw/ SOURCE target
Those flags write local materialization rules, so the workspace stays clean even when some tracked files are intentionally absent.
Components
Harbor workspaces can describe components in the root .harbor manifest:
harbor component add \
--name engine \
--path engine \
--source /srv/harbor/engine \
--role library
harbor component add \
--name game \
--path game \
--source /srv/harbor/game \
--depends engine=compatible
harbor component list
harbor graph
harbor status reports pending manifest-only graph edits as manifest changed. Run harbor snapshot to record component graph changes even when tracked files are unchanged.
You can update one component from its source:
harbor update engine
Nested component workspaces keep a game-engine style tree together while still letting each component snapshot, publish, and sync independently:
game/
.harbor
engine/
.harbor
.harbor.d/
renderer/
.harbor
.harbor.d/
Declare a nested workspace component with the one extra marker:
harbor component add --name engine --path engine --source HUB_OR_PATH --workspace
That writes workspace = true in .harbor. If engine/.harbor.d already exists, component add and component link infer the marker. Parent snapshots do not capture the child's raw .harbor.d; they record the child's current workspace ID as a nested pin and overlay the child HEAD tree into the parent snapshot. Work child-first: cd engine && harbor snapshot ... && harbor publish, then cd .. && harbor snapshot ... && harbor publish. Parent clone/sync/rollback/branch switch recreate or update nested child workspaces from those pins.
Local-only nested links are useful while developing together:
harbor component link --name engine --path engine --local engine --workspace
They cannot be published from the parent until relinked to a remote source or absorbed. harbor component check reports nested state such as changed, dirty, unpublished, unreachable, or local-only. harbor doctor reports unmanaged nested Harbor workspaces and missing nested pin objects. Parent clean/materialization never deletes or rewrites child .harbor.d; dirty children must be snapshotted or cleaned inside the child first.
Contracts
Contracts are lightweight compatibility metadata attached to components:
harbor contract add \
--component engine \
--name api \
--compatibility v1
harbor contract add \
--component game \
--name game-api \
--compatibility v1 \
--requires engine=v1
harbor contract list
harbor contract validate
Current validation checks ownership, duplicate names, required components, compatible dependency edges, and required compatibility labels. Deep ABI/schema/effect validation is still future work.
Local materialization and ignore rules
The root .harbor manifest can keep local-only noise out of status/snapshot and can control sparse materialization:
[ignore]
patterns = ["build/", ".tmp/"]
[include]
patterns = ["engine/src/"]
[exclude]
patterns = ["assets/raw/"]
Ignore patterns affect local-only files. Include/exclude patterns affect which tracked remote paths should exist in the worktree. Harbor writes list rules as Lobster arrays; legacy newline multiline strings remain readable for existing workspaces.
Inspect and repair
harbor inspect HEAD
harbor inspect <object-id-or-prefix>
harbor doctor
harbor doctor --migrate-object-ids
harbor doctor --migrate-object-ids --repair
harbor doctor --repair
inspect prints deterministic summaries for Harbor objects. doctor checks layout, refs, configs, object hashes, object links, and operation history. Repair is conservative: it fixes cases Harbor can prove safe and refuses cases that would require guessing.
Additional docs
- VCS design:
docs/harbor.md - Hub setup and deployment:
setup.md - HTTP remote contract and bundled hub notes:
docs/harbor-hub.md - Lobster config format:
docs/lobster.md
Suggested dogfood rules
Use Harbor on real projects, but keep it boring:
- Keep a Git repo or backup beside the Harbor workspace.
- Start with filesystem remotes before relying on hosted remotes.
- Run
harbor statusbefore destructive-looking commands. - Prefer
harbor snapshot "message"after each logical change, or let Harbor summarize the diff when the message is obvious. - Run
harbor doctorafter sync, clone, and repair experiments.
Project status
Harbor is still a prototype. Its object model, CLI, and recovery story are in place enough to test the local VCS workflow end-to-end. The next big step is real-world feedback: try it on a real workspace, write down what feels awkward, and keep an eye on correctness, performance, and recovery behavior.