ProjectsLast updated on
Last updated on
Project structure, manifest, and artifact storage
A project is a directory managed by the CLI. It contains a manifest that describes the project, a state directory that tracks installed artifacts, and the artifact files themselves. Initialize one with ofm init.
Initializing a project
ofm initIn interactive mode, the CLI prompts for a project title, description, and visibility (public or private). Use --yes to skip prompts:
ofm init --yes --name "My Project" --visibility privateSee the init command reference for all options.
The project manifest
The open-form.json file in the project root defines your project:
{
"$schema": "https://schema.open-form.dev/manifest.json",
"name": "@your-org/my-project",
"title": "My Project",
"description": "A description of your project",
"visibility": "private",
"artifacts": {
"dir": "artifacts",
"format": "yaml"
},
"registries": {
"@acme": "https://registry.acme.com"
},
"security": {
"allowedContentTypes": ["application/pdf", "text/markdown"]
},
"cache": {
"ttl": 3600
}
}Fields
| Field | Type | Required | Description |
|---|---|---|---|
$schema | string | No | JSON schema URL for editor validation |
name | string | Yes | Project identifier in @org/name format |
title | string | Yes | Human-readable project title |
description | string | No | Project description |
visibility | "public" | "private" | Yes | Project visibility |
artifacts | object | No | Artifact storage configuration |
registries | object | No | Registry configuration by namespace |
security | object | No | Security restrictions |
cache | object | No | Cache configuration overrides |
Artifacts
Controls where artifacts are stored and in what format.
| Field | Default | Description |
|---|---|---|
artifacts.dir | "artifacts" | Directory for downloaded artifacts (relative to project root) |
artifacts.format | "yaml" | Default output format (see Output formats) |
Registries
Maps namespaces to registry URLs. See Registries for details.
Security
| Field | Description |
|---|---|
security.allowedContentTypes | Content types permitted when downloading layers |
Cache
| Field | Default | Description |
|---|---|---|
cache.ttl | 3600 | Time in seconds before cached registry data expires |
Directory structure
After initialization and installing an artifact, your project looks like this:
my-project/
├── open-form.json # Project manifest
├── .ofm/ # CLI state directory
│ ├── HEAD
│ ├── index.json
│ ├── config.json
│ ├── lock.json
│ ├── commits/
│ └── objects/
└── artifacts/ # Downloaded artifacts
└── @acme/
└── residential-lease.yamlThe .ofm/ directory
The .ofm/ directory stores internal CLI state. You should not edit these files directly — the CLI manages them.
| File | Purpose |
|---|---|
HEAD | Points to the current commit |
index.json | Tracks installed artifacts and their versions |
config.json | Local CLI configuration (written by ofm configure) |
lock.json | Pinned versions and checksums for reproducible installs |
commits/ | Commit history for artifact changes |
objects/ | Content-addressable object store |
The lock file
.ofm/lock.json pins the exact version and checksum of every installed artifact. This ensures that running ofm add on a different machine produces the same result.
Commit the lock file to version control. The CLI updates it automatically when you add, remove, or update artifacts.
Output formats
The CLI supports four output formats for artifact files. Set the default in artifacts.format in the manifest, or override per command with --format.
| Format | Extension | Description |
|---|---|---|
json | .json | Standard JSON. Portable and widely supported. |
yaml | .yaml | YAML. Easier to read and edit by hand. |
typed | .json + .d.ts | JSON file with a companion TypeScript declaration file for type-safe imports. |
ts | .ts | Standalone TypeScript module with the artifact embedded as as const. |
The typed and ts formats are generated by ofm generate or by passing --format typed / --format ts to ofm add.
Use json or yaml if you don't need TypeScript integration. Use typed if you want type-safe imports without changing your JSON source files. Use ts for a single self-contained module.