import { A as AgentSnapshotRow, T as TemplateSpec, a as TemplateTable, S as SharedBlockId, C as CapabilityWord, b as TemplateField, c as TemplateAgent, d as TemplateAutomation, e as TemplateBooking, f as TemplateChecklist, g as TemplateDashboard, h as TemplateDigest, i as TemplateDocument, j as TemplateDrillDown, k as TemplateDimensions, l as TemplateForm, m as TemplateNotification, n as TemplatePortal, o as TemplateRowAction, p as TemplateStageRules, q as TemplateView, r as TemplateMergeBinding, s as TemplateTryIt, t as TemplateWorkflow, u as TemplateFootprint, I as IndustryGroup, v as TemplateJob, w as TeachesFeature, x as TemplateViewKind, y as TemplateBookingWindow } from '../types-BW9Lvrku.js'; export { z as CAPABILITY_WORDS, B as CATALOGUE_QUOTAS, D as CATALOGUE_STATUSES, E as CHOICE_COLORS, F as CHOICE_COLORS_DISTINCT_UP_TO, G as CHOICE_COLOR_ALIASES, H as CatalogueRow, J as CatalogueStatus, K as ChoiceColor, L as ChoiceColorAlias, M as ConfidentialLevel, N as ConfidentialRequest, O as DEFAULT_TEMPLATE_AGENT, P as ENTITY_REFERENCE_KINDS, Q as INDUSTRY_GROUPS, R as RELATIVE_DATE, U as RetiredId, V as SHARED_BLOCKS, W as SHARED_BLOCK_IDS, X as STAMP_ME, Y as STAMP_NOW, Z as STRENGTHS, _ as SharedBlock, $ as SharedBlockField, a0 as SharedBlockUse, a1 as Strength, a2 as TABLE_KERNEL_ID, a3 as TEACHES_FEATURES, a4 as TEMPLATE_AUDIENCES, a5 as TEMPLATE_EXTRA_KINDS, a6 as TEMPLATE_JOBS, a7 as TEMPLATE_REFERENCE_DATE, a8 as TEMPLATE_RELATIVE_DAYS, a9 as TEMPLATE_SPEC_VERSION, aa as TEMPLATE_VIEW_KINDS, ab as TemplateAgentQuestion, ac as TemplateAgentVariable, ad as TemplateAudience, ae as TemplateAutomationWhen, af as TemplateCalendarView, ag as TemplateChecklistStep, ah as TemplateConfidential, ai as TemplateConfidentialReader, aj as TemplateDashboardBlock, ak as TemplateDimensionOverride, al as TemplateDrillPath, am as TemplateExtra, an as TemplateExtraAgent, ao as TemplateExtraAgentVariable, ap as TemplateExtraKind, aq as TemplateFormField, ar as TemplateFoundation, as as TemplateGalleryView, at as TemplateGridView, au as TemplateGuideStep, av as TemplateKanbanView, aw as TemplateMapView, ax as TemplateMeasureOverride, ay as TemplateOrgChartView, az as TemplatePivotView, aA as TemplatePortalTable, aB as TemplateProvenance, aC as TemplateRelativeDay, aD as TemplateRelativeWindow, aE as TemplateRowTemplate, aF as TemplateSource, aG as TemplateTableSettings, aH as TemplateTimelineView, aI as TemplateViewSort, aJ as UseCaseSingulars, aK as WalkAction, aL as WalkAssertion, aM as WalkImport, aN as WalkMove, aO as WalkStep, aP as canonicalChoiceColor, aQ as confidentialPending, aR as confidentialRequests, aS as footprintOf, aT as isPressDayWord, aU as membersAddRowsSteps, aV as tableSettingsProblems, aW as whenRule } from '../types-BW9Lvrku.js'; import { AggregateMeasure, AggregateFilter } from '../core/index.js'; import { UseCase, UseCaseRelationship } from '../use-cases/index.js'; import { UseCaseProblem } from '../use-cases/index.js'; export { R as RESOLVABLE_FIELD_TYPE_WORDS } from '../validate-Dkl8MjA4.js'; import { RecordsDataSource } from '../core/index.js'; import '../record-C3thPhpR.js'; import '../rule-CMApHawk.js'; import '../field-IlJ97y8H.js'; /** The UTC offset ("-04:00") of a local wall-clock moment in an IANA zone. */ declare function zoneOffset(localIso: string, timeZone: string): string; /** One token → "2026-10-08" or "2026-10-08T09:30:00-04:00". `null` when it is not a token. */ declare function resolveDateToken(token: string, today: string, timeZone: string): string | null; /** True when the token carries an explicit time of day. */ declare function relativeHasTime(token: string): boolean; /** * Every relative-date token anywhere in the spec, resolved against `today` (the install * day, "YYYY-MM-DD") in the business's time zone. Returns a copy; the input is untouched. */ declare function resolveRelativeDates>(spec: T, today: string): T; /** An exact decimal as a fraction, so nothing is rounded (Postgres numeric is exact). */ interface Q { n: bigint; d: bigint; } /** `text::numeric` as Postgres reads it, or null when Postgres would refuse the cast. */ declare function parseNumeric(text: string): Q | null; /** `custom.agg_value_sql`: the Value envelope's `value` when there is one, else the key; as TEXT (`->>`). */ declare function storeText(v: unknown): string | null; /** A JSON number as jsonb `->>` prints it: plain digits, never "1e+21" or "1e-7". */ declare function numberText(n: number): string; /** The value inside a Value envelope ({value: …}), or the value itself. */ declare function unwrap(v: unknown): unknown; interface SeedRow { key: string; values: Record; archived?: boolean; } /** custom.record_filter_sql (flat map): scalar = TEXT equality, null = absent/JSON-null (never ""), object = half-open window. */ declare function storeFilterMatches(row: SeedRow, filter: Record | undefined, _timeZone: string): boolean; type AggregateOutcome = { ok: true; value: number | null; exact: boolean; } | { ok: false; says: string; }; /** * custom.record_aggregate for ONE measure over seed rows (live, non-archived), as the store * computes it: count(*); sum/avg/min/max/median/range over `nullif(text,'')::numeric` (a text that * is not a number is a refusal; no values at all is NULL, not 0); filled/empty/unique by * `nullif(text,'')`; percent_empty/percent_filled as 100 x share of the rows (NULL over none). Exact: an average that does not terminate is reported as inexact. */ /** * The functions a formula may call — THE one list, `@ai-matrx/kit/formula` (mirrors the store's * custom.formula_node_kinds(); architecture D6). The gate parses with kit's parser too, and keeps * only its own EXACT evaluator below: numbers are read from the digits as typed into fractions. */ declare const FORMULA_FUNCTION_NAMES: ReadonlySet; type FxNode = { k: "num"; v: Q; } | { k: "str"; v: string; } | { k: "ref"; v: string; } | { k: "bin"; op: string; a: FxNode; b: FxNode; } | { k: "neg"; a: FxNode; } | { k: "call"; f: string; args: FxNode[]; }; /** Parse a formula text with the one parser, or say what is wrong with it. */ declare function parseGateFormula(text: string): FxNode | string; /** Every `{Label}` a formula reads. */ declare function formulaRefs(n: FxNode): string[]; /** * custom.formula_eval for the part the gate mirrors exactly: + − × ÷ % (an empty value counts as * 0), ABS, and DATEDIFF (whole units, truncated toward zero). Anything else answers "unsupported", * and a question over it is refused rather than guessed. */ declare function evalFormula(n: FxNode, valueOf: (label: string) => unknown): { ok: true; v: Q | null; } | { ok: false; why: string; }; /** A view's rows: its flat `filters` (equality, null, window) AND each `anyOf` (`where`: or of eq). */ declare function viewMatches(row: SeedRow, view: { filters?: Record | undefined; anyOf?: Record | undefined; }, timeZone: string): boolean; declare function storeAggregate(rows: SeedRow[], measure: AggregateMeasure, filter: Record | undefined, timeZone: string): AggregateOutcome; /** Stage names that say when something happened (their dates are never "any" without a reason). */ declare const TIME_BOUND_STAGE: RegExp; /** The first of the field's own rules a value breaks, as a sentence; null when it obeys them all. */ declare function ruleBreak(field: TemplateField, v: unknown): string | null; /** A shared block's table as this template seeds it. */ declare function blockTable(block: SharedBlockId, rows: TemplateSpec["sharedBlocks"][number]["rows"]): TemplateTable; /** The template's own tables plus every shared block it seeds. */ declare function allTables(spec: Pick): TemplateTable[]; type Partial5 = Partial>; /** A template seen as a use case: the five singulars are there when the template carries them. */ type DerivedUseCase = Omit & Partial5; /** * The template as a use case, for every existing use-case consumer: the singulars come from * forms[0], the first stage_rules, the agent's question, the first document and the first * notification WHEN the template has them. A template owes at least two extras (handoff §5), * not one of each kind, so a missing singular is simply absent — never an error. */ declare function toUseCase(spec: TemplateSpec): DerivedUseCase; /** validateUseCase over the derived use case, minus the "a use case owes a …" lines a template does not owe. */ declare function useCaseProblemsOf(spec: TemplateSpec): UseCaseProblem[]; /** * The layouts records-ui draws today — a MIRROR of `VIEW_LAYOUTS` in * `apps/shared/records-ui/src/views.ts` (records cannot import records-ui). A test reads * that file and fails when the two disagree. */ declare const RECORDS_UI_VIEW_LAYOUTS: readonly ["grid", "kanban", "calendar", "gallery", "timeline", "list", "chart", "map", "orgchart", "pivot", "swipe"]; /** Mirror of records-ui `CalendarMode` (CalendarView.tsx). */ declare const RECORDS_UI_CALENDAR_MODES: readonly ["month", "week", "day", "list"]; /** * Field surfaces records-ui draws beyond the plain kinds, each checked against records-ui by * the suite: `rating` (a number with format rating — FieldFormatPicker), `signature` (drawn on * the form and seen as a drawing — docs.ts / SignBlock). */ declare const RECORDS_UI_FIELD_SURFACES: readonly ["rating", "signature"]; interface CapabilityStatus { word: string; provided: boolean; by: string; } declare function capabilityStatus(word: string): CapabilityStatus; /** Every capability the spec USES. `requires` must equal this set — no less, no more. */ declare function capabilitiesUsed(spec: TemplateSpec): Set; /** The designated test numbers (aidream/designated_test_recipients.py): real handsets, never seed data. */ declare const DESIGNATED_REAL_NUMBERS: readonly ["9498072145", "9496662578", "9497027626"]; /** Unicode digits → ASCII, every dash/hyphen → "-", every odd space → " " (so a disguised number reads as one). */ declare function normalizeForPhones(text: string): string; /** * Every number in `text` that is not fictional: a NANP number outside 555-0100…0199 (or a * designated real handset), or an international number outside the UK's Ofcom drama ranges. * `phoneField` = the text IS a phone value, so bare digits count; in prose a number needs * separators, so an NPI or an order number is never read as a phone. */ declare function phonesOutsideFictionalRange(text: string, phoneField?: boolean): string[]; /** Public mail providers: real domains millions of real people use — never "fictional". */ declare const PUBLIC_MAIL_DOMAINS: readonly ["gmail.com", "googlemail.com", "outlook.com", "hotmail.com", "live.com", "msn.com", "yahoo.com", "ymail.com", "icloud.com", "me.com", "mac.com", "aol.com", "proton.me", "protonmail.com", "pm.me", "zoho.com", "gmx.com", "gmx.net", "mail.com", "yandex.com", "fastmail.com", "hey.com", "tutanota.com", "comcast.net", "verizon.net", "att.net", "sbcglobal.net", "bellsouth.net", "cox.net", "qq.com", "163.com", "web.de"]; /** Every domain an email, a website or a url in the text uses. */ declare function domainsIn(text: string): string[]; /** "4127 Calloway Palm Way, Suite 6" → "Calloway Palm Way"; no house number → null. */ declare function numberedStreet(line: string): string | null; /** * A NEW table whose sample rows point at sample rows the PREVIOUS version did not have. The upgrade handles it (it * adds the new rows first and fills each link once its target exists), but a person upgrading sees rows appear in * more than one table at once, and a link whose target the person deleted is left empty; the author should know. * Pure: reads two specs, returns one warning per (new table, link field). Never counted against `ok`. */ declare function newRowsPointAtNewRows(previous: Pick, current: Pick): UseCaseProblem[]; type TemplateStatus = "pass" | "fail" | `waiting on ${string}`; interface TemplateVerdict { ok: boolean; status: TemplateStatus; problems: UseCaseProblem[]; waiting: CapabilityStatus[]; /** * OFFERS, NEVER BLOCKS (TEMPLATE-GAPS 7): what the checker would ADD (state how a child's dates or statuses * agree with its parent's). Never counted against `ok`. A rule a template DOES state is still checked * against its rows and refuses when broken. */ suggestions?: UseCaseProblem[]; /** TEMPLATE-FRESH-3: upgrade notes for the author (see newRowsPointAtNewRows); only when `options.previous` is given. Never blocks. */ warnings?: UseCaseProblem[]; } interface ValidateOptions { /** templates/AGENTS.snapshot.json — the platform agents a template may copy. */ agents?: AgentSnapshotRow[]; /** * The rest of the library (every other template file), so a template copied from another can * be told it still carries that business's names, people or sentences. * G1 always passes it; a single-file check without it skips only this cross-file rule. */ library?: { specs: TemplateSpec[]; signatures?: unknown; }; /** * "gallery" (default): a published platform template — the full bar. * "describe": a private one-off spec made from one sentence (the /make describe box). Its tables, * fields, links, forms, views and booking pages are held to the same rules; what only a gallery * card needs is not asked for — catalog keys, strengths, provenance, the teaching walk, the agent, * seed rows and how the seed looks on screen — and `requires` is worked out, never written. */ profile?: "gallery" | "describe"; /** The previous published version of this template: asks for the upgrade warnings (`verdict.warnings`). */ previous?: TemplateSpec; } /** Every piece of text a person reads in the template, with where it sits. Keys and tokens are not text. */ declare function templateText(spec: TemplateSpec): Array<[string, string]>; /** People named in a template: its team and its person-name columns. */ declare function peopleOf(spec: TemplateSpec): string[]; declare function foreignTextProblems(spec: TemplateSpec, library: { specs: TemplateSpec[]; signatures?: unknown; }): UseCaseProblem[]; declare const MAIN_TABLE_ROWS_MIN = 20; declare const MAIN_TABLE_ROWS_MAX = 50; declare const TABLES_MIN = 2; declare const TABLES_MAX = 8; /** At least this share of a table's rows carry a title nobody else has. */ declare const TITLE_DISTINCT_SHARE = 0.9; /** One platform picture as templates/ASSETS.json lists it (written by `pnpm templates:assets`). */ interface TemplateAssetRow { key: string; fileId: string; name: string; mime: string; bytes: number; publishedToWeb: boolean; } /** * seed.attachments, as written: every `attachments` entry is whole, every attachment-field value is * "@file:" naming one of them, and every listed picture is used. With `assets` (ASSETS.json), * each attachment must BE a library picture (same key and file id) that is published to the web — * a picture only its uploader can read would show members an empty card. */ declare function attachmentProblems(raw: TemplateSpec & { attachments?: Array>; }, assets?: TemplateAssetRow[]): UseCaseProblem[]; declare function validateTemplate(raw: TemplateSpec, options?: ValidateOptions): TemplateVerdict; /** Validate and throw with every problem. A waiting template does not throw — it is held, not broken. */ declare function assertTemplate(spec: TemplateSpec, options?: ValidateOptions): TemplateVerdict; /** Choice words that are a good outcome (never painted red) and a bad one (never painted green). One reading for the check and the describe autofix. */ declare const GOOD_OUTCOME: RegExp; declare const BAD_OUTCOME: RegExp; /** * The lowest sensitivity the store accepts for a field, by what it holds: "restricted" (kept from the AI: * an identity or health fact about a person, a code, a card or bank number, privileged notes), * "confidential" (it reaches a person or a home: a phone, an email, an address), or null (no floor). * The template check refuses anything below it; the describe box fills an omitted sensitivity up to it. */ declare function sensitivityFloorOf(table: Pick, f: Pick): "restricted" | "confidential" | null; type Uuid = string; /** The binding a host writes onto the copied agent's variable (the kit `merge_field` shape). */ interface TemplateAgentBinding { variable: string; tableToken: string; tableId: Uuid; describes: string; } interface TemplateAgentCopyRequest { organizationId: Uuid; platformAgentId: string; platformAgent: string; name: string; bindings: TemplateAgentBinding[]; /** * The host calls this the moment the fork returns the new agent's id, BEFORE naming or binding * it, so a failure after the fork never loses the id: the footprint keeps it either way. */ onCreated?: (agentId: Uuid) => void; } /** * A date WITH a time ("@today-3d 09:30"), declared as `format: "datetime"`. custom.table_from_example * forwards no `kind`, and the store makes every datetime it is not told about a whole-day date — a * calendar of all-day blocks. These columns are declared through field_declare with kind datetime. */ declare const isTimedField: (f: TemplateField) => boolean; /** * A column table_from_example cannot make as declared, so the installer declares it itself through * custom.field_declare, before any row: a date WITH a time (the door forwards no `kind`) and any * column with a `default` (the door forwards no default, and a form that does not ask a required * column relies on it — "Patient status" starts as New). */ /** * TEMPLATE-GAPS (c): the store's stamps — filled by the store, never typed or seeded. Declared through * custom.field_declare BEFORE the rows, so an autonumber numbers the seed rows as they are written. */ declare const STAMP_KINDS: ReadonlySet; declare const isSelfDeclaredField: (f: TemplateField) => boolean; /** A colored choice list, kept the way the grid reads it: display_format.options.choices. */ declare function choiceDisplayFormat(field: TemplateField): { id: string; options: { choices: Array<{ value: string; color: string; }>; }; } | undefined; /** The look a column is made wearing: its colored choices, else the template's declared look. */ declare function fieldDisplayFormat(field: TemplateField): { id: string; options?: Record; } | undefined; /** * `custom.table_from_example`'s `p_example` for ONE table: its own columns (colored choices * included), no relation columns and no rows. One table per call, because the person's * statement ceiling is 8 s and the door costs ~80 ms a column (measured on the clone, * 2026-10-02: this template's six tables, 63 columns and 106 rows in one call took 12.8 s). * Relations, derived columns and rows follow through their own doors, each call small. */ /** * LANE 10 FD — THE TABLES A TEMPLATE MARKS FOUNDATION, from its ONE source: `spec.foundation` (R13), * the day-one tables it lists with what each is kept for. The main table (`tables[0]`, the day-to-day * work) is never one, even if a list names it (the validator refuses that list too). Both installers * read this through `tableShellPayload`: the table is MADE marked, in the table step itself * (`custom.table_from_example` writes `foundation: true` into its document), so the browser install * and the gallery's server install (`plan.ts` → `custom.template_install`) mark the same tables. */ declare function foundationTokens(spec: Partial>): Set; declare function tableShellPayload(spec: Pick & Partial>, t: TemplateTable): Record; /** `custom.table_from_example`'s `p_example` for EVERY table at once: columns and relations, no rows. */ declare function shellsPayload(spec: Pick, tables: TemplateTable[], deferred?: Map>): Record; /** `custom.field_declare`'s spec for one date-and-time column. */ declare function timedFieldSpec(field: TemplateField): Record; /** * `custom.field_declare`'s spec for one self-declared column (isSelfDeclaredField): every declared * key, its colored choices, its kind for a date-and-time, and its default. */ declare function selfDeclaredFieldSpec(field: TemplateField): Record; /** `custom.field_declare`'s spec for one relation column, its target already made. */ declare function relationFieldSpec(field: TemplateField, targetTableId: Uuid, inverseKey?: string): Record; /** Tables in levels their rows can be written in: every table after the tables it points at. */ declare function rowLevels(tables: TemplateTable[]): TemplateTable[][]; /** * The relation columns whose values cannot travel WITH their row: a link to the table's own rows, * or to a table in the same or a later row level (a circle). Those rows are written without them, * and `relationPatches` sets them once every row exists. table token → field keys. */ declare function deferredRelations(tables: TemplateTable[]): Map>; /** The relation columns `deferredRelations` holds back, with their tables, in template order. */ declare function deferredRelationFields(tables: TemplateTable[], deferred: Map>): Array<{ table: TemplateTable; f: TemplateField; }>; /** * A deferred link that is REQUIRED: its rows would be refused before the link is set. Said before * install, the store's own way ("make one side of the circle optional"). */ declare function requiredCircleProblem(tables: TemplateTable[], deferred: Map>): string | null; /** * The deferred links of one table as `custom.record_change_many` changes: * [{op: "update", record_id, patch: {field: id | ids}}], one per row that has any. */ declare function relationPatches(table: TemplateTable, ids: Map, deferred: Set | undefined): Record[]; /** * One table's rows as `custom.record_write_many` takes them, with ids minted here so every * relation value (a row key in the file) is already a record id. Derived columns carry no value. */ /** TEMPLATE-GAPS R3 (3): the seed word for "the person installing this template" in a member column. */ declare const INSTALLER = "@installer"; declare function rowsFor(table: TemplateTable, ids: Map, deferred?: Set): { rows: Record[]; ids: Uuid[]; }; /** `custom.field_declare`'s spec for one lookup or rollup. */ declare function derivedFieldSpec(field: TemplateField, look?: { id: string; options?: Record; }): Record; /** `custom.view_declare`'s spec. */ declare function viewSpec(view: TemplateView, fieldIds?: Record): Record; /** * A view's whole `where` (S2-PRIME, Fields by id): its any-of conditions, its relative day windows * (`within`, read in the reader's zone) and its "me" person columns, ANDed. Undefined when it has none. */ declare function viewWhere(view: Pick, fieldIds: Record): Record | undefined; /** * A view's any-of conditions as the store's Rule expression (S2-PRIME, Fields by id): * {op: "and", args: [{op: "or", args: [{op: "eq", args: [{field: }, {const: v}]}, …]}, …]}. * A key with no id is a template error said by name, never a silently dropped condition. */ declare function anyOfWhere(anyOf: Record | undefined, fieldIds: Record): Record | undefined; /** * `custom.field_declare`'s spec for a formula column: the store parses `formula_text` and computes it on read. * `look` is the number format the column is DECLARED with (a template's own `look` wins, else `formulaLooksOf`'s * inference), written onto the field like any other column's "Shows as". */ declare function formulaFieldSpec(field: TemplateField, look?: { id: string; options?: Record; }): Record; /** * THE NUMBER FORMAT EACH FORMULA COLUMN OF A TABLE IS INSTALLED WITH, by field key: the one inference * (`formulaLookOf`, shared with the preview and the table display) over the table's own columns, formulas in the * order the store parses them so a formula that reads a money formula is money too. A column with nothing worth * carrying has no entry. `inherited` are the looks a rollup or lookup of the table already took from the column it * reads (`templateLooksOf`), so a formula over such a column is money too. */ declare function formulaLooksOf(table: TemplateTable, inherited?: ReadonlyMap; }>): Map; }>; /** * A table's formula columns in an order the store can parse: a formula that reads another formula * (by its label in braces) comes after it. A cycle keeps template order (the store refuses it by name). */ declare function formulaOrder(table: TemplateTable): TemplateField[]; declare function formArgs(org: Uuid, tableId: Uuid, form: TemplateForm): Record; declare function bookingArgs(org: Uuid, tableId: Uuid, booking: TemplateBooking): Record; declare function dashboardBlocks(dashboard: TemplateDashboard, tables: Record): Record[]; declare function stageRulesSpec(rules: TemplateStageRules): Record; /** * A document body in the store's token form. `{{field_key}}` → `{{field:}}` (REC-68: a token * names a Field by id, so a rename never breaks it); `{{business}}` → the business's own name. * A key with no field is left as written, and the door refuses it by name. */ declare function documentBody(doc: TemplateDocument, fieldIds: Record, businessName: string): string; declare function rowActionList(actions: TemplateRowAction[], fieldIds: Record): Record[]; declare function agentCopyRequest(org: Uuid, agent: TemplateAgent, tables: Record): TemplateAgentCopyRequest; /** The choice field of `table` that holds `stage` as one of its choices. */ declare function stageFieldOf(tables: TemplateTable[], table: string, stage: string | undefined): string | null; /** * A drill-down extra as the store keeps one. The drill PATH is the table's own (declared through * `table_dimensions_set` with the template's Dimensions); there is no door that declares a drill * entry point for a custom table (platform.drill_* serves platform-declared definitions), so the * entry point is a dashboard whose one chart groups by the path's first level — clicking a bar is * the drill through custom.drill_resolve. `custom.dashboard_declare`'s name and blocks. */ declare function drillDownDashboard(drill: TemplateDrillDown, dimensions: TemplateDimensions[]): { name: string; blocks: Record[]; }; /** A digest as `custom.subscription_declare` takes it: the saved view it sends, how often, how. */ declare function digestSpec(digest: TemplateDigest, viewId: string): Record; /** * A checklist as `custom.checklist_declare` takes it (p_spec). Steps that ask for a form or a * document name it by the id the install made (`forms`, `documents`: token → id). */ declare function checklistSpec(checklist: TemplateChecklist, tables: Record, forms: Record, documents: Record): Record; /** An automation has no door yet: lane 11 owes it, and the validator holds such a template. */ declare function automationHeld(a: TemplateAutomation): string; /** The triggers a template automation installs, by the use-case event word. */ declare const AUTOMATION_EVENTS: readonly ["created", "due", "overdue", "becomes", "assigned"]; /** * custom.automation_declare's spec for one template automation: a reminder that tells the person who set * it up (the installer — `to: {author: true}`). `due` waits for the date `daysBefore` days ahead * (offset_days negative), `overdue` the day after it, `created` runs on every new row. Field ids are * install-time refs (`${ref:fields..}`). */ declare function automationSpec(a: TemplateAutomation, fieldIds: Record): Record; /** * Every custom.automation_declare spec one template automation installs: one, except `assigned`, which is two * (an edit of the Person column, and a new row with someone already in it) exactly as custom.field_notify_on_assign * declares them. The first is the template's own name; the second adds " (new)". */ declare function automationSpecs(a: TemplateAutomation, fieldIds: Record): Record[]; /** * What custom.booking_declare requires of its table, said BEFORE install: a `slot` column (the door * writes the booked time into it on confirm, and adds it as a required text column when missing), * and a `status` choice column holding "booked" and "cancelled". Null when the table has both. */ declare function bookingColumnsProblem(tables: TemplateTable[], booking: TemplateBooking): string | null; /** A notification as the store keeps one: a saved view of the stage, and an instant subscription. */ declare function notificationParts(n: TemplateNotification, stageField: string | null): { view: Record; subscription: Record; }; /** `custom.portal_declare`'s arguments: each exposed table names the relation that says "theirs". */ declare function portalArgs(org: Uuid, portal: TemplatePortal, tables: Record): Record; /** * TEMPLATE-GAPS (e): `custom.field_declare`'s spec for a button column, every id as an install token: a link's * `{{field_key}}` becomes `{{}}`, a row action its saved id, an automation its saved id. */ declare function buttonFieldSpec(table: string, field: TemplateField): Record; /** A binding as the install plan carries it: `rowIndex` replaced by the seed row's key. */ interface TemplatePlanBinding extends Omit { rowKey?: string; } interface TemplatePlanExtraAgent { key: string; platformAgent: { id: string; name: string; }; name: string; bindings: Array<{ variable: string; describes: string; binding: TemplatePlanBinding; }>; tryIt?: TemplateTryIt; } interface TemplateHostExtras { extraAgents?: TemplatePlanExtraAgent[]; workflows?: TemplateWorkflow[]; } /** Every problem with the optional kit-merge parts of `spec`. Empty when it has none. */ declare function extrasProblems(spec: TemplateSpec, agents: AgentSnapshotRow[] | undefined): UseCaseProblem[]; /** The install plan's host parts: the primary agent's full bindings, extra agents and workflows. */ declare function compileHostExtras(spec: TemplateSpec): { agentBindings: Map; extras: TemplateHostExtras; }; declare const INSTALL_PLAN_VERSION: 1; /** * The seed-date grammar the server's `${date:…}` resolver (custom._template_date) must speak: the * whole client grammar (RELATIVE_DATE — business days `b`, the `~b` weekend snap, weekday anchors * `@mon` / `@next-tue`). Business days and anchors depend on the install day's weekday, so they * cannot be compiled away here; the server resolves them. The plan test holds every committed * template's tokens to this, and this to RELATIVE_DATE, so the two can never drift apart. */ declare const SERVER_DATE_GRAMMAR: RegExp; /** * The back-link key a relation declares on its target (relationships[].inverseKey), unless the target table * already has a column of that key (a hand-listed mirror from before two-way links were declarable). */ declare function backLinkKeyOf(spec: Pick, table: string, field: string): string | undefined; type Look = { id: string; options?: Record; }; /** * THE NUMBER FORMAT EVERY INFERRED COLUMN OF A TEMPLATE IS INSTALLED WITH (FORMULA-FORMAT + ROLLUP-FORMAT), keyed * "
.": formulas (`formulaLooksOf`) and rollups / lookups (`derivedLookOf`, the one inference in * formulaLook.ts) worked out together until nothing changes, so lookup -> formula -> rollup chains settle. A look the * template declares on a column wins and is never listed. */ declare function templateLooksOf(spec: Pick): Map; /** The store doors a plan may call — the server's custom._template_doors(), mirrored. */ declare const TEMPLATE_PLAN_DOORS: readonly ["person_kernel_id", "file_kernel_id", "record_write", "record_write_many", "record_change_many", "table_from_example", "table_declare", "field_declare", "applicable_fields", "table_dimensions_set", "view_declare", "form_declare", "anon_publish", "booking_declare", "dashboard_declare", "pipeline_declare", "doc_template_save", "action_declare", "subscription_declare", "rule_declare", "checklist_declare", "portal_declare", "query_table_homes", "automation_declare", "row_template_declare", "automation_set_enabled"]; type TemplatePlanDoor = (typeof TEMPLATE_PLAN_DOORS)[number]; /** What uninstall archives for a step, by kind (custom.template_uninstall). */ type TemplateMadeKind = "table" | "field" | "view" | "form" | "dashboard" | "document" | "portal" | "record" | "rule"; interface TemplatePlanStep { /** Where in the walk this is, for a refusal a person can read ("tables.patient"). */ label: string; door: TemplatePlanDoor; args: Record; /** NAME → a path into the door's JSON answer ([] = the whole answer). */ save?: Record; /** Every element of the array at `array` saves `prefix + element[key]` = element[value]. */ saveEach?: { array: string[]; key: string[]; value: string[]; prefix: string; }; made?: Array<{ kind: TemplateMadeKind; ref: string; title?: string; table?: string; }>; } interface TemplatePlanAgent { platformAgent: { id: string; name: string; }; name: string; /** * Each variable bound to an installed table; the door answers each with its `table_id`. * `binding` (optional, Kits → Template merge): the full merge-field binding (./extras). */ bindings: Array<{ variable: string; tableToken: string; describes: string; binding?: TemplatePlanBinding; }>; } interface TemplateInstallPlan { planVersion: typeof INSTALL_PLAN_VERSION; /** The business's IANA zone: install-relative dates resolve in it. */ timezone: string; steps: TemplatePlanStep[]; /** * The host's step (the kit path's agent copy), answered by custom.template_install once installed. * Absent for a spec with no agent (a describe one-off): the door answers no agent step. */ agent?: TemplatePlanAgent; /** The mandate this template presents instead of an agent copy; recorded on the install (custom.template_install.mandate_key). */ mandateKey?: string; /** * Ids known before the first step (`ref:tables.` → an existing table's id, for each table that * `bindsTo` one): custom.template_install starts its id map with these, so every later step and every * `made` entry resolves the bound table exactly as if the install had made it. */ ids?: Record; /** Kits → Template merge (optional): more agent copies, then workflows — host steps too (./extras). */ extraAgents?: TemplateHostExtras["extraAgents"]; workflows?: TemplateHostExtras["workflows"]; } /** The gallery card (lane 2 / lane 8): what custom.templates returns, and nothing else. */ interface TemplateCard { name: string; persona: string; business: string; vertical: string; industry: string; job: string; audience: string; teaches: string; strengths: string[]; requires: string[]; footprint: TemplateFootprint; previewImage: string | null; } /** A file already in the file store, seeded as a File record at install (seed.attachments). */ interface TemplateAttachment { key: string; fileId: string; name: string; mime: string; bytes: number; } type TemplateSpecWithAttachments = TemplateSpec & { attachments?: TemplateAttachment[]; }; /** `custom.template_declare`'s p_spec: the spec, its card and its compiled plan. */ type TemplateDeclaration = TemplateSpecWithAttachments & { card: TemplateCard; installPlan: TemplateInstallPlan; organizationId?: string; }; declare function templateCard(spec: TemplateSpec): TemplateCard; /** Compile `spec` into the plan custom.template_install runs. Throws, by name, on a spec it cannot install. */ declare function compileInstallPlan(written: TemplateSpecWithAttachments): TemplateInstallPlan; /** `custom.template_declare`'s p_spec for one template: the spec, its card and its plan. */ declare function templateDeclaration(spec: TemplateSpecWithAttachments, organizationId?: string): TemplateDeclaration; /** The family's budgeted doors: each call does what fits in its budget and says `done`. */ type TemplateFamilyDoor = "template_install" | "template_install_fresh" | "template_uninstall" | "template_restore"; /** * TEMPLATE-FRESH (2026-10-18): what a fresh copy of a template says about itself. A fresh copy * (custom.template_install_fresh) is a NEW independent install every time it is used: its own tables, named * "
· ", and everything wired to them only. The default install (custom.template_install) has none. */ interface TemplateInstance { /** 2, 3, …; the default install is 1. Never reused. */ no: number; title: string; mode: "fresh"; /** What the copy appends to every table name: " · <title>". */ suffix: string; } /** The name a fresh copy gives a template table: "<Table> · <title>" (the store's custom._template_instance_args). */ declare function instanceTableName(name: string, title: string | null | undefined): string; /** One row of custom.template_instances: every install of one template in one organization. */ interface TemplateInstanceRow { install_id: string; instance_no: number; mode: "default" | "fresh"; title: string | null; state: NonNullable<TemplateDoorAnswer["state"]>; version: number; template_id: string; started_at: string; finished_at: string | null; /** The first page the install recorded (template_install_note kind 'page'); null for a copy that recorded none. */ root_page_id: string | null; /** Every page the install recorded, oldest first; [] for a copy that recorded none. */ pages: Array<{ id: string; title: string | null; }>; tables: Array<{ ref: string; id: string | null; title: string | null; }>; newer_version: number | null; /** Hand to `upgradeTemplateInstall(source, org, upgrade.install_id, upgrade.template_id)`; one copy at a time. */ upgrade: TemplateUpgradeHint | null; } /** Every install (default + fresh copies) of one catalogue id in one organization, oldest first. */ declare function listTemplateInstances(source: RecordsDataSource, organizationId: string, catalogueId: string): Promise<{ ok: boolean; instances: TemplateInstanceRow[]; error?: { code: string | null; message: string; }; }>; /** The install that made a page (custom.template_instance_of_page): the row of the install whose recorded pages include it. */ interface TemplateInstanceOfPage { id: string; catalogue_id: string; status: NonNullable<TemplateDoorAnswer["state"]>; /** The first page the install recorded: the page a "made from a template" banner points back to. */ root_page_id: string | null; template_version: number; } /** * Which template install made this page, or null: the page is not one an install recorded, the caller may not read it, or it is * not in that organization (all three answer the same, so nothing leaks). The door checks read access on the page itself. */ declare function templateInstanceOfPage(source: RecordsDataSource, organizationId: string, pageId: string): Promise<{ ok: boolean; instance: TemplateInstanceOfPage | null; error?: { code: string | null; message: string; }; }>; /** What the three doors answer (custom._template_answer). */ interface TemplateDoorAnswer { install_id?: string; state?: "installing" | "installed" | "refused" | "uninstalling" | "uninstalled"; ok?: boolean; done?: boolean; already?: boolean; next_step?: number; steps?: number; made?: Array<{ kind: string; id: string | null; ref: string; title: string | null; table_id: string | null; }>; archived?: unknown[]; left?: unknown[]; refusal?: Record<string, unknown> | null; agent?: { platform_agent: { id: string; name: string; }; name: string; bindings: Array<Record<string, unknown>>; copied: boolean; } | null; /** The mandate the template presents (spec.mandateKey), recorded on the install; null for a template with an agent copy. */ mandate_key?: string | null; /** * Kits → Template merge (custom._template_answer, only for a template that carries them): the plan's * extra agents and workflows, and the ids the host resolves them with — `tables.<token>` → table * id, `row.<token>.<rowKey>` → seed row id. */ host?: { extra_agents?: TemplatePlanExtraAgent[] | null; workflows?: TemplateWorkflow[] | null; ids?: Record<string, string>; } | null; /** template_install's `already` answer, when the template is newer than the install. */ newer_version?: number | null; /** TEMPLATE-FRESH: present only on a fresh copy (custom.template_install_fresh). */ instance?: TemplateInstance | null; /** What `upgradeTemplateInstall` needs to bring the install up to `newer_version` (null when current). */ upgrade?: TemplateUpgradeHint | null; [key: string]: unknown; } /** template_install's hint: call custom.template_upgrade with these ids. */ interface TemplateUpgradeHint { door: "template_upgrade"; install_id: string; template_id: string; from_version: number; to_version: number; } /** What custom.template_upgrade answers: the install answer plus what this upgrade did. */ interface TemplateUpgradeAnswer extends TemplateDoorAnswer { /** True when this call changed the install; false on `already` (current) or a refusal. */ upgraded?: boolean; /** The install's version now. */ version?: number; from_version?: number; to_version?: number; /** * Per kind: `tables`, `fields`, `views`, `dashboards`… made; `rows` seeded on new tables; * `fields_converted` (choice → link), `links`, `targets_created`, `fields_retired`; `kept` steps. */ counts?: Record<string, number>; /** Anything the upgrade left as it was, with the reason. */ skipped?: Array<{ kind: string; ref: string; reason: string; }>; } interface TemplateUpgradeRun { ok: boolean; answer: TemplateUpgradeAnswer | null; error?: { code: string | null; message: string; hint: string | null; }; calls: number; } /** The upgrade hint an install answer carries, or null when the install is current. */ declare function templateUpgradeHint(answer: TemplateDoorAnswer | null | undefined): TemplateUpgradeHint | null; /** * Apply a newer version of a template to an existing install (custom.template_upgrade): new tables, * fields, views and seed rows of new tables are made; a choice column that became a link is converted * by title; a column the new version drops is retired, never dropped. One transaction per call, so a * lock wait or a timeout is retried. Never throws: a refusal is `ok: false` with `answer.refusal`. * A host that copies agents runs its host steps on `answer` after, exactly as after an install. */ declare function upgradeTemplateInstall(source: RecordsDataSource, organizationId: string, installId: string, templateId: string, options?: BusyRetryOptions & { maxCalls?: number; }): Promise<TemplateUpgradeRun>; /** TEMPLATE-FRESH-2: the one sentence a person sees when the tables stayed busy through every retry. */ declare const TEMPLATE_BUSY_MESSAGE = "The tables were busy; try again in a minute."; interface BusyRetryOptions { /** Retries after a transient answer (lock wait 55P03, deadlock 40P01, timeout 57014, serialization 40001, PGRST001/PGRST002, 502/503/504, a reset connection). Default 6. */ busyRetries?: number; /** Waits between them: 0.5, 1, 2, then 4 s, each with +/-25 % jitter. Tests pass a fake. */ sleep?: (ms: number) => Promise<void>; /** The jitter's source (0..1); tests pass a fixed one so the waits are exact. */ random?: () => number; } interface TemplateDoorRun { ok: boolean; answer: TemplateDoorAnswer | null; /** The transport's own error (the 8 s ceiling, a lock wait), after the retries ran out. */ error?: { code: string | null; message: string; hint: string | null; }; calls: number; } /** * Call one of the family's budgeted doors until it says done: install (p_template_id), uninstall * or restore (p_install_id). A refusal comes back verbatim (`ok: false`, answer.refusal); a lock * wait or a statement timeout is retried, because a call that times out changed nothing. * * TEMPLATE-FRESH: `template_install_fresh` (id = the template id) makes a NEW copy on its first call and * continues THAT copy (p_install_id from the first answer) on every later call, so one run is one copy. * `options.title` names it (else the store numbers it "<template name> 2", "3", …). */ declare function runTemplateDoor(source: RecordsDataSource, door: TemplateFamilyDoor, organizationId: string, id: string, options?: BusyRetryOptions & { maxCalls?: number; onCall?: (answer: TemplateDoorAnswer) => void; title?: string | null; installId?: string | null; /** A fresh copy's id when this run minted it (heard BEFORE the first call, so a host can keep it for a refresh). */ onInstallId?: (installId: string) => void; }): Promise<TemplateDoorRun>; /** * TEMPLATE-INSTALL-2: a new id for one copy of a template. The page mints it BEFORE the first call and sends it on every call, a retry * or a refresh included, so `template_install_fresh` answers the same install however many times it is asked (never a second copy). */ declare function newTemplateInstallId(): string; /** Tables a plan makes (for a suite): the `tables.*` refs its steps save. */ declare function planTables(plan: TemplateInstallPlan): string[]; /** One table of the plan's skeleton: every name S2, S3 and S4 must agree on. */ interface DescribePlanTable { token: string; name: string; labelSingular: string; subject: "person" | "animal" | "thing"; /** One line: why the business needs it. */ purpose: string; titleField: { key: string; label: string; }; /** The organization's own table this one IS (keys that already exist are kept verbatim). */ reuse?: { existing_table_id: string; keepKeys: string[]; }; /** The flow, in order. The field is keyed `status`. */ status?: { choices: string[]; default: string; }; /** Booking lands here: a required `slot` datetime. */ slot?: true; /** The child holds the single link. */ links: Array<{ key: string; label: string; target: string; many: boolean; }>; /** 3–8 plain facts the work needs ("amount", "address"). */ mustHave: string[]; } interface DescribePlanDoor { kind: "form" | "booking"; table: string; audience: "public" | "staff" | "member"; purpose: string; } /** S1 output. */ interface DescribePlan { business: { name: string; describes: string; timezone: string; }; id: string; useCase: string; industry: IndustryGroup; vertical: string; job: TemplateJob; teaches: TeachesFeature; audience: "organization" | "individual"; tables: DescribePlanTable[]; doors: DescribePlanDoor[]; views: Array<{ kind: TemplateViewKind; table: string; why: string; }>; booking?: { visit: string; minutes: number; windows: TemplateBookingWindow[]; source: "org_hours" | "assumed"; }; leaveOut: string[]; assumptions: string[]; } /** S2 output. */ interface TablesPart { tables: TemplateTable[]; relationships: UseCaseRelationship[]; } /** A field S3 needs and asks the merge to add (skipped when the key already exists). */ interface FieldRequest { table: string; key: string; label: string; parityType: string; choices?: string[]; askOfSubject?: boolean; askOfGuardian?: boolean; required?: boolean; help?: string; } /** S3 output. */ interface DoorsPart { forms: TemplateForm[]; booking?: TemplateBooking; fieldRequests: FieldRequest[]; } /** S4 output. */ interface ViewsPart { views: TemplateView[]; } /** S6 output: a patch list. `path` names a piece of the spec; `set` is merged onto it. */ interface RepairPatch { /** "tables.visit.fields.pain_level" · "tables.visit" · "forms.intake.fields.phone" · "extras.booking" · "views.<token>" */ path: string; set: Record<string, unknown>; } interface RepairAnswer { patches: RepairPatch[]; notes?: string[]; } /** What a check says is wrong: the validator's own words, verbatim. */ interface DescribeProblem { at: string; says: string; } /** The organization's own table, as the mandate's `existing_tables` variable carries it. */ interface ExistingTable { id: string; name: string; fields: Array<{ key: string; label: string; kind: string; choices?: string[]; }>; } /** What the code steps may know beyond the spec. All optional: a bare spec is checked on its own. */ interface DescribeCtx { plan?: DescribePlan; existingTables?: ExistingTable[]; /** Install day, YYYY-MM-DD in the business's zone: absolute seed dates become relative to it. Defaults to today in UTC. */ today?: string; } /** S7: the answer the frontend's describe box already reads. */ interface DescribeResult { __kind: "describe_template_result"; template: Record<string, unknown>; notes: string[]; reuses: Array<{ token: string; existing_table_id: string; }>; } /** Keys only a gallery card carries; a describe spec never sends them to the check. */ declare const GALLERY_ONLY: string[]; /** * The spec as the check reads it: the mandate's template with the lists the shape always has defaulted * (an omitted empty list is not a defect) and every gallery-only key taken off. */ declare function describeSpec(template: Record<string, unknown>): TemplateSpec; /** The deterministic default view of one table: kanban by status, else calendar by slot, else grid by title. */ declare function fallbackView(t: { token: string; name?: unknown; titleField?: unknown; fields: Array<{ key: string; parityType: string; }>; }): TemplateView; /** The plan's reuse decisions, in the shape the frontend's bindReuses takes. */ declare function reusesOf(plan: DescribePlan): Array<{ token: string; existing_table_id: string; }>; /** * S5 step 1 and assembly. `doors` and `views` may be missing (a failed step): the views fall back to the default, the * forms stay empty (a missing front door is for the check to say, never for code to invent). */ declare function mergeDescribeParts(plan: DescribePlan, tables: TablesPart, doors: DoorsPart | null | undefined, views: ViewsPart | null | undefined, existingTables?: ExistingTable[], notes?: string[]): TemplateSpec; interface AutofixResult { spec: TemplateSpec; autoFixes: string[]; } interface DescribeCheckResult extends AutofixResult { problems: DescribeProblem[]; } declare function autofixDescribeSpec(input: TemplateSpec | Record<string, unknown>, ctx?: DescribeCtx): AutofixResult; /** S5 whole: autofix, then the describe-profile check. */ declare function describeCheck(spec: TemplateSpec | Record<string, unknown>, ctx?: DescribeCtx): DescribeCheckResult; type Rec = Record<string, unknown>; /** * "tables (visit).fields (pain_level).rules" → [{root:"tables",id:"visit"},{root:"fields",id:"pain_level"},{root:"rules"}]. * A piece the validator could only name by position ("views[1] (undefined)", "forms[0]") gets the id "#1" / "#0": the * place in its list, which resolvePath reads. (A missing name is never an id.) */ declare function parseAt(at: string): Array<{ root: string; id?: string; }>; /** The repair path a problem's `at` points at: the deepest piece that can be patched. Never a path that resolves to nothing for a piece that exists. */ declare function pathOfAt(at: string): string; /** The object a repair path names, inside `spec` (not a copy). */ declare function resolvePath(spec: TemplateSpec, path: string): Rec | undefined; interface RepairSlice { /** The repair path a patch for this slice would use. */ path: string; /** The JSON the problems point at. Never the whole spec. */ slice: unknown; problems: DescribeProblem[]; } /** * The minimal slices S6's agent is sent: for each distinct piece the problems point at, that piece's JSON and the * problems' own words. A table-level problem gets the table with its fields indexed; a field-level problem, only that field. */ declare function repairSlices(spec: TemplateSpec, problems: DescribeProblem[]): RepairSlice[]; interface ApplyResult { spec: TemplateSpec; /** Paths that landed. */ applied: string[]; /** Paths that did not, with why (an unknown piece, or a patch that tried to rename). */ skipped: Array<{ path: string; why: string; }>; } /** * Apply S6's patch list: each `set` is merged (shallow, `null` removes a key) onto the piece its `path` names. A key, token * or fieldKey is never changed (references would break). A field or question that does not exist yet is ADDED when the patch * carries what makes one (label + parityType for a field, `ask` for a question). Never mutates its input. */ declare function applyRepairPatches(input: TemplateSpec, patches: RepairPatch[]): ApplyResult; interface TrimResult { spec: TemplateSpec; /** One line per piece left out, for the notes. */ notes: string[]; } /** * The deterministic last resort when repair did not clear a problem: leave out the offending OPTIONAL piece, with a note — * a view, a help text, a question the field does not require. Anything else stays a problem (the honest failure). */ declare function lastResortTrim(input: TemplateSpec, problems: DescribeProblem[]): TrimResult; /** * S7. Notes: the plan's assumptions, what it left out, then the auto-fixes that changed the setup, then `extraNotes` * (what a last-resort trim left out). Capped at 7 lines. `reuses` keeps only tokens the spec has. */ declare function packageDescribeResult(spec: TemplateSpec, plan: Pick<DescribePlan, "assumptions" | "leaveOut"> | undefined, autoFixes: string[], reuses: Array<{ token: string; existing_table_id: string; }>, extraNotes?: string[]): DescribeResult; /** Each booking availability key: what it means and the type the install door takes. */ declare const BOOKING_AVAILABILITY_FACTS: Record<string, string>; /** What a view is made of. */ declare const VIEW_SHAPE_FACTS: { readonly token: "snake_case, unique among every view, form and extra — always written"; readonly name: "what a person clicks, such as \"Intake board\""; readonly table: "the token of one of the template's tables"; readonly kind: readonly ["grid", "kanban", "calendar", "gallery", "timeline", "map", "orgchart", "pivot"]; readonly groupBy: "kanban only, required: the key of a select field whose choices become the columns"; readonly dateField: "calendar only, required: the key of a datetime field"; readonly startField_endField: "timeline only, required: keys of two datetime fields"; readonly coverField: "gallery only, required: the key of a file field"; }; /** The store's closed lists, as the mandate's `vocabulary` value — read from the package, never typed by a caller. */ declare function describeVocabulary(): Record<string, unknown>; /** The content words of a key or label, stemmed, as a sorted unique list. */ declare function meaningWords(text: string): string[]; /** Two fields of one table mean the same when their kinds agree and their key words, or label words, are the same set. */ declare function sameMeaning(a: { key: string; label?: string; parityType: string; }, b: { key: string; label?: string; parityType: string; }): boolean; type Reuse = DescribeResult["reuses"][number]; interface SafeReusesResult { spec: TemplateSpec; /** The reuses that remain: link-only, safe to bind. */ reuses: Reuse[]; /** One line per reuse turned into a new table. */ notes: string[]; converted: Array<{ token: string; existingName: string; newName: string; why: string; }>; } declare function safeReuses(spec: TemplateSpec, reuses: Reuse[], existingTables: ExistingTable[]): SafeReusesResult; declare const DESCRIBE_RESULT_KIND = "describe_template_result"; declare function describeResultJsonSchema(): Record<string, unknown>; /** The template as the check reads it: every JSON-text part opened (an object already open is left as it is). */ declare function parseDescribeTemplate(template: Record<string, unknown>): Record<string, unknown>; /** A suggested automation: installed, then switched off by the plan (plan.ts `automation_set_enabled`). */ type StarterAutomation = TemplateAutomation & { startsOff: true; }; interface StarterResult { spec: TemplateSpec; /** What was added, one line each, in the person's words. */ built: string[]; /** What could not be added, and why, one line each. */ notBuilt: string[]; } /** The most charts the starter dashboard draws (a count per table does not count against it). */ declare const STARTER_MAX_CHARTS = 6; /** The most new tables the starter dashboard counts. */ declare const STARTER_MAX_TABLES = 6; /** * The described business's own name, or "" when the name is really the WORKSPACE's (a default "<person>'s Workspace" or a * name the host says is the organization's): a dashboard is named after the business, never after where it is installed. */ declare function usableBusinessName(name: string | undefined, avoidNames?: string[]): string; /** The store's label rule (validate.ts: at most 40 characters and 6 words): the first candidate that fits, else the last cut to fit. */ declare function fitLabel(...candidates: string[]): string; /** * THE ONE FUNCTION: the checked spec plus a starter dashboard and suggested automations built from its own new * tables. Pure; the input is not changed. */ declare function addStarterInterface(input: TemplateSpec, opts?: { avoidNames?: string[]; }): StarterResult; export { AUTOMATION_EVENTS, AgentSnapshotRow, BAD_OUTCOME, BOOKING_AVAILABILITY_FACTS, CapabilityWord, DESCRIBE_RESULT_KIND, DESIGNATED_REAL_NUMBERS, FORMULA_FUNCTION_NAMES, GALLERY_ONLY, GOOD_OUTCOME, INSTALLER, INSTALL_PLAN_VERSION, IndustryGroup, MAIN_TABLE_ROWS_MAX, MAIN_TABLE_ROWS_MIN, PUBLIC_MAIL_DOMAINS, RECORDS_UI_CALENDAR_MODES, RECORDS_UI_FIELD_SURFACES, RECORDS_UI_VIEW_LAYOUTS, SERVER_DATE_GRAMMAR, STAMP_KINDS, STARTER_MAX_CHARTS, STARTER_MAX_TABLES, SharedBlockId, TABLES_MAX, TABLES_MIN, TEMPLATE_BUSY_MESSAGE, TEMPLATE_PLAN_DOORS, TIME_BOUND_STAGE, TITLE_DISTINCT_SHARE, TeachesFeature, TemplateAgent, TemplateAutomation, TemplateBooking, TemplateBookingWindow, TemplateChecklist, TemplateDashboard, TemplateDigest, TemplateDimensions, TemplateDocument, TemplateDrillDown, TemplateField, TemplateFootprint, TemplateForm, TemplateJob, TemplateMergeBinding, TemplateNotification, TemplatePortal, TemplateRowAction, TemplateSpec, TemplateStageRules, TemplateTable, TemplateTryIt, TemplateView, TemplateViewKind, TemplateWorkflow, VIEW_SHAPE_FACTS, addStarterInterface, agentCopyRequest, allTables, anyOfWhere, applyRepairPatches, assertTemplate, attachmentProblems, autofixDescribeSpec, automationHeld, automationSpec, automationSpecs, backLinkKeyOf, blockTable, bookingArgs, bookingColumnsProblem, buttonFieldSpec, capabilitiesUsed, capabilityStatus, checklistSpec, choiceDisplayFormat, compileHostExtras, compileInstallPlan, dashboardBlocks, deferredRelationFields, deferredRelations, derivedFieldSpec, describeCheck, describeResultJsonSchema, describeSpec, describeVocabulary, digestSpec, documentBody, domainsIn, drillDownDashboard, evalFormula, extrasProblems, fallbackView, fieldDisplayFormat, fitLabel, foreignTextProblems, formArgs, formulaFieldSpec, formulaLooksOf, formulaOrder, formulaRefs, foundationTokens, instanceTableName, isSelfDeclaredField, isTimedField, lastResortTrim, listTemplateInstances, meaningWords, mergeDescribeParts, newRowsPointAtNewRows, newTemplateInstallId, normalizeForPhones, notificationParts, numberText, numberedStreet, packageDescribeResult, parseAt, parseDescribeTemplate, parseGateFormula, parseNumeric, pathOfAt, peopleOf, phonesOutsideFictionalRange, planTables, portalArgs, relationFieldSpec, relationPatches, relativeHasTime, repairSlices, requiredCircleProblem, resolveDateToken, resolvePath, resolveRelativeDates, reusesOf, rowActionList, rowLevels, rowsFor, ruleBreak, runTemplateDoor, safeReuses, sameMeaning, selfDeclaredFieldSpec, sensitivityFloorOf, shellsPayload, stageFieldOf, stageRulesSpec, storeAggregate, storeFilterMatches, storeText, tableShellPayload, templateCard, templateDeclaration, templateInstanceOfPage, templateLooksOf, templateText, templateUpgradeHint, timedFieldSpec, toUseCase, unwrap, upgradeTemplateInstall, usableBusinessName, useCaseProblemsOf, validateTemplate, viewMatches, viewSpec, viewWhere, zoneOffset }; export type { AggregateOutcome, ApplyResult, AutofixResult, BusyRetryOptions, CapabilityStatus, DerivedUseCase, DescribeCheckResult, DescribeCtx, DescribePlan, DescribePlanDoor, DescribePlanTable, DescribeProblem, DescribeResult, DoorsPart, ExistingTable, FieldRequest, RepairAnswer, RepairPatch, RepairSlice, SafeReusesResult, SeedRow, StarterAutomation, StarterResult, TablesPart, TemplateAgentBinding, TemplateAgentCopyRequest, TemplateAssetRow, TemplateAttachment, TemplateCard, TemplateDeclaration, TemplateDoorAnswer, TemplateDoorRun, TemplateFamilyDoor, TemplateHostExtras, TemplateInstallPlan, TemplateInstance, TemplateInstanceOfPage, TemplateInstanceRow, TemplateMadeKind, TemplatePlanAgent, TemplatePlanBinding, TemplatePlanDoor, TemplatePlanExtraAgent, TemplatePlanStep, TemplateSpecWithAttachments, TemplateStatus, TemplateUpgradeAnswer, TemplateUpgradeHint, TemplateUpgradeRun, TemplateVerdict, TrimResult, ValidateOptions, ViewsPart };