{"id":41805587,"url":"https://github.com/danieljhkim/monodev","last_synced_at":"2026-03-07T20:11:40.294Z","repository":{"id":334492932,"uuid":"1141603486","full_name":"danieljhkim/monodev","owner":"danieljhkim","description":"CLI for managing reusable dev overlays (agent instructions, dev scripts, editor config) across different sessions and branches without polluting git.","archived":false,"fork":false,"pushed_at":"2026-02-28T21:10:32.000Z","size":759,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T23:37:31.695Z","etag":null,"topics":["cli","developer-experience","developer-tools","golang","local-development","monorepo"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danieljhkim.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-25T04:41:24.000Z","updated_at":"2026-02-28T21:10:35.000Z","dependencies_parsed_at":"2026-02-07T05:03:06.633Z","dependency_job_id":null,"html_url":"https://github.com/danieljhkim/monodev","commit_stats":null,"previous_names":["danieljhkim/monodev"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/danieljhkim/monodev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljhkim%2Fmonodev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljhkim%2Fmonodev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljhkim%2Fmonodev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljhkim%2Fmonodev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danieljhkim","download_url":"https://codeload.github.com/danieljhkim/monodev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljhkim%2Fmonodev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30229592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","developer-experience","developer-tools","golang","local-development","monorepo"],"created_at":"2026-01-25T06:15:37.378Z","updated_at":"2026-03-07T20:11:40.270Z","avatar_url":"https://github.com/danieljhkim.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# monodev\n\nMost codebases suffer from \"local file drift.\" We generate debug scripts, AI scratchpads (.cursorrules, .claude, etc.), and task notes that live alongside our code but don't belong in the repo. These files are either accidentally committed (clutter) or deleted too soon (lost knowledge).\n\n`monodev` introduces a third space: **Local-First Overlays**. It keeps your dev-only artifacts persistent and portable without ever leaking them into your Git history.\n\nThe Monodev Way:\n- **Invisible**: Keeps \"git status\" clean.\n- **Persistent**: Your notes, scripts, and agent files survive branch switches.\n- **Portable**: Push/Pull your local state via hidden orphan branches.\n\n---\n\n## Quick Start\n\nPlatform support: macOS (Apple Silicon only)\n\n```bash\n# 1. Install\nbrew install danieljhkim/tap/monodev\n\n# 2. Create your first store and track a file\nmonodev checkout -n my-debug-tools\nmonodev track debug_helper.py\nmonodev commit --all\n\n# 3. Remove the overlay after done working\nmonodev unapply\n\n# 4. Reapply again later when needed\nmonodev apply\n\nmonodev help\n```\n\n![monodev preview](docs/assets/cli_preview.png)\n\n---\n\n## Core ideas\n\n### **Stores**\nA **store** is a named, reusable snapshot of **dev-only files** (editor config, scripts, agent instructions, Makefiles, etc.).\n\n- A store defines *what* files are overlaid and their contents\n- Stored at: `~/.monodev/stores/\u003cstore-id\u003e/`\n\nYou can think of a store as a portable bundle of development artifacts that can be applied across multiple components or sessions.\n\n### **Workspaces**\nA **workspace** represents a specific directory within a repository where overlays are applied.\n\n- Each workspace tracks:\n  - the active store\n  - which stores are currently applied\n- Workspace IDs are derived from:\n  - the repository fingerprint (hashed git remote URL)\n  - the relative path within the repo\n- Stored at: `.monodev/workspaces/\u003cworkspace-id\u003e.json`\n\n\u003e **In short:** stores define *what* dev artifacts exist, and workspaces define *where* and *when* they are applied.\n\n---\n\n## Basic workflow\n\n### Basic create, track, commit \u0026 apply:\n\n```bash\n# create and check out a store (similar to `git checkout` but doesn't apply overlays yet)\n# this also sets the store as \"active store\" for the current directory\nmonodev checkout -n my-component-store \n\n# track dev-only files for the \"active store\" (similar to `git add`)\nmonodev track Makefile .cursor scripts/dev .claude .vscode\n\n# check status of the current workspace\nmonodev status\n\n# persist the tracked files to the store (similar to `git commit`)\nmonodev commit --all\n\n# check for modified tracked files\nmonodev diff\n# if you want to commit the changes, you can do:\nmonodev commit --all\n\n# removes the \"active store\" overlays from the current directory\nmonodev unapply\n\n# later, in another component directory:\nmonodev checkout my-component-store\nmonodev apply # this will add those artifacts to the current dir\nmonodev unapply # this will remove the overlays from the current dir\n```\n\n### How it works\n\nWhen you invoke `monodev checkout \u003cstore-id\u003e` under a specific directory within a repo, a workspace file is created in `.monodev/workspaces/\u003cworkspace-id\u003e.json`. This file contains the metadata for the workspace, including the active store, the applied stores, and the tracked paths.\n\nThe `workspace-id` is derived from the repo fingerprint (hashed git remote URL + absolute path) and the relative path to the workspace. So when you cd into to a different directory, you will not have an \"active store\" for that directory. And when you cd back to the original component directory, the active store is restored. \n\nWhen you invoke `monodev apply` with the active store, the overlays are applied to the current directory. This is done by creating copies of the tracked paths to the current directory.\n\nYou can use `monodev status` to see the current workspace status and applied overlays.\n\n![monodev status](docs/assets/monodev_status.png)\n\n---\n\n## Commands\n\n### Core commands\n\nThese are the core commands you will use most often. You can still apply multiple store overlays using these commands multiple times. \n\nWhen there are conflicts (i.e. multiple stores claim the same path), you can use `--force` to override them. When conflicts are overridden, your latest actions (unapply, apply) will take precedence.\n\n```bash\n# this shows the current workspace status and applied overlays\nmonodev status\n\n# this lists all available stores\nmonodev store ls\n\n# this shows the detailed metadata and tracked paths for a store\nmonodev store describe \u003cstore-id\u003e\n\n# this deletes a store and all its overlay artifacts\nmonodev store rm \u003cstore-id\u003e\n\n# this sets the active store (store must already exist)\nmonodev checkout \u003cstore-id\u003e\n\n# this creates a new store and sets it as the active store\nmonodev checkout -n \u003cstore-id\u003e [--scope global|component] [--description \"some details\"]\n\n# this tracks a path in the active store (.monodev/\u003cstore-id\u003e/track.json is updated)\nmonodev track \u003cpath\u003e\n\n# this untracks a path in the active store (.monodev/\u003cstore-id\u003e/track.json is updated)\nmonodev untrack \u003cpath\u003e\n\n# persist the tracked paths in the active store (.monodev/\u003cstore-id\u003e/overlay is updated)\nmonodev commit \u003cpath\u003e\n\n# persist all tracked paths in the active store\nmonodev commit --all\n\n# this applies the \"active store's\" overlays to the current workspace\nmonodev apply [--force] [--dry-run]\n\n# this removes the \"active store's\" applied overlays from the current workspace\nmonodev unapply [--force] [--dry-run]\n\n```\n\n### Workspace management\n\n```bash\n# list all workspaces\nmonodev workspace ls\n\n# show detailed information about a workspace\nmonodev workspace describe \u003cworkspace-id\u003e\n\n# delete a workspace\nmonodev workspace rm \u003cworkspace-id\u003e\n```\n\n### Stack management\n\nTo easily manage multiple stores in one go, you can use the stack command. \n\nStack isn't technically required (you can still use `monodev apply/unapply` multiple times), but it's a convenient way to manage multiple stores. \n\nWhen using stack, the \"active store\" is not affected - use `monodev apply/unapply` separately for that.\n\nWhen there are conflicts (i.e. multiple stores claim the same path), you can use `--force` to override them - later stores take precedence.\n\n```bash\n# list all stores in the stack\nmonodev stack ls\n\n# add a store to the stack\nmonodev stack add \u003cstore-id\u003e\n\n# remove a store from the stack\nmonodev stack pop [\u003cstore-id\u003e]\n\n# clear the stack\nmonodev stack clear\n\n# apply the stack to the current workspace\nmonodev stack apply [--force] [--dry-run]\n\n# remove the stack-applied overlays from the current workspace\nmonodev stack unapply [--force] [--dry-run]\n```\n\n### Remote persistence\n\nShare stores across machines and teams using Git-based remote persistence. Stores are pushed to a separate orphan branch (`monodev/persist` by default) to keep them isolated from your main repository history.\n\n```bash\nmonodev init # initialize the .monodev directory in the repository root\n\n# Configure which Git remote to use for persistence\nmonodev remote use origin\n\n# Show current remote configuration\nmonodev remote show\n\n# Set a custom persistence branch (optional)\nmonodev remote set-branch monodev/custom\n\n# Push existing stores to remote\nmonodev push \u003cstore-id\u003e...\n\n# Pull stores from remote\nmonodev pull \u003cstore-id\u003e...\n\n# Pull and verify checksums\nmonodev pull \u003cstore-id\u003e... --verify\n\n# Force pull (overwrite local stores)\nmonodev pull \u003cstore-id\u003e... --force\n```\n\n**How it works:**\n\n1. Remote configuration is stored locally at `.monodev/remote.json`\n2. Stores are materialized to `.monodev/persist/stores/` before pushing\n3. A separate Git repository is created at `.monodev/.git` with an orphan branch\n4. The orphan branch is pushed to your configured remote\n5. When pulling, stores are fetched and dematerialized to `~/.monodev/stores/`\n\nThis approach keeps persistence separate from your main Git history while leveraging Git's compression and deduplication.\n\n---\n\n## What monodev is (and isn't)\n\n**Is**\n- per-workspace dev overlay manager\n- designed for monorepos and large codebases\n- deterministic\n- portable\n\n**Is not**\n- a build system\n- a dependency manager\n- a replacement for dotfiles or Nix\n\n---\n\n## Status\n\nEarly development. \n\nBuilt it for personal use, but contributions and design feedbacks are welcomed.\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljhkim%2Fmonodev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanieljhkim%2Fmonodev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljhkim%2Fmonodev/lists"}