Skip to content

Workflows

Workflows (called processes internally) are configured in two places:

  • workspace/workflows.ts — the registry that decides which workflows exist. ws-config workflows sync creates and deletes workflows from it.
  • workspace/<WorkflowName>_<id>/main.ts — one workflow's settings. ws-config workflows push updates them via the process.set_info API.

Creating/deleting a workflow (the registry) is separate from editing its settings (main.ts) because they hit different endpoints and have very different blast radius.

workflows.ts — the registry

pull generates this file with one entry per workflow (WorkflowEntry):

typescript
export const workflows: WorkflowEntry[] = [
  { _id: "abc123", name: "Sales Pipeline", enableUnlinkedMode: false, folder: "Sales_Pipeline_abc123" },
  { name: "Customer Support" },                       // new — omit _id to create on sync
  { name: "Contacts", enableUnlinkedMode: true },     // create as a dataset, not a workflow
];
PropertyTypeNotes
_idstring?Present for existing workflows. Omit to create. Never change it.
namestringWorkflow name. Required.
enableUnlinkedModeboolean?true creates a dataset (unlinked mode) instead of a pipeline workflow.
folderstring?Local folder name; auto-generated on pull.

The entry is spread into the process.create call, so all properties on it (name, enableUnlinkedMode, folder) are sent on sync. Every other setting is configured afterwards in main.ts via workflows push.

Create a workflow by adding an entry without _id, then run workflows sync and pull — the SDK creates it, assigns the id, and generates its <WorkflowName>_<id>/ folder. Delete by removing its entry and running workflows sync (snapshot-guarded, prompts unless --force). Never hand-create or delete workflow folders — pull manages them — and never change the _id inside a folder name.

main.ts — workflow settings

pull writes main.ts as a single HailerWorkflowUpdatePayload object, generated from the workflow minus its fields, phases, and server-managed properties. Ids inside it are replaced with enum references from ../enums (e.g. WorkspaceMembers.John_Doe_c19).

typescript
import { WorkspaceTeams, WorkspaceMembers } from "../enums";

export const workflowConfig: HailerWorkflowUpdatePayload = {
  _id: "abc123",
  name: "Sales Pipeline",
  description: "Track deals from lead to close",
  defaultView: "kanban",
  // ...settings below
};

_id is required for matching but not sent in the update body. On push everything else is sent to process.set_info, so all the settings below are editable.

Core

PropertyTypeDescription
namestringWorkflow name.
descriptionstring?Workflow description.
defaultView"table" | "kanban" | "wall" | "calendar"View shown when the workflow opens.
ordernumber?Sort order in the workflow list.
coverImagestring?File id of a cover image.
keystring?Custom unique identifier for the workflow.

Ordering

PropertyTypeDescription
fieldsOrderstring[]Field ids in display order. Reorder here to reorder fields.
phasesOrderstring[]Phase ids in display order.

Field/phase definitions live in fields.ts / phases.ts; only their order is set from main.ts.

Members & permissions

typescript
members: [
  { id: HailerMembers.Sales_Team_abc, info: {}, permissions: ["any"] },
  { id: HailerMembers.John_Doe_c19,   info: {}, permissions: ["own"] },
]

members is an array of HailerMember. Each id is prefixed (user_, team_, group_, network_) — use the generated HailerMembers enum. permissions is drawn from:

PermissionMeaning
anyAny activity in the workflow.
ownOnly activities they own.
ownteamOnly activities owned by their team.
adminFull administrative control of the workflow.

Feature flags

FlagEnables
enableUnlinkedModeDataset mode (activities aren't linked into a pipeline).
enableMessengerPer-activity discussion/messenger.
enableAttachmentsFile attachments on activities.
enableMapLocationLocation field / map view.
enableUniqueNameEnforce unique activity names.
enableOwnerFieldShow an activity owner field.
enableOwnerTeamFieldShow an owner-team field (label via ownerTeamFieldTitle).
enableAddedFieldShow the created-timestamp field.
enableModifiedFieldShow the updated-timestamp field.
enableLinkedAnnouncementsReceive announcements when linked activities change.
enablePreselectedTeamPreselect a team on new activities (see preselectedTeam).
enableGuestEditingLet guests edit (requires allowGuests).
enablePredefinedNameUse a predefined name prefix (predefinedNamePrefix).

Activity name

PropertyTypeDescription
nameEditableboolean?Whether users can edit the activity name.
nameColumnTextstring?Header text for the name column.
nameFieldPlaceHolderTextstring?Placeholder in the name field.
createNewLabelstring?Label on the "create new" button.
predefinedNamePrefixstring?Prefix used when enablePredefinedName is on.
nameFunctionEnabledboolean?Generate the activity name from code.
nameFunctionstring?JavaScript that returns the activity name.
nameFunctionVariablesRecord<string, HailerFieldFunctionVariable>Field dependencies for nameFunction (see Fields → Function fields).

Teams, guests & people

PropertyTypeDescription
allowGuestsboolean?Allow guest access.
preselectedTeam{ team; account }Team preselected on new activities. pull may return null; push normalizes null → unset.
personInChargestring?Default person-in-charge user id.
personInChargeLabelstring?Custom label for person-in-charge.
ownerTeamFieldTitlestring?Label for the owner-team field.
initPhaseDescriptionstring?Title used for new-activity feed announcements.
discussionPermissionsDiscussionPermission[]?Per-activity discussion permissions.

Translations

Workflow UI texts can be translated per locale (en, fi, sv) via the translations map. pull writes it into main.ts when the workflow has translations remotely; workflows push applies local changes. Field and phase ids appear as enum keys:

typescript
translations: {
  fi: {
    name: "Liidit",
    createNewLabel: "Uusi liidi",
    fields: {
      [Leads_FieldIds.status_c19]: { label: "Tila", placeholder: "Valitse tila" },
    },
    phases: {
      [Leads_PhaseIds.new_4a2]: { name: "Uusi" },
    },
  },
  sv: { /* ... */ },
},

Accepted keys per locale (max lengths enforced by the API — anything else is rejected, so e.g. predefined-option values (data) are not translatable):

LevelKeys
Workflowname (96), description (1024), nameColumnText (64), nameFieldPlaceHolderText (128), createNewLabel (96), personInChargeLabel (64), predefinedNamePrefix (32), initPhaseDescription (128), ownerTeamFieldTitle (64)
fields.<fieldId>label (128), unit (20), placeholder (256), description (256), defaultValue (128)
phases.<phaseId>name (96), description (256), possibleNextPhaseSettings.<phaseId>.text (128)

How push applies translations:

  • The local map is a full replace. It overwrites the remote map entirely — removing a locale, field, or phase entry from main.ts deletes that translation remotely on push.
  • Delete-all is deliberately not supported. When translations is absent or empty locally, push skips them entirely, so a main.ts from before translations support (or a workflow that never had translations) can never wipe the remote map.
  • Keep the default locale in sync with the base settings. Hailer shows the translation value when present and falls back to the base setting otherwise.

Also accepted (not populated on pull)

HailerWorkflowUpdatePayload additionally accepts these — pull doesn't write them, but you can add them to main.ts and they'll be sent to process.set_info: locationRequired, tags, allowMultipleTags, allowCustomTags, requireFileTag, defaultGroupByField, color, activityTaggingPhaseIds.

Read-only / managed elsewhere

Not present in main.ts (the SDK strips them before writing and before hashing) — editing them here has no effect:

  • System: cid, uid, created, updated, version, isStarred. _id is the match key — retained in the local file but not sent in the update body.
  • fields / phases — edit in fields.ts / phases.ts.
  • documentTemplates — edit via templates.
  • publicForm, workflowSuite, phasesRemoved, createdActivities, groupNames, enableActivityTagging, autoPickPreselectedTeam.

Commands

  • ws-config workflows sync — create/delete workflows from workflows.ts.
  • ws-config workflows push — update main.ts settings (never creates or deletes workflows; note that the translations map is replaced wholesale — see Translations).

See the sync model for how changes are applied.

Hailer Developer Documentation · v1.3.4