Skip to main content
The template manifest is the template: section of lua.skill.yaml that you author, frozen at publish together with the source agent’s promoted version, and served to installers as a display-only projection. This page lists every field of the authored section and the served manifest, and summarizes the install result. The lints that guard the fields are on Lints and consent. Verified against lua-cli 3.33.0.

Sections

lua marketplace template draft writes the section and publish sends it. Whenever the section exists, the eight always-sent sections in the table below (every row except tagline) are sent on every publish, and an absent or empty one clears the server’s copy. The optional tagline is the one exception: it is sent only when its key is present, so leaving it out keeps the current tagline. The env contract is not in the file: declare it with --env-contract "KEY=description" (KEY?= for optional) on publish; omitting the flag keeps the previous version’s contract. The frozen primitives (skills, webhooks, jobs, preprocessors, postprocessors, triggers, workflows, model) are never authored here.

connections[]

One entry per capability the agent plugs into, satisfiable by any platform in its list. Connections the installer already holds are reused; only gaps are requested.
string
required
Stable identity of the capability. Non-empty and unique; renaming it is remove-plus-add for installers.
string
required
Discovery label, for example crm. platforms decides what satisfies it.
boolean
required
true blocks the install until satisfied. false is offered and never blocks; primitives bound to a declined connection are installed inert.
'user' | 'org'
Which grant may satisfy it. Omit to accept either.
string
required
Label of the connect prompt. Non-empty.
string
required
Why the agent needs it. Non-empty.
array
required
At least one { type, oauthScopes? }. type is an integration type such as hubspot; types are unique per entry. oauthScopes is refused at publish while granted-scope capture rolls out.
string[]
Skill keys in this version that depend on the connection. A multi-platform entry whose bound skill calls platform-native tools is refused; narrow platforms or use capability-level access.
lua.skill.yaml
The served manifest enriches each platform with name, authSupport (token, oauth, or both), and scopes as { scope, displayName, description? }.

personaTemplate

The persona with {{VAR}} slots, each declared and typed. Installer answers land on the installed agent; the manifest carries only the declarations.
string | { base?, voice?, text? }
required
The prompt text; the object form matches the persona’s channel branches. At least 40 literal characters must remain across branches beside the slots.
array
required
One declaration per slot. Every {{TOKEN}} needs an entry and every entry must appear in at least one branch.
boolean
required
true lets the installer edit the resolved text; the edit is stored verbatim and wins over substitution.
Each vars[] entry:
string
required
Matches [A-Za-z_][A-Za-z0-9_]*. persona is reserved. Must not collide with an env contract key.
string
required
Form label. Non-empty.
string
required
Help text. Non-empty.
'string' | 'number' | 'boolean' | 'enum' | 'model'
required
model holds a model code; enum and maxLength are not allowed on it.
boolean
default:"false"
A var that is not required must carry a default.
string | number | boolean
Must match type; for enum, a member of the list.
string[]
Required for type: enum: unique, non-empty strings. Not allowed on other types.
string
Input placeholder, for example Acme Inc..
integer
default:"256"
Strings only; 1 to 2000.
{ param: string, equals: string[] }
Ask only while param (another var or an env contract key) has one of equals. A conditional var must carry a default. Rules under showIf rules.
lua.skill.yaml

triggerPresets

A map keyed by trigger key covering the version’s jobs, webhooks, triggers, and connection-event triggers. Keys you don’t author default to { enabled: true }; connection-event keys are always enabled: false.
boolean
required
Recommended default. The desktop install form asks the installer to confirm each key; a CLI install arms the recommended defaults. true is refused on a connection-event key.
string
Falls back to the primitive’s name, then the humanized key.
string
What enabling does.
array
Schedule fields the installer may change. Not allowed on connection-event keys. Every job with a cron schedule gets a preset.timezone entry at publish whether or not you declare one.
Each editableParams[] entry:
string
required
preset.seconds on an interval schedule, preset.timezone on a cron schedule, or workflowRef.input.<dotpath> for a workflow schedule’s input. One entry per path.
string
required
Form label; a raw path is never shown.
string
Help text under the field.
string
Display only, for example minutes.
number
default:"60"
For preset.seconds: at least 60 and a multiple of 60.
number
At least min.
number
default:"60"
For preset.seconds: a multiple of 60.
Interval schedules run on whole minutes, so seconds is 60 or a multiple of it, both in the frozen job and in the envelope; the frozen schedule must satisfy its own envelope, and a once schedule cannot be published. workflowRef.input.* entries may also carry default and required.
lua.skill.yaml

paramsMeta

Display metadata for env contract keys, keyed by the key. Every key must exist in the contract, and once the section is present every contract key needs an entry with a displayName.
string
required
Form label. Non-empty.
string
Falls back to the contract’s description.
'string' | 'number' | 'boolean' | 'enum' | 'model'
required
Values are stored as strings; the type drives validation. A model value is not checked against the model catalog at install.
string | number | boolean
Must match type; for enum, a member.
string[]
Required for type: enum; unique, non-empty strings.
string
Input placeholder.
integer
Strings only; 1 to 2000.
number
Numbers only; finite and not greater than max. A numeric default must fall inside the range.
number
Numbers only; finite.
{ param: string, equals: string[] }
Ask only while param (another env contract key) has one of equals. A hidden key is neither required nor validated, and any value for it is cleared.
Keys under LUA_TRIGGER_URL__ are reserved: at install the platform writes one such variable per webhook-source trigger, holding that install’s trigger URL, and removes it at uninstall.
lua.skill.yaml

tagline

A one-line pitch for the Hire card, shown ahead of the description. Optional; when it is absent the card uses the description.
  • Up to 90 characters, counted after runs of spaces and line breaks are collapsed to one space and the ends trimmed. Longer is refused: by the CLI before anything is sent (template.tagline in lua.skill.yaml is 95 characters; keep it to 90 or fewer) and by the server with 400 TAGLINE_TOO_LONG, before the publish takes a version number.
  • Sent on publish only when the key is present. Leave the key out to keep the current tagline; set it to an empty value to clear it.
  • It is listing copy, like the description: it belongs to the template, not to one version, and it changes when the publish lands (for a public template, before the version is approved). lua marketplace template create --tagline and PATCH /marketplace/templates/:templateId set it too.
  • Lua staff may edit the tagline on the listing. draft writes the listing’s tagline into template.tagline when the listing has one, and says so (tagline: updated from the listing); when the listing has none it keeps the file’s value, including one you have not published yet.
  • When the file’s tagline differs from the listing’s, publish warns that it replaces it (The listing's tagline is "…"; this publish replaces it with …). In a terminal it asks first; declining stops the publish and points to draft. Under --yes, --force, --ci or without a terminal it warns and carries on; with --json the warning goes to stderr. Run draft before publish to keep a staff edit.
  • If the listing cannot be read, draft and publish carry on without the pull or the warning.
Needs lua-cli 3.57.0 or later.

onInstall, onUninstall, sharedData, installPolicy

onInstall and onUninstall are { tool?, instruction? } with at least one field; sharedData is a list of { name, access: 'read' | 'write' }; installPolicy is { perWorkspace: 'single' | 'multiple' }. Fields, timing, and refusals are on Lifecycle hooks.

Served manifest

Installers read a projection of the frozen version: display metadata and requirements, never code, trigger instructions, or values. Fields are enriched at read time.
object
array
key, displayName, description, version; source (agent or marketplace) with marketplaceSkillId and versionId when composed from a marketplace skill.
array
The authored entries with each platform enriched: { type, name, authSupport, oauthScopes?: { scope, displayName, description? }[] }.
array
array
{ template, vars[], editable }
The authored section; each var carries name, displayName, description, type, and any required, default, enum, placeholder, maxLength, showIf.
array
Per frozen workflow: key, displayName, description?, version, form (graph or script), stepCount, hasApproval, hasSchedule, hasSignalWait, hasJobTier, and, when set, jobSecondsMax, inputSchema, outputSchema, budget, concurrencyPolicy, schedule, scheduleInput, workspace, params, outputVisibility, envTemplateKeys, knowledge, replyChannels, protocolVersion, phases, scriptSurface. Absent on a version without workflows.
object
Served verbatim so the install and uninstall screens can show them; onInstall.startWorkflow serves the workflow key only.

Install result

lua marketplace template install --json prints the install result: the ledger row (templateId, agentId, orgId, installedVersion, appliedAgentVersion, status of installed or apply_failed, lastError, allowCreatorUpdates, appliedBy, appliedAt, installedBy), the outcome fields armedTriggers, blockedTriggers, unwatchedTriggers, triggerEndpoints, hiddenParamsCleared, and personaSkipped, and the lifecycle hook outcomes. The field reference, the request bodies, and the one-call deploy result are on the agent templates API. The install request the CLI sends carries version, envValues (from --env-vars), and allowCreatorUpdates only; contentHash, connectionSelections, triggerOverrides, personaVars, editedPersona, acceptModifiedPrimitives, acceptWithdrawnParams, and model are REST-only fields of the same route, so persona answers, connection choices, trigger overrides, and drift acceptance come from the desktop install form or the agent templates API. envValues is a request field, never a result field. The publish request carries sourceAgentVersion, changelog, envContract, the seven sections, and skipAutoApply; the version response adds approvalStatus (public templates), autoApplyRunId, and autoApplyTargetCount when a fan-out was started.

See also