oss-cli

Your repositories
and your notes,
on your machine.

One command that answers from what is already on your machine — the projects you follow, the notes you keep, the files in front of you — and only reaches for a model when it needs one.

  • A GitHub token is the only requirement. Everything else is a layer you add when you want it.
  • Nothing leaves the machine unless you attach a cloud key and ask it to.
  • Sync once, then the network is optional — 32 of the 44 commands never need it.
  • Ollama, a Claude key, or the CLI you already sign in to — the name goes in front of the command, and none of them is required.
$ brew install ramanathan1504/oss-cli/oss

Linux and Windows run the same jar — see the install guide.

oss ask — a real session

    

Yesterday's conversation, still there this morning — oss ask --resume picks it up in the directory you left it in. Every turn is written as it is said, so closing the terminal loses nothing.

What you type first

One command that asks — and looks before it asks anyone else.

oss ask reads files, searches everything this machine has indexed, runs your project's own build, and can propose an edit shown as a diff and confirmed by you. Give it no question and it opens a conversation; --resume picks the last one up. Five commands used to need a model — chat, guide and prompt are covered by this one now, and still work unchanged.

Every question starts with what you already worked out: your notes, your synced issues, and every question asked here with the answer it got. The instruction is explicit — if one of these already solved it, point at it before proposing anything new.

# no question, and it keeps asking
oss ask

# one issue, with everything already known about it
oss ask --issue 4129 -r owner/name

# let it run this project's own build — never an arbitrary command
oss ask --allow-run "do the tests pass?"

# let it propose one edit, shown as a diff, confirmed by you
oss ask --allow-edit "fix the null check in the parser"

Neither permission is on unless you type it, and neither is a setting: there is nowhere to leave them on by accident.

How it works is four markdown files, not a prompt buried in Java. oss skill lists them, and a file of yours in ~/.oss-cli/skills with the same name replaces one of ours entirely — the same takeover an attached runner has over the built-in one.

What it looks like

A session, playing itself.

Output copied from real runs, on a made-up repository called owner/name. This plays; it does not take input. A box on a web page cannot run oss, and one that behaves as though it can teaches the wrong shape of the tool — every line below is something you type in your own terminal.

oss — recorded output

Things worth typing

Each of these changes what the next one can do.

  • oss doctor every prerequisite at once, with the fix for each
  • oss model --fetch about 22 MB, once — then search is by meaning
  • oss sync --all pull down what you follow, so the rest works offline
  • oss search "rollover compression" --global across everything synced
  • oss followup --changed what moved since you last reviewed it
  • oss ask a question about one issue, answered from what is stored
  • oss history pick a saved conversation back up
  • oss skill the routines it knows, and your own alongside them

How it works

Nothing is mandatory. Every layer is yours to add.

Most tools fail closed — install this, configure that, then maybe you get an answer. OSS-CLI is built as a ladder. It runs on whatever you have connected and tells you, every single time, exactly which sources went into the answer you are reading.

The factsneeds: a GitHub token Issues and pull requests synced to local SQLite. Diffs, commits, changed files grouped by area, CI results, review threads. No clone required.
Project conventionsneeds: a repo profile The rules a change is actually judged against — toolchain version, formatting gates, API baselines, OSGi packaging. Read from the repository, and from the build files it inherits.
Search by meaningoptional: the built-in model One command, oss model --fetch, puts a 22 MB model on your disk and runs it inside the process. No server and no daemon, and it is never downloaded unless you ask. Without it, search and duplicates rank by shared terms instead.
Local answersoptional: Ollama, and you ask for it A verdict on a pull request, an answer to a question — generated on your own machine, with nothing sent anywhere. Typed as oss llm review 4249: a daemon that happens to be running is not a request.
Your prior workoptional: your own notes Point it at folders you already keep. Past investigations, saved conversations and hand-written notes become searchable evidence, surfaced while you review rather than after.
Escalationoptional: a cloud API key Typed as oss claude review 4249, and only reached when the local rung falls short — the reason is printed. No key? oss prompt assembles the same context for you to paste anywhere.

Who may answer

The engine goes in front of the command.

Not a flag on some commands and a different flag on others. What you typed is the whole answer to "did a model see this, and whose".

# nothing leaves this machine
oss review 4249

# a daemon on this machine may answer
oss llm review 4249

# Claude may answer — needs a key
oss claude review 4249

# either may, in that order
oss llm claude review 4249

# the provider's own CLI — your subscription, no API key
oss claude --cli review 4249

# the same sentence, whichever provider you have
oss gemini ask "why does the retry loop give up?"
oss codex review 4249
oss junie triage 4129

Five names, and each works in front of any command: oss llm is a local daemon, oss claude is Anthropic, oss gemini is Google, oss codex is OpenAI and oss junie is JetBrains. Which one you have decides nothing about what you may ask — that is the point of putting the name in front rather than building a different flag into each command.

May, not will. Naming an engine grants permission; it does not order a call. Every ask starts on the local rung — your own notes, the vector index, the deterministic checks — and goes out only when that rung fails a test the command states out loud, with the reason printed. A question your archive already answers is not worth a round trip.

No API credit is not a broken install. Each cloud engine has a command-line tool of its own, and --cli reaches the engine through the one you have already signed in to, billing your subscription rather than an API key. When a provider refuses a call for billing and its tool is on your PATH, the error names the keystroke that recovers — and never switches by itself, because whose account paid should stay the line you typed.

A command that never asks a model refuses the prefix instead of ignoring it. oss claude doctor would look like it asked a model something, and running the same deterministic report anyway would leave that impression standing.

Offline

Sync once. Then the network is optional.

One command needs the internet. Everything else reads a file on your disk — including search by meaning, because the model doing the arithmetic is running inside the process, not behind an API.

44 of 44 commands still work

  • sync
  • ask
  • skill
  • search
  • review
  • triage
  • setup
  • doctor
  • hub
  • pr
  • ext
  • serve
  • run
  • memory
  • llm
  • claude
  • gemini
  • codex
  • junie
  • critical
  • analyze
  • hidden-critical
  • duplicates
  • prs
  • profile
  • onboard
  • report
  • trend
  • guide
  • chat
  • history
  • prompt
  • inspect
  • backup
  • restore
  • alias
  • followup
  • backlog
  • pick
  • model
  • issue
  • bench
  • kb
  • bug

Connected, all forty-four answer. Pull the cable and twelve go dark — six fetch something you asked for by number or by list, the four cloud engines call their providers, model downloads the embedder once in the life of the install, and bug files a fault in oss itself. bug is the only one of the twelve that writes anywhere, and it writes nothing until it has printed the whole issue — redacted — and you have said yes. The other thirty-two never needed it: doctor pings and reports rather than depends, llm talks to a daemon on this machine, serve binds to localhost over the corpus already on disk, and run and memory are as offline as the extension you attached — type either on its own and it lists the verbs that extension actually declares, read from the manifest on your machine rather than from this page.

While you have a connection
# a token — the only thing oss requires of you
export GITHUB_TOKEN=$(gh auth token)

# the embedding model: 22 MB, once, ever
oss model --fetch

# register a repository and pull it down
oss sync --add owner/name
oss sync --all

now turn the wifi off

Everything below still works
# finds "log rotation with zstd" — no shared words, same subject
oss search "rollover compression"

# rank what is waiting, by community signal
oss critical

# see what would be retrieved, and whether it escalates
oss inspect 812

# assemble a complete expert prompt from local context
oss prompt 812

Why it works: sync fetches, then a 22 MB ONNX model running in this process turns what it fetched into vectors on your machine. No server, no daemon, no key, nothing listening on a port. Ollama is a separate connector for writing text — nothing that indexes or searches goes near it. Without the model, search still works by shared terms and says which mode it used. Read the full guide →

An actual review

Every answer names its sources.

The last block of any review is the part that matters most: what was used, and what was not available. A thin review is never mistaken for a clean one.

Facts first. Author, base branch, head commit and the shape of the diff come from GitHub and are cached against that head commit.

Conventions are deterministic. The gate checks involve no model at all — they are the project's own rules, including the ones it inherits.

Your prior work is evidence. Notes you already keep are ranked against the changed paths and surfaced while you review.

The footer is the honest part. A layer you have not connected is listed as unused, not silently skipped.

Why it exists

Stop reassembling the same context by hand.

The work of understanding a change is mostly retrieval: what the project's rules are, what was decided last time, which upstream file this actually inherits from. OSS-CLI does that part once and keeps it.

Inherited rules

Finds what isn't in the repo

Many projects publish their packaging and API rules in a parent build file, not in the repository you are reading. OSS-CLI follows that chain and tells you where each rule came from.

Commit-aware cache

Re-reviewing is free

Evidence is cached against the head commit, not the pull request number. Nothing changed since last time? Instant. Someone pushed? It re-fetches on its own, with no staleness setting to get wrong.

A knowledge base, built in

No second repository to clone

File a note, index it, search it by meaning, see which notes touch which topic, and measure what your notes have touched against what a technology actually documents — touched, because writing about something is meeting it and only you can say you have learned it — all oss memory, all shipped. It harvests your own public work on GitHub and the Claude Code, codex and gemini transcripts already on your disk, redacting secrets rather than dropping the passage around them. oss memory sessions files each of those transcripts under what it was about rather than which program produced it — the tool is a field on the note, never a folder — and oss memory contributions writes one note per change of yours that actually merged: the commit, the diffstat, and every review remark, including the ones pinned to lines of the diff. Both work with no model at all; a summary on top comes from whichever CLI or local model you have, and the note says which wrote it. oss memory curriculum then places every area a subject's own manual documents into one of three states — gap when the archive says nothing, backlog when you have met it and never sat down with it, and covered, which only you can assign: you move the file, and re-running never moves it back. oss memory track keeps every write-up a repository carries, filed under its own first heading and stamped with the path, commit and digest it came from — so a note edited three commits after it was filed is something doctor reports rather than something you find out about. oss memory schedule --install runs the harvest daily and --hourly files transcripts as you go; oss memory doctor tells you whether it worked. Pointing it at your own folder is a few lines of kb.json, not a checkout.

A runner, built in

It builds your project with your project’s own command

oss run detect reads what the directory already declares — pom.xml, build.gradle, package.json, go.mod, Cargo.toml, a Makefile — and oss run build and oss run test run it, printing the exact command first so you can type it yourself. Nothing is invented: a package.json with no build script is reported as having none rather than being sent one that fails. oss run init writes the starter pack that unlocks the matrix engine, filled in from what is already there.

Local-first

Your data stays put

Issues, vectors and notes live in SQLite on your disk. Retrieval and embedding run locally. Nothing leaves your machine unless you explicitly escalate a prompt to a cloud model.

Extensions

Two questions it will not answer alone

OSS-CLI reads any repository through the API, in any language, without a clone — which is why it generalises, and why it cannot tell you does this actually run or have I worked this out before. Both have a built-in floor — oss run builds and tests any project, oss memory files and finds anything you write — and an extension takes over when you attach one. A run recorded with --pr is remembered against that pull request and read back before any model is consulted, because a question the runner has already answered is not worth a network round trip. A repo declares an oss-ext.json and becomes a runner or a memory; oss ext add <repo> attaches it, and a verb it does not declare falls back to the core rather than being refused. Written in anything, called as a child process.

Packs

A pack is a file, not a script

A pack is a description of your applications, versions and configurations — and it is data the tool reads, not a program it runs. pack.json, or the same object in a json block inside pack.md so one file explains itself to a person and to the tool at once. Reading it cannot execute anything, and a pack states what it is for, so oss can find the right one instead of being told.

On your machine

A page, if you want one. The same commands either way.

Nothing here is a second product with its own features to learn. Every button runs the command you would have typed, and says which one on hover — so the page can never tell you something the terminal would not. Work in whichever you prefer, and swap mid-task.

# the board, over whatever you already follow
oss serve
localhost:1504

What is waiting on you

Every pull request you own or review, across every project you follow, in one list — the same list oss hub prints in the terminal. Two of its signals exist nowhere on GitHub: which reviews you wrote and never posted, and whose head has moved since you looked.

On the row

Answers where the question is

“Have I worked this out before?” is asked about the change in front of you, so it is answered underneath it — no second page, no retyping the title. The search runs on the model inside oss, with no network.

Before any model

What actually ran

A model cannot tell you whether a change builds — asked, it writes a confident sentence about code it never executed. The runner can, because it executes it. oss run --pr <n> --checkout test fetches that pull request into a throwaway worktree, runs there, and records what it found; the row shows it before offering you a model. It also stores which commit it ran on, so a pass from a tree that is not the change under review is never allowed to read like a pass. A pull request from a fork is refused unless you say --allow-fork — running one executes its author’s build on your machine.

Reading, not writing

Nothing on it writes

Not "asks first" — there is no write path on the page at all. It cannot post a review, file a note, attach an extension or sync; those are verbs you type, because an outward write is confirmed where you typed it and a browser has nowhere to confirm one. The board names them rather than hiding them, so you know where they went.

Install

A GitHub token. That's the whole requirement.

Every download carries its own Java, so there is no runtime to install first — and the Linux and Windows archives are the same build Homebrew installs for you on macOS.

1 · Install
brew install ramanathan1504/oss-cli/oss

Homebrew pulls in OpenJDK 17 for you and puts oss on your PATH.

2 · Give it a GitHub token
# any token with the `repo` scope — the gh CLI already has one
security add-generic-password -a "$USER" -s github_token \
  -w "$(gh auth token)" -U
3 · Check everything
oss doctor

First run

Register a repository and sync it
# any repository you want to follow
oss sync --add owner/name

# pulls issues and PRs, then builds the search index
oss sync --all

# review a pull request with everything you have connected
oss review 4234 -r owner/name

Optional, any time: run oss model --fetch for search by meaning, install Ollama for local answers and verdicts, then run oss setup to point OSS-CLI at your own note folders. Skip all three and every command above still works.

Whichever backend you have

One interface, and it says which rung answered

Naming an engine grants permission; it does not order a call. Every ask starts on the local rung and climbs only when that rung fails a stated test — and the rung that answers says so before it answers.

What you haveWhat answers
An API keyThe provider's API
No key, but their CLI installed and signed inThat CLI, on your subscription — announced, not silent
Neither, but Ollama runningThe local daemon
None of itThe built-in model: ranks and retrieves, offline

A key is never abandoned for a subscription without being asked — that would change who pays and what the harness may read. Having no key is a different situation: there is no account to move away from, and the alternative was a dead end you had to already know a flag to escape.

It writes the way you write

oss profile --me measures how you write from text with your name on it — the issues and pull requests you authored, the comments you wrote. Harvested threads and generated notes are excluded on purpose: a voice learned from those is the tool's own, handed back to you as yours. Every trait is arithmetic over your text, never a model asked what you “sound like”, because that returns flattery and flattery cannot be checked. Under twenty samples it tells no model anything, and says so.

Packs, and the support packs under them

A pack is a subject; a support pack is something attached to it. Every repository you follow is already a pack, so this works before you configure anything — a manifest only says which one it sits under. The assistant is then told what is attached and to which subject, stated as fact rather than as instruction: told “use the bench” a model reaches for it on an unrelated issue to be helpful; told “this exists, it supports that”, it can decline.

Reference

The commands you will actually use

Since 3.0, oss --help shows the twelve that carry the daily work rather than all forty at once — a list that long is an inventory, not a menu. Nothing was removed. The rest still run, unchanged, and oss --help-all lists every one of them. Or run oss doctor when something is not behaving — it checks every prerequisite and names what to fix.

CommandNeedsWhat it does
sync --add <repo>tokenRegisters a repository and builds its convention profile
sync --alltokenPulls issues and pull requests, then updates the search index
sync --metokenIndexes your own pull request history and your note folders
profiletokenShows a project's language, build, toolchain and enforced conventions
review <pr>tokenReviews a pull request using every source you have connected
prompt <issue>tokenAnswers locally, or assembles a complete expert prompt when it cannot
search <query>—Searches everything you have indexed — by meaning with the built-in model, by shared terms without it
triage <issue>OllamaFull triage audit for a single issue
chat <issue>Ollama or a keyTalks an issue through, writing every turn as it is said
history—Browses saved conversations and resumes one where it stopped
doctor—Checks every prerequisite and says exactly what to fix