Files
2026-09-04 22:54:50 -05:00

182 lines
4.7 KiB
Markdown

# optimus
A deliberately small project runtime for initialized modules, settings, named artifacts, and transformer-node helpers.
## Project shape
A host project provides JSON settings in `./settings/`:
```text
settings/
modules.json
artifacts.json
anything-else.json
```
`modules.json` maps semantic module names to initializer modules:
```json
{
"chatter": "./tree/chatter/index.js",
"markdown-builder": "./tree/markdown-builder/index.js"
}
```
Each module exports an initializer that receives the same shared `utils` object:
```js
module.exports = utils => {
function doSomething() {
const chatter = utils.loadModule("chatter");
const llm = utils.getSettings("llm");
}
return { doSomething };
};
```
## Utilities
### `utils.loadModule(name)`
Returns the initialized module registered under that semantic name.
### `utils.getSettings(name)`
Returns the parsed contents of `./settings/<name>.json`.
### `utils.hashPayload(value)`
Returns a SHA-256 hex hash of `JSON.stringify(value)`. No key sorting or normalization is performed.
### `utils.buildNode(payload, sources = {})`
Builds a transformer-node packet from a payload and already-loaded source nodes:
```js
const node = utils.buildNode(payload, {
hebrew: hebrewNode,
guidance: guidanceNode,
});
```
Result:
```json
{
"sourceHash": {
"hebrew": "<hebrewNode.hash>",
"guidance": "<guidanceNode.hash>"
},
"hash": "<hash of payload>",
"payload": "<payload>"
}
```
Optimus does not persist or validate the node. The owning module decides where its artifacts live and when to rebuild them.
### `utils.buildBinaryNode(filePath, sources = {})`
Builds the binary equivalent of a transformer-node packet. The supplied path is kept as the usable binary payload locator, while `hash` is computed from the file bytes:
```js
const node = utils.buildBinaryNode(resolvedCoverPath);
```
Result:
```json
{
"sourceHash": {},
"hash": "<SHA-256 of file bytes>",
"payloadBin": "<filePath>"
}
```
Derived binary artifacts can name source nodes in the same way as `buildNode()`:
```js
return utils.buildBinaryNode(pdfPath, {
volume: volumeNode,
style: styleNode,
});
```
`buildBinaryNode()` does not copy the file, interpret the path, or know what kind of binary it represents. It hashes the bytes currently at `filePath` and returns that path unchanged as `payloadBin`.
## Artifacts
`settings/artifacts.json` explicitly names the module and public builder function for each top-level artifact:
```json
{
"job.en.md": {
"module": "unpointed-hebrew-markdown-builder",
"builder": "buildMarkdownOutput",
"params": ["job", "en"]
}
}
```
Build one artifact:
```bash
npx optimus --artifact job.en.md
```
Build every declared artifact:
```bash
npx optimus
```
Artifacts are logical requested outcomes. Their modules own filenames, directories, persistence, cache policy, and dependency behavior.
A builder may call `utils.setArtifactOutcome("up to date")` (or another concise outcome) before returning. Optimus prints the requested artifact ID before invoking the builder and prints that outcome afterward; builders that do not report one receive the generic `completed — success` result.
## Invocation setting overlays
Optimus loads the project defaults from direct `settings/*.json` files. Each filename remains a free-form settings name available through `utils.getSettings(name)`.
A process can layer one or more JSON overlays on top of those defaults:
```bash
npx optimus --artifact psalms.en.md --setting settings/overlays/remote.json
```
Multiple overlays are applied left-to-right:
```bash
npx optimus --artifact psalms.en.md \
--setting settings/overlays/remote.json \
--setting settings/overlays/experimental-model.json
```
An overlay is one object whose top-level keys are ordinary settings names:
```json
{
"llm": {
"host": "remote-box",
"model": "remote-model"
}
}
```
Overlay behavior is deliberately small:
- object over object: recursively overlay properties;
- arrays: replace the previous array;
- scalars: replace the previous value;
- `null`: replace the previous value with `null`;
- omitted properties: inherit the value underneath;
- an overlay may introduce a new free-form settings name.
`utils.getSettings("llm")` sees only the resulting effective settings. Modules do not know which values came from defaults versus invocation overlays.
Overlay paths are resolved relative to the project root unless absolute.
## Build-all memory behavior
`buildAll()` awaits each declared artifact sequentially and does not retain prior artifact results. Artifact builders may still return either ordinary values or Promises; the runtime remains compatible with genuinely asynchronous work such as LLM requests.