From Source Code to Harness: The Seven-Phase Translation

CLI-Anything builds its command contract from a source codebase rather than from a software name or a generic template. This chapter follows that source-to-harness lifecycle: what the project must learn about the target before it designs commands, why tests and documentation belong inside the build, and how refinement turns an incomplete first pass into a more useful interface. The practical result is a way to see generated CLI work as a chain of design decisions with evidence at each transition, not as an opaque act of code generation.

A software name is not enough

The generator accepts a local source path or a repository URL because the methodology depends on inspecting the target. A name can identify an application, but it cannot reveal how that application stores state, which backend performs the meaningful work, how a GUI action reaches that backend, or which existing command-line and scripting interfaces are available. Those details determine whether a harness can be faithful and what its limits will be.

Source acquisition is therefore the first semantic boundary in the build. The generator obtains a working copy, confirms that it contains source code, and derives a target identity from that local material. This is not merely setup before the “real” work. If the input is incomplete, wrong, or unrelated to the named software, every later design decision is built on a false premise. The methodology's insistence on a source path is a modest form of architectural humility: the agent cannot responsibly invent a control surface for mechanisms it has not examined.

The source also provides a way to distinguish what the project knows from what it assumes. A repository may expose a native file format but not a complete rendering path. An application may have a scripting API that covers scene construction but not every interactive feature. A backend may be available in one environment and absent in another. These facts are not obstacles to be hidden after the first successful command; they are inputs to the scope of the harness.

Analysis comes before command design

The next stage asks what the target is made of and where its semantics live. CLI-Anything's methodology tells a builder to identify the backend engine, map GUI actions to API calls, understand the data model, locate existing CLI tools, and inspect the application's command or undo system when one exists. The aim is not to reproduce the GUI's menus one by one. It is to find the operations and state transitions that make those menus meaningful.

This distinction changes how a command group is designed. In a video editor, “drag a clip onto a track” may correspond to a relationship between media producers, timeline entries, and a track container. In a 3D application, “add an object” may require a scene description, transforms, materials, lighting, and a later render through the application's scripting API. The command surface should expose the target's logical domains, not the accidental geometry of its windows.

Analysis must also identify ownership. Which state belongs in a project file? Which state is temporary session context? Which values are interpreted by the target backend only at render time? What can be inspected before mutation, and what can be verified only after execution? These questions are easy to postpone because a small demonstration can be built without answering them. Postponement becomes expensive when the agent needs to resume a project, undo a change, run a command from another directory, or explain why an output does not match the request.

The output of analysis is therefore not just a list of APIs. It is a model of the semantic seams available to the harness. A good seam lets the CLI express a meaningful operation, persist or query the relevant state, call the right backend, and return evidence that the agent can use. A weak seam may still support a narrow experiment, but it should not be presented as full coverage.

Architecture design turns findings into a contract

Once the target's structure is understood, CLI-Anything moves to architecture design. The methodology calls for command groups that match the application's logical domains, a state model that explains what persists between commands, and output modes that serve both interactive and programmatic use. It also places rendering and session management in the design rather than treating them as later additions.

The design stage makes several choices explicit. One is interaction mode: a harness may support one-shot subcommands, a stateful REPL, or both. Another is state ownership: some project state may live in a native file, some in a JSON representation, and some in a session record. A third is output form: human-readable tables and messages can help a person inspect a workflow, while structured JSON gives an agent stable fields to parse. These choices are connected. If a command is intended to run as a separate process, the design must say how it finds the project and what it saves before the process exits.

The architecture must also preserve the real-backend rule. If the target application applies effects only at render time, the CLI cannot treat successful XML or JSON mutation as the final outcome. If the native format is binary or difficult to edit safely, an intermediate representation may be appropriate, but the design must define how that representation becomes an actual project or script for the real application. A design that leaves this boundary vague may produce an elegant command surface with no reliable meaning behind it.

At this point, the agent's earlier command contract becomes concrete. info, list, and status need target-specific state to report. Mutation commands need target-specific validation. Export commands need target-specific backend invocation. Error messages need to distinguish missing inputs from missing software and unsupported operations. The design is coherent only when these decisions fit together.

flowchart LR A["Source path or repository"] --> B["Architecture, data model, and backend analysis"] B --> C["CLI groups, state, and output design"] C --> D["Harness implementation"] D --> E["Test planning and execution"] E --> F["Documentation and SKILL.md"] F --> G["Packaging and installation"] G --> H["Refine capability gaps"] H --> B

The loop in the diagram is intentional. The first pass moves from source toward an installed tool, but refinement sends evidence about missing capability back to analysis. It is not a failure of the method that later work discovers a gap; the method treats coverage as something to measure and expand rather than as a property guaranteed by generation alone.

Implementation is only one transition

The implementation phase creates the harness structure and its core operations. The project describes modules for project management, sessions, export, domain-specific operations, utilities, and tests, together with a Click-based entry point. Those names are less important than the responsibilities they separate. Project logic represents or edits the target state. Session logic preserves context and history. Backend logic invokes the real application. The CLI layer exposes these responsibilities through commands, output modes, and error handling.

A healthy transition from design to implementation preserves the decisions made during analysis. If the target's semantic unit is a timeline track, the CLI should not quietly reduce it to an unstructured list of files. If the target has a real renderer, the export path should not quietly substitute an unrelated library. If the interface claims to support JSON, every relevant command needs a stable machine-readable result, including meaningful failures. Implementation is where the architecture becomes observable, so inconsistencies here are not cosmetic defects; they change what the agent can safely infer.

The methodology also asks harnesses to provide a unified REPL skin and to make the REPL available when the command is invoked without a subcommand. That shared surface gives different harnesses a recognizable interactive behavior, but it does not remove target-specific semantics. A common prompt or success marker can improve orientation; it cannot make two applications share the same state model. Consistency belongs at the interface layer, while fidelity belongs at the target boundary.

Tests are planned before they become claims

CLI-Anything places test planning before test implementation and asks the builder to describe unit tests, end-to-end scenarios, realistic workflows, expected files, and output checks. This ordering changes what “coverage” means. A test plan forces the builder to name the behavior that should be observable before implementation makes a convenient subset look complete.

The methodology separates fast unit tests from tests that use real project files, the real backend, and the installed command. Those layers answer different questions. A unit test can show that a function manipulates an in-memory structure correctly. A native end-to-end test can show that the generated project file has the expected form. A true-backend test can show that the actual application renders or exports something with the expected properties. A subprocess test can show that the installed entry point works as an agent would invoke it. No single layer substitutes for the others.

This is why documentation of test results comes after execution. A plan describes intended coverage; a result records what happened in a particular run. Keeping the two parts together makes it harder to present an aspiration as an observed fact. The project also requires output verification rather than trusting a zero exit status. Depending on the domain, that may mean checking a file signature, a package structure, pixels, audio characteristics, or duration. The exact check belongs to the target, but the principle is common: verify the artifact that matters.

The approach is strict about missing backends when the test is supposed to exercise real software. That strictness can make local setup less convenient, yet it protects the meaning of the test. If a real-render test silently falls back to a synthetic approximation, a passing result no longer says that the target application performed the requested work. The methodology prefers a visible failure to an ambiguous success.

Documentation and packaging complete the build

After the harness is tested, CLI-Anything generates a self-contained SKILL.md and packages the CLI for installation. These stages are not administrative cleanup. The skill document tells an agent what the CLI is for, how its commands are grouped, what prerequisites exist, how to use JSON output, and how to interpret common workflows. The generator extracts information from the harness's README, setup metadata, and Click command structure, then writes a canonical repository copy and a compatibility copy inside the installed package.

Packaging connects that description to an executable identity. The project uses a shared cli_anything.* namespace so separately installed harnesses can coexist, and it exposes console entry points that can be found on PATH. The resulting relationship is important: a tool is not fully agent-usable if its commands work only from the directory where they were generated, or if its capabilities are documented only in a private development note that the agent cannot locate.

This stage also exposes a maintenance dependency. Generated documentation can become stale when commands change. A skill file can accurately describe the harness at one point and omit a later refinement. The methodology therefore places documentation updates inside refinement and requires package data to include the skill copy. Discoverability is part of the lifecycle precisely because it can drift away from implementation if no one treats it as a tested interface.

Refinement closes the loop

The refinement command assumes that the first harness is a coverage hypothesis, not a final inventory of the target application's abilities. It reads the existing CLI and tests, rescans the software's public APIs and batch operations, compares current coverage with available capabilities, and prioritizes gaps by impact, ease, and composability. A focused refinement can narrow the work to a coherent area rather than expanding every surface at once. New commands receive tests and documentation, and the old suite must continue to pass.

This is a more disciplined response to incompleteness than adding random features whenever a user notices a missing command. The gap report connects a missing capability to the target's actual architecture and asks whether the capability unlocks a meaningful workflow. It also preserves the semantic boundary: a new command is valuable only if it can represent the target operation, reach the right backend, and produce evidence that the result is real.

The lifecycle therefore has two directions. Forward movement turns source understanding into an installed, discoverable interface. Feedback moves from tests, failed workflows, and missing capabilities back into analysis and design. The project does not establish that every first run reaches complete coverage; its own methodology says iterative refinement may be necessary. What it offers is a process for making the next decision more informed than the last one.

The decisive design work happens before code generation: identifying the backend, data model, and observable operations that can support a faithful command surface. The next step is to examine exactly what crosses that boundary when the target uses a native project format, a binary representation, or a scripting API—and why the real software must remain authoritative when the command becomes an artifact.

References