From a File Drop to a Conditional Capability

FlyingMouse Format’s central engineering problem is deciding what a particular file can become in the runtime that is actually available. This chapter follows that decision from the desktop window or CLI through the local service, target calculation, and conversion dispatch. The practical value for the reader is a way to distinguish a format that is registered in the application from a conversion that the current source, engine, and destination can honestly support.

One conversion contract, two callers

The desktop interface and the command line look like different products. One is built for drag-and-drop, previews, remembered preferences, and batch queues; the other is built for scripts, stable JSON, output directories, and automation. FlyingMouse Format avoids making them separate conversion systems. Both enter through the same local service and use the same capability and conversion routes.

That choice is more important than it first appears. If the interface had one table of supported targets while the CLI maintained another, the two could gradually disagree. A format might be offered interactively but rejected by automation, or the command line might accept a target that the window has learned is unavailable. Shared routing does not eliminate every bug, but it puts the decision in one place: the service recognizes the source, calculates its allowed targets, dispatches the conversion, and registers the result.

A typical request has several distinct moments. The caller supplies a file and a desired destination. The service receives the upload into a runtime directory and decodes the original name. It normalizes the source extension so aliases such as related image or text extensions can be treated consistently. It then checks the requested target against the complete set of known targets, and checks again against the targets permitted for this source category and the tools available in the current process. Only after those gates does it choose a conversion path.

That sequence gives each component a clear owner. The caller owns intent: “turn this file into that kind of output.” The local service owns interpretation and authorization of the conversion request. The specialized engine owns the transformation itself. The result registry owns the relationship between the newly produced file and the download or preview URL that exposes it. Keeping those responsibilities separate makes the system easier to reason about than a single handler that accepts a filename, guesses at an engine, and hopes the output is usable.

The distinction also matters for failures. A missing file is a request problem. A target that is globally unknown is a capability vocabulary problem. A target that exists in the product but is not valid for this source is a source-target mismatch. A missing engine is an environment problem. A converter that runs but produces incomplete content is a quality problem. FlyingMouse Format’s local API can return these at different points instead of treating every failure as an undifferentiated “conversion error.”

The route is easier to see as a sequence than as a list of modules:

sequenceDiagram participant C as UI or CLI participant A as Local API participant P as Capability probe participant G as Source-target gate participant E as Converter or engine participant R as Result registry C->>A: Submit file and requested target A->>P: Read current tool capabilities P-->>A: Available engines and diagnostics A->>G: Check source-specific targets alt Target is unavailable G-->>C: Structured rejection else Target is allowed G->>E: Dispatch conversion E-->>A: Output or qualified failure A->>R: Register successful result R-->>C: Download/preview metadata end

The important feature of this sequence is not its HTTP vocabulary. It is the placement of decisions. The application does not begin expensive conversion before it knows that the requested target is plausible, and it does not equate an engine’s process exit with a complete user result.

There are three vocabularies behind that placement. The first is the filename vocabulary: an extension such as md, pdf, or ofd is a convenient signal supplied by the user, but it is not yet a conversion plan. The second is the category vocabulary: text, document, spreadsheet, presentation, PDF, image, audio, and video determine which family of routes is relevant. The third is the tool vocabulary: the engines that are present and runnable determine which members of that family can be exposed. A request becomes meaningful only when those three descriptions agree.

That agreement also protects state. The caller can ask for a target, but it does not get to choose an arbitrary output route merely by sending a string. The service normalizes the input, checks that the target belongs to the application’s known set, calculates the source-specific intersection, and then chooses an output name and temporary location. After conversion, it removes the upload and registers the result with its download name, MIME type, and preview information. The registry is what turns a private runtime file into the one result the current caller is allowed to retrieve. This is a small but important form of state ownership: the caller expresses intent, while the service controls the lifecycle of the artifact created in response.

The same model is useful for batch operations. When several files are selected together, a target that is valid for only one of them cannot be presented as though the batch were homogeneous. The interface can show the shared target intersection, while the service still validates each request. The principle is the same as for a single file: the most permissive member should not silently expand the promise made to the least capable member.

These gates do not make conversion deterministic in the strongest sense. Engines may behave differently across platforms, and a file can be syntactically recognized yet semantically difficult. What the architecture gains is a clean place to express uncertainty. If the request never reaches an engine, the user receives an availability or source-target explanation. If the engine runs and the output needs inspection, later validation can attach a warning to the produced result. The stages remain distinguishable instead of being collapsed into one opaque operation.

Capability is a runtime fact

A converter can have a static format table and still be unable to perform a particular conversion. FlyingMouse Format therefore combines configuration with probes. Its capability response reports categories, targets, platform information, and details about optional tools. LibreOffice is checked as an executable document engine. Pandoc is tested by asking it for its version. Poppler and FFmpeg are checked as available commands, and OCR has its own availability path. The result is not merely “the source code contains a branch for this format,” but “this installation can currently expose that branch.”

This distinction is especially important because the repository does not keep all large engines in the source checkout. A developer who clones the project may have the JavaScript application but not the FFmpeg, LibreOffice, Poppler, or Tesseract resources needed for a complete conversion experience. A packaged build can also use different resources from the development environment. If the UI displayed every target unconditionally, the first meaningful engine check would happen only after the user had selected a file, waited for an upload, and encountered a failure.

Instead, optional engines change the product surface. Many Office and WPS conversions depend on LibreOffice. Markdown-to-Word and Markdown-to-PDF depend on the bundled Pandoc path in the profiles that include it. PDF rendering to images depends on Poppler. OCR-dependent routes need an OCR engine. The application can still offer other routes when one tool is missing, but it should not represent the missing capability as available merely because a file extension appears in a static list.

This makes capability reporting a form of negotiation. The caller asks, in effect, “What can this runtime do with this kind of source?” The application answers using both the source category and the present tools. A text file may have destinations that an image does not. An image may gain OCR text output only when OCR is enabled. A PDF may have text-oriented targets even when page rendering is unavailable, while image targets depend on a renderer. The answer is conditional because the source and the environment jointly determine the legal next step.

Capability negotiation also makes the application’s error messages more useful. If Pandoc cannot run, the user can repair the installation rather than inspect an apparently successful but missing Word/PDF option. If a target is not allowed for the source, the request can be rejected before an engine is invoked. If a tool probe fails, diagnostic information can remain attached to the capability result instead of being buried in a generic conversion log. Early rejection is not merely a performance optimization; it gives the user a more accurate model of what happened.

There is a subtle limit here. A capability probe generally establishes presence and basic runnability, not fidelity for every input. Pandoc answering its version request does not prove that every Markdown extension will become a good DOCX. LibreOffice starting does not prove that a particular WPS document will render correctly. A PDF table extractor being enabled does not mean that a low-quality scan contains enough evidence for a trustworthy spreadsheet. Capability is the entrance condition for a path, not the conclusion of quality assurance.

Why source-specific gates matter

The global target vocabulary answers a narrow question: is this output type part of the application at all? The source-specific gate answers the question a user actually cares about: can this input be converted to that output through a supported route? Both are necessary because a universal target list would be dangerously permissive.

Consider audio. FlyingMouse Format deliberately exposes ordinary audio targets rather than video containers for an audio source. That is not a limitation caused by a missing menu item; it expresses the semantic boundary of the category. A target can be technically imaginable and still be inappropriate for the contract the application is willing to support. Similar boundaries apply to specialized or experimental inputs, which can be labeled separately so that unusual decoders are not mistaken for the same confidence level as ordinary paths.

OFD provides a clearer architectural example. OFD is an open document format used in Chinese electronic-document contexts, but LibreOffice cannot open it. Sending OFD into the general document branch would make the apparently convenient general engine the wrong abstraction. FlyingMouse Format intercepts OFD earlier, exposes a narrower target set centered on PDF, and uses a pure-JavaScript conversion path. Once a valid PDF exists, the result can reuse the project’s existing PDF routes for images, text, or Word-related work.

That design is a useful compromise between duplication and false uniformity. The project does not pretend that every document engine accepts every document family. It gives the exceptional format its own adapter, keeps its public targets narrow, and reuses a downstream representation whose later processing is already understood. The adapter is small because it stops at a boundary the rest of the system can handle; it is not asked to impersonate LibreOffice.

The same principle applies to targets that depend on a sequence of engines. An input may first be rendered, then recognized, then written to a destination. If any stage is unavailable, the capability should be reduced or the request should fail with a meaningful explanation. This is especially important for non-specialists, who cannot be expected to know which external binaries a desktop application happens to require. The application’s target list is part of its explanation of the system.

A source-specific gate also protects the result name and lifecycle. Once the target has been approved, the service chooses the output extension, creates a runtime path, runs the relevant converter, and removes the uploaded temporary file after success or failure. On success, it registers the output and returns metadata for preview or saving. The result is therefore tied to the same decision that authorized the conversion; it is not an arbitrary file left in a shared directory for any caller to discover.

The boundary of a capability report

A capability response can answer three useful questions: whether a category is recognized, which targets are currently exposed, and which optional tools appear available. It cannot answer every question about the resulting artifact. It does not promise that a complex PDF will become a pixel-identical Word file, that OCR will read a shadowed scan correctly, or that a malformed spreadsheet will preserve every feature. Those judgments belong to the path-specific validation and warnings that come after dispatch.

This separation prevents two opposite mistakes. The first is overpromising: treating a present button or a successful engine probe as evidence of universal fidelity. The second is under-explaining: returning a generic failure that hides the difference between an unavailable engine and a difficult input. FlyingMouse Format’s architecture is strongest when it lets the early gate answer only what it knows, then leaves the harder question—what meaning survived—to the conversion path that can actually inspect the output.

Once a target has passed these conditions, the central question changes. It is no longer “Can this runtime start a route?” It becomes “What structure does the source contain, and what structure can the destination preserve?” That is where format conversion stops being a menu-selection problem and becomes an interpretation problem.

References