Skip to content

Configuration reference

Running hailer-sdk ws-config pull writes your entire workspace into a workspace/ directory of TypeScript files. You edit those files and push them back. This section documents every file and every property you can configure in it.

The workspace/ directory

workspace/
├── .metadata.json                  # sync snapshot — DON'T EDIT (regenerated on every pull)
├── workflows.ts                    # registry of workflows (create/delete workflows)
├── teams.ts                        # workspace teams
├── groups.ts                       # workspace groups
├── insights.ts                     # workspace insights (reports)
├── apps.ts                         # workspace apps
├── enums.ts                        # generated id enums — DON'T EDIT
├── hailer.d.ts                     # generated type definitions — DON'T EDIT
└── <WorkflowName>_<id>/            # one folder per workflow
    ├── main.ts                     # workflow settings
    ├── fields.ts                   # field definitions
    ├── phases.ts                   # phase definitions
    ├── functions/                  # function-field code (if any)
    ├── templates.ts                # document-template registry (if the workflow has templates)
    └── templates/<TemplateName>_<id>/
        ├── template.config.ts      # template field mappings + options
        └── template.code.ts        # PDF/CSV generation function
FileConfiguresReference
workflows.tsWhich workflows exist (create / delete)Workflows
<workflow>/main.tsA workflow's settingsWorkflows
<workflow>/fields.tsA workflow's fieldsFields
<workflow>/phases.tsA workflow's phasesPhases
<workflow>/templates.ts + templates/Document templatesTemplates
teams.tsWorkspace teamsTeams
groups.tsWorkspace groupsGroups
insights.tsWorkspace insightsInsights
apps.tsWorkspace appsApps

enums.ts, hailer.d.ts, and .metadata.json are generated — never hand-edit them. Every editable file imports its types from hailer.d.ts, so your editor autocompletes and type-checks every property described in this reference.

How push decides: create, update, delete

Each configurable file exports an array (or, for main.ts, a single object). Every push command compares three things for each item: your local version, the current remote version, and the snapshot recorded at your last pull (.metadata.json). The rules are identical for workflows, fields, phases, teams, groups, insights, apps, and templates.

Create

An item without an _id (for templates, without a templateId) is treated as new and created on the server. After creating, the SDK assigns the real id — run pull to bring it into your local files.

typescript
// A new field: no _id → created on push
{ label: "Priority", type: "textpredefinedoptions", data: ["Low", "High"] }

Update

An item with an _id is matched to its remote counterpart and updated only if something changed. The SDK hashes the normalized local and remote versions and compares both against the snapshot:

Local vs remoteSince last pullResult
IdenticalSkip (nothing to do)
DifferentOnly you changed itUpdate
DifferentOnly the server changed itSkip — pull first
DifferentBoth changed itSkip — conflict, pull and reconcile
DifferentNo snapshot entry existsSkip — pull first to establish a baseline

This is why you should always pull before editing and pull again after pushing: the snapshot is what lets the SDK tell your change apart from someone else's.

Delete

An item present on the server but absent from your local file is deleted — but only if the snapshot has a hash for it (proving it existed at your last pull). If there's no snapshot entry, the SDK assumes it was created remotely after your pull and skips the deletion to avoid data loss. Deletions prompt for confirmation unless you pass --force.

System fields are ignored

Before hashing, the SDK strips server-managed fields (_id, cid, uid, created, updated, and a handful of computed/immutable properties per entity). Editing those has no effect — they're documented as read-only on each page. What remains is what you actually control.

The sync snapshot (.metadata.json)

pull writes .metadata.json at the workspace root: a content-hash snapshot of every item as it existed on the server at pull time.

jsonc
{
  "version": 1,
  "pulledAt": 1779171963557,
  "workflows": {
    "<workflowId>": {
      "self": "<hash>",                       // main.ts
      "fields":    { "<fieldId>": "<hash>" },
      "phases":    { "<phaseId>": "<hash>" },
      "templates": { "<templateId>": "<hash>" }
    }
  },
  "teams":    { "<teamId>":    "<hash>" },
  "groups":   { "<groupId>":   "<hash>" },
  "insights": { "<insightId>": "<hash>" },
  "apps":     { "<appId>":     "<hash>" }
}

Commit it to git. Sharing the snapshot gives teammates the same divergence baseline, so everyone's pushes detect conflicts against the same reference point. If the file is missing (first run after an upgrade, or someone deleted it), push and sync refuse to update or delete items they can't verify — run pull to rebuild the baseline.

Hailer Developer Documentation