A command-line tool that reads an existing codebase, turns the project information already hiding inside it into clean Smartsheet rows, and keeps them current. It never invents an owner, a priority or a date.
Owners, priorities and dates are filled only when the code literally states them. Everything else stays blank on purpose, and a guard refuses to sync fabricated data. One deliberate exception, stated plainly: a TODO that is still in the code is recorded as Not Started, because the comment describing the work still exists. That is a documented rule rather than a fact read from the file.
Each row carries the file it came from - and the line, wherever the evidence has one - plus the evidence type and a confidence level, so a human can verify it in seconds. Repository-wide checks such as “no lockfile” cite (repository), because they are about the repo as a whole rather than one line.
When a person edits the sheet, the tool never silently overwrites their decision. When both sides have moved and disagree the row becomes a flagged conflict; when only the sheet's own technical baseline was stale it is repaired and the row is flagged for a person with the reason. Either way it is a flag, not a silent stomp. Nothing is ever deleted.
Explain it like I am 5
Imagine your software project is a giant toy box.
Lots of important notes are hidden inside it: little reminders to fix things, a list of what is already finished, a diary of every change.
Our program looks through the box and finds the useful notes. It does not throw anything away, and it does not move anything. It only reads.
Then it writes neat copies of those notes onto a big checklist that the whole team can see. That checklist is Smartsheet.
When something in the toy box changes, the program checks again and updates the checklist on the same line instead of adding another one. Run it twice at once and it can still double up, so it is meant to be run one at a time.
And if the program is not sure about something, it does not guess. It puts a little flag on it and asks a grown-up to look.
The problem
A software project already records what is happening, in a dozen scattered places: TODO and FIXME comments, README roadmaps, changelogs, CI files, package manifests, ownership files, decision records. A project manager should not have to open twelve files to answer one question. This tool reads all of them and puts organized copies into one sheet, so the sheet stays honest with almost no manual upkeep.
The core discipline
Accuracy beats a full sheet. These two lists are the heart of the design: the tool is generous with evidence and strict about invention. The right column is what makes it safe to trust.
Real output
This is genuine output from “Orderly”, a small bakery order-tracking API bundled with the tool. Note the blanks the tool chose to leave, the monospace file:line source on every row that has a line, and the low-confidence risk routed to Human Review.
| Item ID | Item | Type | Status | Priority | Owner | Confidence | Review | Source |
|---|---|---|---|---|---|---|---|---|
| RSI-TD-594c25cb9a7a | sessions never expire; add a TTL and a cleanup job | Bug | Not Started | blank | @maria, @dev-lee | High | src/auth/session.js:5 | |
| RSI-TD-2e07fd3135a8 | daily summary report for the owner | Task | Not Started | High | @maria | High | src/orders/service.js:22 | |
| RSI-CK-dad057ed2313 | Email the customer when an order is ready (#42) | Task | Not Started | blank | @maria | High | README.md:16 | |
| RSI-RL-2a64fb8335cd | Release 1.2.0 | Release | Released | blank | blank | High | CHANGELOG.md:10 | |
| RSI-AD-b9cd6e10e217 | ADR-0001: Use PostgreSQL for order storage | Decision | Done | blank | @maria | High | docs/adr/0001-use-postgres.md | |
| RSI-RK-01c48a243e80 | Possible risk: HACK in a security-sensitive file (ORD-17) | Risk | Unknown | blank | blank | Low | ✓ | src/payments/stripe.js:4 |
6 of 23 rows shown. Full sheet has 26 columns; the technical ones hide behind the main view.
Smartsheet, used properly
The rows are the start. What turns the sheet into something that runs a project is Smartsheet’s own features. All six below are configured and live in the real sheet (set up by hand from the recipes in docs/smartsheet-import.md - the tool creates the columns and rows, not the automations), not mocked up - set up so the sheet reacts, alerts and summarizes on its own, with no one babysitting it.
Type, Status, Priority and Confidence are proper single-select dropdowns, not free text. Owner is a Contact column, which is what lets Smartsheet offer it as an alert recipient at all. A Contact holds a real address only when the code stated one; a CODEOWNERS handle such as @team-b is written as a display value, and a display value cannot be emailed.
Rows turn red when the code and a person disagree, amber when something is flagged for review, and grey when an item vanished from the code. Trouble is visible at a glance.
One shared view that shows only the rows that are blocked, in conflict, or flagged for review. Everyone opens the same filter and sees exactly what is on fire.
Two automations built on the live sheet: when a row is flagged for review Smartsheet emails the Owner (where the code stated a real address - it cannot email a blank cell or a display-only handle), and a weekly reminder chases items with no owner at all. The tool creates the sheet and its columns; the automations are built once in Smartsheet's UI, and the import guide walks through it.
Where the code never named an owner, Smartsheet sends an update request asking who owns this. The answer drops into the row, and the sync never overwrites it.
A summary sheet of counts, built from sheet-summary formulas, feeds a dashboard and a report so leadership sees where things stand without touching a single row.
A dashboard built from cross-sheet formulas over the same sheet. It answers what needs my attention in about five seconds. These are the real counts from the demo repository.
These are the live Sheet Summary values from the real sheet: Open items 10, Blocked 0, Needs human review 3, Sync conflicts 0. Built from COUNTIF formulas over the same rows. “Status unknown” is 7 on purpose - the repository never stated a status for those items, so the tool refuses to invent one rather than quietly counting them as open.
How it works
Nine small, independently tested extractors do the parsing — no language model in the path that produces facts. An optional Claude pass (off by default) writes plain-language summaries into the AI Suggestion column, and may fill an empty Description with a clearly labelled summary. It never writes to a fact column such as Owner, Status, Priority or Source.
Walk the repo read-only. Skip vendor dirs and binaries. Withhold anything that looks like a secret before any other rule.
Nine parsers turn comments, checklists, changelogs, manifests, CI, tests, CODEOWNERS and ADRs into quoted evidence: whitespace collapsed, clipped to 400 characters, redacted.
Evidence becomes rows with a stable ID and a confidence level. A guard rejects any invented owner, priority or date.
A three-way merge creates, updates or flags rows in Smartsheet. Idempotent, batched, retry-aware. Or export a CSV.
The hard part, solved
This is the question that sinks most sync tools. The answer is an explicit ownership model: every column belongs to the repository, to the human, or to both under a defined conflict rule.
Facts the repository is the source of truth for. Overwritten whenever the code changes.
PM decisions. Seeded once on creation only if the code proves them, then left alone forever.
If both sides change Status and disagree, the human value stays, the code's value moves to Repo Status, and the row is flagged.
Run it twice
Every line below is real output from rsi demo, which runs the true analyzer and sync engine against an in-memory sheet, so it needs no account and sends nothing anywhere. This is the sequence to walk through live.
An empty sheet. Every item found in the repository becomes a row.
Idempotent: the second run makes no duplicates and writes nothing.
The same row is updated, matched by its stable Item ID. No duplicate row appears.
Both sides changed Status and now disagree. The human's value is kept; the code's value is preserved separately; the row is flagged.
The tool cannot know if it was fixed or just removed, so it keeps the row and asks a human. Nothing is deleted.
Live build · 26 August 2026
23 rows and 22 typed columns generated from the sample repository and imported into a real Smartsheet, then the surrounding toolset built on top: summary formulas, conditional formatting, a shared filter, a grouped report, a dashboard and two automations.
Honest status
Every feature described above is built, 147 automated tests cover it against a fake fetch, and the sheet, dashboard and automations shown here are a real Smartsheet account, built from the tool's own CSV export. One thing is still deliberately not claimed as done: the live write over the REST API, because Smartsheet gates API tokens behind the Business plan and the 30-day trial cannot issue one. The sheet below was populated through Smartsheet’s own CSV import instead.
# from the app/ folder npm install npm test # 147 passing npm run demo:walkthrough # the full storyline, no account needed # when you have a Smartsheet token in .env: npx rsi setup-sheet # create the sheet with all columns npx rsi sync --dry-run # preview every change, write nothing npx rsi sync