Skip to content

Helper manifest

A helper library is two things: source, which the host evaluates, and a manifest, which describes what is in it.

This page is the manifest’s reference. For what libraries are and how to write one, see Helper libraries.

Because three things need to know what a library offers without running it:

  • The formula editor, for autocomplete and signatures.
  • The validator, to reject a call to a function that does not exist — at validation, rather than on row 300.
  • The AI, which is told what helpers are available so it proposes expressions that will work.

Deriving that by parsing the source would be guesswork. Declaring it is a contract.

The practical consequence: a function missing from the manifest is invisible, even if the source exports it. Adding a function means adding it in both places.

{
"namespace": "acme",
"version": "1.2.0",
"scope": "org",
"description": "ACME-specific transforms.",
"functions": [
{
"name": "accountCode",
"description": "The ACME account code for a customer name.",
"params": [{ "name": "name", "type": "string" }],
"returns": "string",
"examples": [
{ "call": "helpers.acme.accountCode(row.Customer)", "result": "AC-0042" }
],
"tags": ["accounts"]
}
]
}
Field Required Notes
namespace Lower-case identifier. Becomes helpers.<namespace>.*.
version Semver, 1.2.0. Exactly three numeric parts.
scope org or global. Org routes only write org.
description What the library is for.
functions The list below.
Field Required Notes
name An identifier.
description One line. Read by people and by the model.
params Each with name and type; optional and description allowed.
returns A type, as a string.
examples { call, result } pairs.
tags For grouping in the editor.

Types are free-form strings, not a checked type system — string, number, Record<string, unknown>. They document intent for a reader and for the model; they are not enforced at run time.

These are not decoration. The description is what somebody sees in autocomplete at the moment they are deciding whether this is the function they want, and it is what the model reads when proposing a formula.

A function described as “formats a code” will be misused. Described as “The ACME account code for a customer name — returns an empty string when the customer is unknown”, it will not.

Examples are the highest-value field after the description, because they show shape and edge cases in less space than prose:

"examples": [
{ "call": "helpers.acme.accountCode('Northwind Traders')", "result": "AC-0042" },
{ "call": "helpers.acme.accountCode('Unknown Ltd')", "result": "''" }
]

Functions are called under their namespace:

helpers.acme.accountCode(row.Customer)

The one exception is the built-in core library, which is also flattened onto helpers.* — so helpers.trim(…) works as well as helpers.core.trim(…). Your own libraries are always namespaced, which keeps them from colliding with each other or with a future built-in.

The version is semver, and it is what a project pins.

Publishing a new version does not change what an existing project does. A project records the versions it was built against, so a change to a helper cannot silently alter an import that has been running for a year. Somebody updates the project deliberately.

That makes the version meaningful — so use it properly. A changed return shape is a major bump, whatever it looks like from inside the library.

On write. The manifest is checked against the schema, its namespace must match the path it is written to (NAMESPACE_MISMATCH otherwise), and an org route will not accept scope: "global" (GLOBAL_LIBRARY) — a global library belongs to the product, not to an org.

The manifest shape is one of Sloose’s versioned contracts, shared by the widget, the server, the SDK and every customer configuration repository. It does not change without a version bump, so a manifest written today keeps working.

By hand, or as part of a configuration repository alongside the source — which is the better arrangement, because the manifest and the code it describes then change in the same commit and get reviewed together.