{"id":51438308,"url":"https://github.com/andrewmcodes/obsidian-import","last_synced_at":"2026-07-05T09:01:22.201Z","repository":{"id":365808674,"uuid":"1273841054","full_name":"andrewmcodes/obsidian-import","owner":"andrewmcodes","description":"Import structured metadata from canonical sources into an Obsidian vault as plain Markdown notes — Ruby gem with a Charm TUI and scriptable CLI.","archived":false,"fork":false,"pushed_at":"2026-06-19T00:44:26.000Z","size":131,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T02:21:49.898Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/andrewmcodes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["andrewmcodes"]}},"created_at":"2026-06-18T23:36:34.000Z","updated_at":"2026-06-19T00:44:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/andrewmcodes/obsidian-import","commit_stats":null,"previous_names":["andrewmcodes/obsidian-import"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/andrewmcodes/obsidian-import","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewmcodes%2Fobsidian-import","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewmcodes%2Fobsidian-import/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewmcodes%2Fobsidian-import/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewmcodes%2Fobsidian-import/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewmcodes","download_url":"https://codeload.github.com/andrewmcodes/obsidian-import/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewmcodes%2Fobsidian-import/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35148606,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-07-05T09:01:21.210Z","updated_at":"2026-07-05T09:01:22.194Z","avatar_url":"https://github.com/andrewmcodes.png","language":"Ruby","funding_links":["https://github.com/sponsors/andrewmcodes"],"categories":[],"sub_categories":[],"readme":"# obsidian-import\n\n`obsidian-import` imports structured metadata from canonical sources into an [Obsidian](https://obsidian.md) vault as plain, human-editable Markdown notes with standardized frontmatter. Search a source, preview the metadata, and write a portable note into your vault — no scraping, no proprietary storage, and no required plugins.\n\nIt ships a scriptable CLI for automation, and the metadata engine is UI-agnostic so it can be driven from a TUI, an MCP server, or any other front end.\n\n## Supported object types and their sources\n\nEvery object type has a single canonical source of truth, queried through that source's official API:\n\n| Type          | Source              |\n| ------------- | ------------------- |\n| `book`        | Open Library        |\n| `gem`         | RubyGems            |\n| `npm_package` | npm                 |\n| `github_repo` | GitHub              |\n| `app`         | Apple App Store     |\n| `vscode_extension` | Visual Studio Marketplace |\n| `movie`       | TMDb                |\n| `tv_show`     | TMDb                |\n| `podcast`     | Listen Notes        |\n\nNotes follow a standardized, flat frontmatter schema (core fields, then flattened source-specific metadata, then tags) defined in [ADR-001](docs/adr/001-metadata-schema.md).\n\n## Installation\n\nInstall the gem and add it to your application's Gemfile by executing:\n\n```bash\nbundle add obsidian-import\n```\n\nIf bundler is not being used to manage dependencies, install the gem by executing:\n\n```bash\ngem install obsidian-import\n```\n\nThis installs the `obsidian-import` executable. The gem requires Ruby 3.2 or newer.\n\n## Configuration\n\nConfiguration lives at `~/.config/obsidian-import/config.yml` (honoring `XDG_CONFIG_HOME`). Create a starter file with:\n\n```bash\nobsidian-import config init\n```\n\nThis writes a commented template with user-only (`0600`) permissions. Pass `--force` to overwrite an existing file. The file looks like:\n\n```yaml\n# obsidian-import configuration\n# Path to your Obsidian vault. Required to create notes.\nvault_path: ~/Documents/Obsidian\n\n# Vault-relative folder for each object type.\nfolders:\n  book: Books\n  gem: Gems\n  npm_package: npm Packages\n  github_repo: GitHub Repositories\n  app: Apps\n  movie: Movies\n  tv_show: TV Shows\n  podcast: Podcasts\n\n# API credentials. Prefer environment variables for secrets:\n#   TMDB_API_KEY, GITHUB_TOKEN, LISTEN_NOTES_API_KEY\napi_keys:\n  tmdb: \"\"\n  github: \"\"\n  listen_notes: \"\"\n```\n\nSettings, in order of precedence: explicit runtime configuration, environment variables, the YAML file, then built-in defaults.\n\n- `vault_path` — your Obsidian vault root. Required to write notes. Overridable with the `OBSIDIAN_VAULT` environment variable.\n- `folders` — vault-relative folder per object type. Your overrides merge over the defaults shown above.\n- `api_keys` — credentials for the keyed sources. Prefer the environment variables over committing secrets to the file.\n\n### API credentials\n\nThree sources accept credentials, resolved from the environment first, then the config file:\n\n| Source       | Used by              | Environment variable    | Required?                         |\n| ------------ | -------------------- | ----------------------- | --------------------------------- |\n| TMDb         | `movie`, `tv_show`   | `TMDB_API_KEY`          | Yes                               |\n| Listen Notes | `podcast`            | `LISTEN_NOTES_API_KEY`  | Yes                               |\n| GitHub       | `github_repo`        | `GITHUB_TOKEN`          | Optional (raises rate limits)     |\n\nCredentials are never logged, cached, or written into generated notes, and are redacted from error output.\n\nFor GitHub specifically, if the [`gh` CLI](https://cli.github.com) is installed and authenticated, requests are made through `gh api` so they reuse your existing gh credentials (higher rate limits, no token wiring needed); otherwise obsidian-import falls back to a direct, optionally-`GITHUB_TOKEN`-authenticated HTTP request. Set `OBSIDIAN_IMPORT_NO_GH=1` to force the direct HTTP path.\n\n## CLI usage\n\n```bash\nobsidian-import types                                   # list supported object types\nobsidian-import search \u003ctype\u003e \u003cquery\u003e                   # search a source\nobsidian-import show \u003ctype\u003e \u003cid\u003e [--frontmatter]        # render a note (or just its frontmatter)\nobsidian-import export \u003ctype\u003e \u003cid\u003e [--vault PATH] [--folder NAME]  # write a note into the vault\nobsidian-import config init [--force]                   # create the config file\nobsidian-import --help                                  # show usage\nobsidian-import --version                               # show the version\n```\n\n### Examples\n\nList the supported types and which require an API key:\n\n```bash\nobsidian-import types\n```\n\nSearch a source — results are numbered, with a truncated description and the source URL:\n\n```bash\nobsidian-import search gem view_component\nobsidian-import search book \"the pragmatic programmer\"\nobsidian-import search github_repo rails\n```\n\nRender a note to stdout, or just its YAML frontmatter:\n\n```bash\nobsidian-import show gem view_component\nobsidian-import show gem view_component --frontmatter\n```\n\nWrite a note into your vault. `\u003cid\u003e` is the source identifier (gem name, GitHub `owner/repo`, TMDb numeric id, Open Library work key, etc.). The target folder comes from the type-to-folder mapping unless overridden:\n\n```bash\nobsidian-import export gem view_component\nobsidian-import export github_repo rails/rails\nobsidian-import export movie 27205 --vault ~/Vaults/Research --folder \"Watchlist\"\n```\n\nOn success, `export` prints the absolute path of the note it created. All library errors (missing credentials, no vault configured, network failures, rate limits) are reported as friendly messages, and the process exits non-zero on failure.\n\n### Interactive use\n\nRunning `obsidian-import` with no arguments (or `obsidian-import tui`) launches an interactive [Charm Ruby](https://github.com/charmbracelet) TUI — a Spotlight/Raycast-style flow to pick a type, search live, preview metadata, and create a note. The same `Application` facade backs both the CLI and the TUI, so behavior is identical across interfaces.\n\nKeys: `↑`/`↓` navigate, `enter` selects/searches, `/` re-edits the query from the results list, `esc` goes back, and from the preview screen `c` creates the note, `y` copies the Markdown, `f` copies the frontmatter, `o` opens the source URL, and `ctrl+c` quits. The TUI's Charm gems are native extensions loaded lazily, so if they are unavailable on your platform the CLI and the rest of the library keep working.\n\n## How notes are written\n\n- The note filename is slugified from the title (lowercased, separators to hyphens, invalid characters stripped), with numeric suffixes resolving collisions. Software objects get a double extension, e.g. `rubocop.gem.md`.\n- The destination folder is created recursively if missing.\n- The frontmatter is a flat YAML block: core fields first, then flattened source-specific metadata, then `tags`. See [ADR-001](docs/adr/001-metadata-schema.md) for the full schema.\n- Responses are cached on disk under `~/.cache/obsidian-import` (honoring `XDG_CACHE_HOME`) with a 24-hour default TTL. Cached data never contains credentials.\n\n## Development\n\nAfter checking out the repo, install dependencies with `bin/setup`. Workflows are exposed through [mise](https://mise.jdx.dev):\n\n```bash\nmise run test        # run the RSpec suite\nmise run lint        # run StandardRB\nmise run format      # auto-correct style with StandardRB\nmise run typecheck   # run Steep against the RBS signatures\nmise run docs        # generate YARD documentation\nmise run ci          # full pipeline: lint, typecheck, test\n```\n\nYou can also run `bin/console` for an interactive prompt. To install the gem locally, run `bundle exec rake install`.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at \u003chttps://github.com/andrewmcodes/obsidian-import\u003e. The contributor and agent guide — including the adapter contract and how to add a new source — is in [AGENTS.md](AGENTS.md).\n\nThis project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the obsidian-import project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewmcodes%2Fobsidian-import","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewmcodes%2Fobsidian-import","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewmcodes%2Fobsidian-import/lists"}