Omrylo Blog

Building a Memory Layer for Local CLI Tools

Package managers install software but do not preserve the purpose, repository, and status of scattered scripts. tool-manage keeps that context locally.

The longer a development environment is used, the less its commands resemble a tidy software list. It accumulates global npm binaries, scripts copied into PATH, internal CLIs, AI coding helpers, and automation written for one project. The commands may still run, but their purpose, origin, and maintenance state become easy to forget.

Installing them again does not solve that problem. What is missing is a record that can be revisited: the command name and path, what it does, where its repository lives, who owns it, how it is used, and whether it still belongs in the active toolbox. tool-manage begins with that missing layer of context.

Draw the boundary around package managers first

npm, pnpm, Homebrew, and runtime managers already install software and switch versions well. tool-manage does not resolve dependencies, choose a version, or take over command execution. It registers tools that already exist and preserves the information needed to understand them later.

That boundary keeps the command surface small. `tm --add` registers, bare `tm` lists active records, `--show` reads one record, `--edit` adds local context, `--update` refreshes detected information, `--generate` creates a description skeleton, and `--remove` retires an entry. Every action belongs to the record lifecycle rather than the software lifecycle.

Automatic discovery and manual description are both first-class

For a conventional package command, the tool can resolve the executable from PATH, inspect nearby package metadata, and capture name, version, description, author, repository, license, and a help preview when available. That path removes repetitive entry work and gets an existing package into the catalog quickly.

An internal script may have no package.json and expose almost nothing. tool-manage therefore accepts local or remote JSON descriptions and uses `tm --generate` to create a starting spec with commandName, description, version, repository, author, and helpPreview. Manual metadata is not an error condition. It is a source the product must support deliberately.

The record also has to remain readable in a terminal. `tm --show` brings description, version, repository, author, and help preview into one view while omitting empty fields, so a small amount of manual context can still produce a clear result when discovery is incomplete.

Two registration paths
Command in PATH → Discover path and package metadata → Save record

Private script → Complete a JSON description → Import into the same registry

Why the registry uses local SQLite

A toolbox catalog can contain private repositories, internal authors, help text, and machine paths. Requiring a hosted account simply to inspect that information would add unnecessary exposure and operations to a personal tool. SQLite provides structured fields, queries, and migrations while keeping the database in `~/.tool-manage`.

The data model separates command records from user overrides. An update can refresh detected versions and package fields without casually erasing context that a person intentionally added. A small app_meta table keeps application-level state and migration information explicit as the schema evolves.

Deletion should permit a change of mind

A personal catalog needs cleanup, but “not active now” is different from “this history has no value.” `tm --remove` therefore writes `deleted_at`: the record disappears from the active list while its database row remains. Adding the same command again restores the existing record.

Automated tests cover that reversibility. They do not only check terminal copy; they open the SQLite database, verify that the row survives removal, and confirm that re-adding clears the deletion state on the original row. A product designed as memory should not lose memory during normal maintenance.

Small tools earn value by naming a problem precisely

tool-manage does not cover every developer workflow. It is unnecessary for someone with only a few familiar commands and does not replace version management, task orchestration, or team software inventory.

It serves a narrower and increasingly common state: the tools already exist and continue to multiply, while their context is scattered across README files, shell history, and memory. Naming that layer and making it searchable, maintainable, and reversible is the complete value of this small open-source product.