@ai-matrx/records 0.95.1 → 0.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{client-DQWdJeFM.d.ts → client-D7bvxEZW.d.ts} +9 -0
  3. package/dist/{client-CEX4WdvX.d.cts → client-DKgbZUNt.d.cts} +9 -0
  4. package/dist/core/index.cjs +4 -0
  5. package/dist/core/index.cjs.map +1 -1
  6. package/dist/core/index.d.cts +3 -2
  7. package/dist/core/index.d.ts +3 -2
  8. package/dist/core/index.js +4 -0
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/data/index.cjs +4 -0
  11. package/dist/data/index.cjs.map +1 -1
  12. package/dist/data/index.d.cts +1 -1
  13. package/dist/data/index.d.ts +1 -1
  14. package/dist/data/index.js +4 -0
  15. package/dist/data/index.js.map +1 -1
  16. package/dist/{declareTable-Bkh3C1Ao.d.ts → declareTable-D_CiMnXM.d.ts} +1 -1
  17. package/dist/{declareTable-DeQ9_TMb.d.cts → declareTable-VoNRi_j_.d.cts} +1 -1
  18. package/dist/questions/index.d.cts +1 -1
  19. package/dist/questions/index.d.ts +1 -1
  20. package/dist/react/index.cjs +4 -0
  21. package/dist/react/index.cjs.map +1 -1
  22. package/dist/react/index.d.cts +9 -0
  23. package/dist/react/index.d.ts +9 -0
  24. package/dist/react/index.js +4 -0
  25. package/dist/react/index.js.map +1 -1
  26. package/dist/setup/index.cjs +4 -0
  27. package/dist/setup/index.cjs.map +1 -1
  28. package/dist/setup/index.d.cts +1 -1
  29. package/dist/setup/index.d.ts +1 -1
  30. package/dist/setup/index.js +4 -0
  31. package/dist/setup/index.js.map +1 -1
  32. package/dist/templates/index.cjs +124 -65
  33. package/dist/templates/index.cjs.map +1 -1
  34. package/dist/templates/index.d.cts +6 -1
  35. package/dist/templates/index.d.ts +6 -1
  36. package/dist/templates/index.js +124 -65
  37. package/dist/templates/index.js.map +1 -1
  38. package/dist/typed-table/index.cjs +4 -0
  39. package/dist/typed-table/index.cjs.map +1 -1
  40. package/dist/typed-table/index.d.cts +2 -2
  41. package/dist/typed-table/index.d.ts +2 -2
  42. package/dist/typed-table/index.js +4 -0
  43. package/dist/typed-table/index.js.map +1 -1
  44. package/dist/views/index.d.cts +1 -1
  45. package/dist/views/index.d.ts +1 -1
  46. package/package.json +4 -4
@@ -949,4 +949,9 @@ interface SafeReusesResult {
949
949
  }
950
950
  declare function safeReuses(spec: TemplateSpec, reuses: Reuse[], existingTables: ExistingTable[]): SafeReusesResult;
951
951
 
952
- export { AgentSnapshotRow, type AggregateOutcome, type ApplyResult, type AutofixResult, BAD_OUTCOME, BOOKING_AVAILABILITY_FACTS, type CapabilityStatus, CapabilityWord, DESIGNATED_REAL_NUMBERS, type DerivedUseCase, type DescribeCheckResult, type DescribeCtx, type DescribePlan, type DescribePlanDoor, type DescribePlanTable, type DescribeProblem, type DescribeResult, type DoorsPart, type ExistingTable, FORMULA_FUNCTION_NAMES, type FieldRequest, GALLERY_ONLY, GOOD_OUTCOME, 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, type RepairAnswer, type RepairPatch, type RepairSlice, SERVER_DATE_GRAMMAR, type SafeReusesResult, type SeedRow, SharedBlockId, TABLES_MAX, TABLES_MIN, TEMPLATE_PLAN_DOORS, TIME_BOUND_STAGE, TITLE_DISTINCT_SHARE, type TablesPart, TeachesFeature, TemplateAgent, type TemplateAgentBinding, type TemplateAgentCopyRequest, type TemplateAssetRow, type TemplateAttachment, TemplateAutomation, TemplateBooking, TemplateBookingWindow, type TemplateCard, TemplateChecklist, TemplateDashboard, type TemplateDeclaration, TemplateDigest, TemplateDimensions, TemplateDocument, type TemplateDoorAnswer, type TemplateDoorRun, TemplateDrillDown, type TemplateFamilyDoor, TemplateField, TemplateFootprint, TemplateForm, type TemplateHostExtras, type TemplateInstallPlan, TemplateJob, type TemplateMadeKind, TemplateMergeBinding, TemplateNotification, type TemplatePlanAgent, type TemplatePlanBinding, type TemplatePlanDoor, type TemplatePlanExtraAgent, type TemplatePlanStep, TemplatePortal, TemplateRowAction, TemplateSpec, type TemplateSpecWithAttachments, TemplateStageRules, type TemplateStatus, TemplateTable, TemplateTryIt, type TemplateUpgradeAnswer, type TemplateUpgradeHint, type TemplateUpgradeRun, type TemplateVerdict, TemplateView, TemplateViewKind, TemplateWorkflow, type TrimResult, VIEW_SHAPE_FACTS, type ValidateOptions, type ViewsPart, agentCopyRequest, allTables, anyOfWhere, applyRepairPatches, assertTemplate, attachmentProblems, autofixDescribeSpec, automationHeld, blockTable, bookingArgs, bookingColumnsProblem, capabilitiesUsed, capabilityStatus, checklistSpec, choiceDisplayFormat, compileHostExtras, compileInstallPlan, dashboardBlocks, deferredRelationFields, deferredRelations, derivedFieldSpec, describeCheck, describeSpec, describeVocabulary, digestSpec, documentBody, domainsIn, drillDownDashboard, evalFormula, extrasProblems, fallbackView, foreignTextProblems, formArgs, formulaFieldSpec, formulaOrder, formulaRefs, foundationTokens, isSelfDeclaredField, isTimedField, lastResortTrim, meaningWords, mergeDescribeParts, normalizeForPhones, notificationParts, numberText, numberedStreet, packageDescribeResult, parseAt, 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, templateText, templateUpgradeHint, timedFieldSpec, toUseCase, unwrap, upgradeTemplateInstall, useCaseProblemsOf, validateTemplate, viewMatches, viewSpec, zoneOffset };
952
+ declare const DESCRIBE_RESULT_KIND = "describe_template_result";
953
+ declare function describeResultJsonSchema(): Record<string, unknown>;
954
+ /** The template as the check reads it: every JSON-text part opened (an object already open is left as it is). */
955
+ declare function parseDescribeTemplate(template: Record<string, unknown>): Record<string, unknown>;
956
+
957
+ export { AgentSnapshotRow, type AggregateOutcome, type ApplyResult, type AutofixResult, BAD_OUTCOME, BOOKING_AVAILABILITY_FACTS, type CapabilityStatus, CapabilityWord, DESCRIBE_RESULT_KIND, DESIGNATED_REAL_NUMBERS, type DerivedUseCase, type DescribeCheckResult, type DescribeCtx, type DescribePlan, type DescribePlanDoor, type DescribePlanTable, type DescribeProblem, type DescribeResult, type DoorsPart, type ExistingTable, FORMULA_FUNCTION_NAMES, type FieldRequest, GALLERY_ONLY, GOOD_OUTCOME, 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, type RepairAnswer, type RepairPatch, type RepairSlice, SERVER_DATE_GRAMMAR, type SafeReusesResult, type SeedRow, SharedBlockId, TABLES_MAX, TABLES_MIN, TEMPLATE_PLAN_DOORS, TIME_BOUND_STAGE, TITLE_DISTINCT_SHARE, type TablesPart, TeachesFeature, TemplateAgent, type TemplateAgentBinding, type TemplateAgentCopyRequest, type TemplateAssetRow, type TemplateAttachment, TemplateAutomation, TemplateBooking, TemplateBookingWindow, type TemplateCard, TemplateChecklist, TemplateDashboard, type TemplateDeclaration, TemplateDigest, TemplateDimensions, TemplateDocument, type TemplateDoorAnswer, type TemplateDoorRun, TemplateDrillDown, type TemplateFamilyDoor, TemplateField, TemplateFootprint, TemplateForm, type TemplateHostExtras, type TemplateInstallPlan, TemplateJob, type TemplateMadeKind, TemplateMergeBinding, TemplateNotification, type TemplatePlanAgent, type TemplatePlanBinding, type TemplatePlanDoor, type TemplatePlanExtraAgent, type TemplatePlanStep, TemplatePortal, TemplateRowAction, TemplateSpec, type TemplateSpecWithAttachments, TemplateStageRules, type TemplateStatus, TemplateTable, TemplateTryIt, type TemplateUpgradeAnswer, type TemplateUpgradeHint, type TemplateUpgradeRun, type TemplateVerdict, TemplateView, TemplateViewKind, TemplateWorkflow, type TrimResult, VIEW_SHAPE_FACTS, type ValidateOptions, type ViewsPart, agentCopyRequest, allTables, anyOfWhere, applyRepairPatches, assertTemplate, attachmentProblems, autofixDescribeSpec, automationHeld, blockTable, bookingArgs, bookingColumnsProblem, capabilitiesUsed, capabilityStatus, checklistSpec, choiceDisplayFormat, compileHostExtras, compileInstallPlan, dashboardBlocks, deferredRelationFields, deferredRelations, derivedFieldSpec, describeCheck, describeResultJsonSchema, describeSpec, describeVocabulary, digestSpec, documentBody, domainsIn, drillDownDashboard, evalFormula, extrasProblems, fallbackView, foreignTextProblems, formArgs, formulaFieldSpec, formulaOrder, formulaRefs, foundationTokens, isSelfDeclaredField, isTimedField, lastResortTrim, meaningWords, mergeDescribeParts, 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, templateText, templateUpgradeHint, timedFieldSpec, toUseCase, unwrap, upgradeTemplateInstall, useCaseProblemsOf, validateTemplate, viewMatches, viewSpec, zoneOffset };
@@ -949,4 +949,9 @@ interface SafeReusesResult {
949
949
  }
950
950
  declare function safeReuses(spec: TemplateSpec, reuses: Reuse[], existingTables: ExistingTable[]): SafeReusesResult;
951
951
 
952
- export { AgentSnapshotRow, type AggregateOutcome, type ApplyResult, type AutofixResult, BAD_OUTCOME, BOOKING_AVAILABILITY_FACTS, type CapabilityStatus, CapabilityWord, DESIGNATED_REAL_NUMBERS, type DerivedUseCase, type DescribeCheckResult, type DescribeCtx, type DescribePlan, type DescribePlanDoor, type DescribePlanTable, type DescribeProblem, type DescribeResult, type DoorsPart, type ExistingTable, FORMULA_FUNCTION_NAMES, type FieldRequest, GALLERY_ONLY, GOOD_OUTCOME, 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, type RepairAnswer, type RepairPatch, type RepairSlice, SERVER_DATE_GRAMMAR, type SafeReusesResult, type SeedRow, SharedBlockId, TABLES_MAX, TABLES_MIN, TEMPLATE_PLAN_DOORS, TIME_BOUND_STAGE, TITLE_DISTINCT_SHARE, type TablesPart, TeachesFeature, TemplateAgent, type TemplateAgentBinding, type TemplateAgentCopyRequest, type TemplateAssetRow, type TemplateAttachment, TemplateAutomation, TemplateBooking, TemplateBookingWindow, type TemplateCard, TemplateChecklist, TemplateDashboard, type TemplateDeclaration, TemplateDigest, TemplateDimensions, TemplateDocument, type TemplateDoorAnswer, type TemplateDoorRun, TemplateDrillDown, type TemplateFamilyDoor, TemplateField, TemplateFootprint, TemplateForm, type TemplateHostExtras, type TemplateInstallPlan, TemplateJob, type TemplateMadeKind, TemplateMergeBinding, TemplateNotification, type TemplatePlanAgent, type TemplatePlanBinding, type TemplatePlanDoor, type TemplatePlanExtraAgent, type TemplatePlanStep, TemplatePortal, TemplateRowAction, TemplateSpec, type TemplateSpecWithAttachments, TemplateStageRules, type TemplateStatus, TemplateTable, TemplateTryIt, type TemplateUpgradeAnswer, type TemplateUpgradeHint, type TemplateUpgradeRun, type TemplateVerdict, TemplateView, TemplateViewKind, TemplateWorkflow, type TrimResult, VIEW_SHAPE_FACTS, type ValidateOptions, type ViewsPart, agentCopyRequest, allTables, anyOfWhere, applyRepairPatches, assertTemplate, attachmentProblems, autofixDescribeSpec, automationHeld, blockTable, bookingArgs, bookingColumnsProblem, capabilitiesUsed, capabilityStatus, checklistSpec, choiceDisplayFormat, compileHostExtras, compileInstallPlan, dashboardBlocks, deferredRelationFields, deferredRelations, derivedFieldSpec, describeCheck, describeSpec, describeVocabulary, digestSpec, documentBody, domainsIn, drillDownDashboard, evalFormula, extrasProblems, fallbackView, foreignTextProblems, formArgs, formulaFieldSpec, formulaOrder, formulaRefs, foundationTokens, isSelfDeclaredField, isTimedField, lastResortTrim, meaningWords, mergeDescribeParts, normalizeForPhones, notificationParts, numberText, numberedStreet, packageDescribeResult, parseAt, 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, templateText, templateUpgradeHint, timedFieldSpec, toUseCase, unwrap, upgradeTemplateInstall, useCaseProblemsOf, validateTemplate, viewMatches, viewSpec, zoneOffset };
952
+ declare const DESCRIBE_RESULT_KIND = "describe_template_result";
953
+ declare function describeResultJsonSchema(): Record<string, unknown>;
954
+ /** The template as the check reads it: every JSON-text part opened (an object already open is left as it is). */
955
+ declare function parseDescribeTemplate(template: Record<string, unknown>): Record<string, unknown>;
956
+
957
+ export { AgentSnapshotRow, type AggregateOutcome, type ApplyResult, type AutofixResult, BAD_OUTCOME, BOOKING_AVAILABILITY_FACTS, type CapabilityStatus, CapabilityWord, DESCRIBE_RESULT_KIND, DESIGNATED_REAL_NUMBERS, type DerivedUseCase, type DescribeCheckResult, type DescribeCtx, type DescribePlan, type DescribePlanDoor, type DescribePlanTable, type DescribeProblem, type DescribeResult, type DoorsPart, type ExistingTable, FORMULA_FUNCTION_NAMES, type FieldRequest, GALLERY_ONLY, GOOD_OUTCOME, 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, type RepairAnswer, type RepairPatch, type RepairSlice, SERVER_DATE_GRAMMAR, type SafeReusesResult, type SeedRow, SharedBlockId, TABLES_MAX, TABLES_MIN, TEMPLATE_PLAN_DOORS, TIME_BOUND_STAGE, TITLE_DISTINCT_SHARE, type TablesPart, TeachesFeature, TemplateAgent, type TemplateAgentBinding, type TemplateAgentCopyRequest, type TemplateAssetRow, type TemplateAttachment, TemplateAutomation, TemplateBooking, TemplateBookingWindow, type TemplateCard, TemplateChecklist, TemplateDashboard, type TemplateDeclaration, TemplateDigest, TemplateDimensions, TemplateDocument, type TemplateDoorAnswer, type TemplateDoorRun, TemplateDrillDown, type TemplateFamilyDoor, TemplateField, TemplateFootprint, TemplateForm, type TemplateHostExtras, type TemplateInstallPlan, TemplateJob, type TemplateMadeKind, TemplateMergeBinding, TemplateNotification, type TemplatePlanAgent, type TemplatePlanBinding, type TemplatePlanDoor, type TemplatePlanExtraAgent, type TemplatePlanStep, TemplatePortal, TemplateRowAction, TemplateSpec, type TemplateSpecWithAttachments, TemplateStageRules, type TemplateStatus, TemplateTable, TemplateTryIt, type TemplateUpgradeAnswer, type TemplateUpgradeHint, type TemplateUpgradeRun, type TemplateVerdict, TemplateView, TemplateViewKind, TemplateWorkflow, type TrimResult, VIEW_SHAPE_FACTS, type ValidateOptions, type ViewsPart, agentCopyRequest, allTables, anyOfWhere, applyRepairPatches, assertTemplate, attachmentProblems, autofixDescribeSpec, automationHeld, blockTable, bookingArgs, bookingColumnsProblem, capabilitiesUsed, capabilityStatus, checklistSpec, choiceDisplayFormat, compileHostExtras, compileInstallPlan, dashboardBlocks, deferredRelationFields, deferredRelations, derivedFieldSpec, describeCheck, describeResultJsonSchema, describeSpec, describeVocabulary, digestSpec, documentBody, domainsIn, drillDownDashboard, evalFormula, extrasProblems, fallbackView, foreignTextProblems, formArgs, formulaFieldSpec, formulaOrder, formulaRefs, foundationTokens, isSelfDeclaredField, isTimedField, lastResortTrim, meaningWords, mergeDescribeParts, 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, templateText, templateUpgradeHint, timedFieldSpec, toUseCase, unwrap, upgradeTemplateInstall, useCaseProblemsOf, validateTemplate, viewMatches, viewSpec, zoneOffset };
@@ -1696,9 +1696,9 @@ var ACCOUNT_DOOR_PATTERNS = [
1696
1696
  instead: "Call create_fixture_user / fixture_user (aidream/aidream/testing/persona.py) or createFixtureUser / withFixtureUser (scripts/lib/persona.mjs). A rolled-back raw insert is allowed with a trailing matrx-fixture:rollback-only <reason> on the same line."
1697
1697
  }
1698
1698
  ];
1699
- function findPlaceholders(text) {
1699
+ function findPlaceholders(text2) {
1700
1700
  const hits = [];
1701
- const lines = text.split("\n");
1701
+ const lines = text2.split("\n");
1702
1702
  for (const line of lines) {
1703
1703
  if (ALLOW_PRAGMA.test(line)) continue;
1704
1704
  for (const pattern of PLACEHOLDER_PATTERNS) {
@@ -2564,8 +2564,8 @@ function bookingColumnsProblem(tables, booking) {
2564
2564
  if (clash) return `The booking page adds a "${label}" column to "${t.name}", which already has one ("${clash.key}"). Rename that column, or key it "${key}".`;
2565
2565
  }
2566
2566
  const status = t.fields.find((f) => f.key === "status");
2567
- const words = new Set((status?.choices ?? []).map((c) => c.toLowerCase()));
2568
- if (status && (!words.has("booked") || !words.has("cancelled"))) {
2567
+ const words2 = new Set((status?.choices ?? []).map((c) => c.toLowerCase()));
2568
+ if (status && (!words2.has("booked") || !words2.has("cancelled"))) {
2569
2569
  return `The booking page writes "booked" and "cancelled" into "${t.name}"'s status, and its choices do not hold both.`;
2570
2570
  }
2571
2571
  return null;
@@ -2683,8 +2683,8 @@ var q = (n, d) => {
2683
2683
  };
2684
2684
  var qAdd = (a, b) => q(a.n * b.d + b.n * a.d, a.d * b.d);
2685
2685
  var qCmp = (a, b) => a.n * b.d === b.n * a.d ? 0 : a.n * b.d < b.n * a.d ? -1 : 1;
2686
- function parseNumeric(text) {
2687
- const m = /^\s*([+-]?)(\d*)(?:\.(\d*))?(?:[eE]([+-]?\d+))?\s*$/.exec(text);
2686
+ function parseNumeric(text2) {
2687
+ const m = /^\s*([+-]?)(\d*)(?:\.(\d*))?(?:[eE]([+-]?\d+))?\s*$/.exec(text2);
2688
2688
  if (!m || !m[2] && !m[3]) return null;
2689
2689
  const frac = m[3] ?? "";
2690
2690
  let n = BigInt(`${m[1] === "-" ? "-" : ""}${m[2] || "0"}${frac}` || "0");
@@ -2734,9 +2734,9 @@ function unwrap(v) {
2734
2734
  return v && typeof v === "object" && !Array.isArray(v) && "value" in v ? unwrap(v.value) : v;
2735
2735
  }
2736
2736
  function boundMoment(raw) {
2737
- const text = raw.trim();
2738
- if (!text) return null;
2739
- const at = Date.parse(/^\d{4}-\d{2}-\d{2}$/.test(text) ? `${text}T00:00:00Z` : text);
2737
+ const text2 = raw.trim();
2738
+ if (!text2) return null;
2739
+ const at = Date.parse(/^\d{4}-\d{2}-\d{2}$/.test(text2) ? `${text2}T00:00:00Z` : text2);
2740
2740
  return Number.isNaN(at) ? null : at;
2741
2741
  }
2742
2742
  function storeFilterMatches(row, filter, _timeZone) {
@@ -2774,8 +2774,8 @@ function toFx(n) {
2774
2774
  return { k: "call", f: n.name, args: n.args.map(toFx) };
2775
2775
  }
2776
2776
  }
2777
- function parseGateFormula(text) {
2778
- const parsed = parseFormulaText(text);
2777
+ function parseGateFormula(text2) {
2778
+ const parsed = parseFormulaText(text2);
2779
2779
  return parsed.ok ? toFx(parsed.ast) : parsed.error;
2780
2780
  }
2781
2781
  function formulaRefs(n) {
@@ -3125,8 +3125,8 @@ function capabilitiesUsed(spec) {
3125
3125
  }
3126
3126
  var DESIGNATED_REAL_NUMBERS = ["9498072145", "9496662578", "9497027626"];
3127
3127
  var DIGIT_ZEROS = [1632, 1776, 1984, 2406, 2534, 2662, 2790, 2918, 3046, 3174, 3302, 3430, 3664, 3792, 3872, 4160, 6112, 6160, 65296];
3128
- function normalizeForPhones(text) {
3129
- return text.normalize("NFKC").replace(/\p{Nd}/gu, (c) => {
3128
+ function normalizeForPhones(text2) {
3129
+ return text2.normalize("NFKC").replace(/\p{Nd}/gu, (c) => {
3130
3130
  const cp = c.codePointAt(0) ?? 48;
3131
3131
  const zero = DIGIT_ZEROS.find((z) => cp >= z && cp <= z + 9);
3132
3132
  return zero === void 0 ? c : String(cp - zero);
@@ -3140,8 +3140,8 @@ function nanpBad(area, exchange, line) {
3140
3140
  const n = Number(line);
3141
3141
  return exchange !== "555" || n < 100 || n > 199 || DESIGNATED_REAL_NUMBERS.includes(`${area}${exchange}${line}`);
3142
3142
  }
3143
- function phonesOutsideFictionalRange(text, phoneField = false) {
3144
- const t = normalizeForPhones(text);
3143
+ function phonesOutsideFictionalRange(text2, phoneField = false) {
3144
+ const t = normalizeForPhones(text2);
3145
3145
  const out = [];
3146
3146
  for (const m of t.matchAll(INTL)) {
3147
3147
  const digits = m[0].replace(/\D/g, "");
@@ -3195,11 +3195,11 @@ var PUBLIC_MAIL_DOMAINS = [
3195
3195
  "163.com",
3196
3196
  "web.de"
3197
3197
  ];
3198
- function domainsIn(text) {
3198
+ function domainsIn(text2) {
3199
3199
  const found = /* @__PURE__ */ new Set();
3200
- for (const m of text.matchAll(/[a-z0-9._%+-]+@([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase());
3201
- for (const m of text.matchAll(/\bhttps?:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase().replace(/^www\./, ""));
3202
- for (const m of text.matchAll(/\bwww\.([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase().replace(/\.$/, ""));
3200
+ for (const m of text2.matchAll(/[a-z0-9._%+-]+@([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase());
3201
+ for (const m of text2.matchAll(/\bhttps?:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase().replace(/^www\./, ""));
3202
+ for (const m of text2.matchAll(/\bwww\.([a-z0-9-]+(?:\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? "").toLowerCase().replace(/\.$/, ""));
3203
3203
  return [...found];
3204
3204
  }
3205
3205
  function numberedStreet(line) {
@@ -3285,7 +3285,7 @@ function peopleOf(spec) {
3285
3285
  function proseOf(spec) {
3286
3286
  return templateText(spec).filter(([at]) => !at.startsWith("tables ("));
3287
3287
  }
3288
- var words8 = (text) => text.toLowerCase().replace(/\{\{[^}]*\}\}/g, " ").split(/[^a-z0-9']+/).filter(Boolean);
3288
+ var words8 = (text2) => text2.toLowerCase().replace(/\{\{[^}]*\}\}/g, " ").split(/[^a-z0-9']+/).filter(Boolean);
3289
3289
  var FOREIGN_INDEX = /* @__PURE__ */ new WeakMap();
3290
3290
  function foreignIndexOf(other) {
3291
3291
  let ix = FOREIGN_INDEX.get(other);
@@ -3305,8 +3305,8 @@ function foreignIndexOf(other) {
3305
3305
  }
3306
3306
  function foreignTextProblems(spec, library) {
3307
3307
  const problems = [];
3308
- const text = templateText(spec);
3309
- const hay = text.map(([at, v]) => [at, v.toLowerCase()]);
3308
+ const text2 = templateText(spec);
3309
+ const hay = text2.map(([at, v]) => [at, v.toLowerCase()]);
3310
3310
  const all = hay.map(([, v]) => v).join("\n");
3311
3311
  const esc = (w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3312
3312
  const find = (word) => {
@@ -3316,9 +3316,9 @@ function foreignTextProblems(spec, library) {
3316
3316
  return hay.find(([, v]) => re.test(v));
3317
3317
  };
3318
3318
  const mine = proseOf(spec).map(([at, w]) => {
3319
- const words = words8(w);
3319
+ const words2 = words8(w);
3320
3320
  const runs = [];
3321
- for (let i = 0; i + 8 <= words.length; i += 1) runs.push(words.slice(i, i + 8).join(" "));
3321
+ for (let i = 0; i + 8 <= words2.length; i += 1) runs.push(words2.slice(i, i + 8).join(" "));
3322
3322
  return [at, runs];
3323
3323
  });
3324
3324
  for (const other of library.specs) {
@@ -3353,8 +3353,8 @@ var SYNONYM_WORDS = {
3353
3353
  function labelMeans(f, sameAs) {
3354
3354
  const label = norm(f.label);
3355
3355
  if (sameAs.includes(label)) return true;
3356
- const words = new Set(label.split(" "));
3357
- return Object.values(SYNONYM_WORDS).some((group) => group.some((w) => words.has(w)) && sameAs.some((s) => group.some((w) => s.split(" ").includes(w))));
3356
+ const words2 = new Set(label.split(" "));
3357
+ return Object.values(SYNONYM_WORDS).some((group) => group.some((w) => words2.has(w)) && sameAs.some((s) => group.some((w) => s.split(" ").includes(w))));
3358
3358
  }
3359
3359
  var sameJson = (a, b) => JSON.stringify(a) === JSON.stringify(b);
3360
3360
  var sortedJson = (v) => JSON.stringify(Object.keys(v).sort().map((k) => [k, v[k]]));
@@ -3946,8 +3946,8 @@ function validateTemplate(raw, options = {}) {
3946
3946
  for (const by of dim.default?.by ?? []) if (!dimKeys.has(by.split(":")[0] ?? "")) say(`${at}.default.by`, `The first screen groups by "${by}", which is not a dimension.`);
3947
3947
  for (const show of dim.default?.show ?? []) if (!inferredMeasures.has(show) && !newMeasures.has(show)) say(`${at}.default.show`, `The first screen shows "${show}", which is not a measure of this table.`);
3948
3948
  });
3949
- const checkMerge = (at, table, text2) => {
3950
- for (const m of text2.matchAll(MERGE_TOKEN)) {
3949
+ const checkMerge = (at, table, text3) => {
3950
+ for (const m of text3.matchAll(MERGE_TOKEN)) {
3951
3951
  const key = m[1] ?? "";
3952
3952
  const f = fieldOf(table, key);
3953
3953
  if (!f) say(at, `{{${key}}} does not resolve: the store merges only the fields of "${table}" (no today, no business details).`);
@@ -4855,7 +4855,7 @@ function validateTemplate(raw, options = {}) {
4855
4855
  const f = fieldOf(table, key);
4856
4856
  if (f?.absoluteDates) say(`tables (${table}).fields (${key})`, `"${f.label}" holds history (absoluteDates), so it cannot drive ${where}: schedule dates are relative to install day.`);
4857
4857
  }
4858
- const text = JSON.stringify(raw);
4858
+ const text2 = JSON.stringify(raw);
4859
4859
  const isPhoneField = (f) => f.parityType === "phone" || /(^|_)(phone|mobile|cell|fax|tel)(_|$)/.test(f.key) || /\b(phone|mobile|cell|fax)\b/.test(norm(f.label));
4860
4860
  const phoneHits = /* @__PURE__ */ new Set();
4861
4861
  for (const p of phonesOutsideFictionalRange(raw.business?.phone ?? "", true)) phoneHits.add(p);
@@ -4873,7 +4873,7 @@ function validateTemplate(raw, options = {}) {
4873
4873
  for (const d of raw.provenance?.fictionalDomains ?? []) {
4874
4874
  if (PUBLIC_MAIL_DOMAINS.includes(d.toLowerCase())) say("provenance.fictionalDomains", `"${d}" is a public mail provider real people use, so it is never fictional. Give each person a mailbox on an invented domain.`);
4875
4875
  }
4876
- for (const domain of /* @__PURE__ */ new Set([...domainsIn(text), ...websites])) {
4876
+ for (const domain of /* @__PURE__ */ new Set([...domainsIn(text2), ...websites])) {
4877
4877
  if (!declaredDomains.has(domain)) say("provenance.fictionalDomains", `"${domain}" is used but not declared fictional. List every invented domain in provenance.fictionalDomains (each is checked not to resolve).`);
4878
4878
  }
4879
4879
  const streets = new Set((raw.provenance?.fictionalStreets ?? []).map((s) => s.toLowerCase()));
@@ -4916,10 +4916,10 @@ function validateTemplate(raw, options = {}) {
4916
4916
  if (seeded) say(`tables (${t.token}).fields (${f.key})`, `"${f.label}" is computed by the store (${f.parityType}), and ${seeded} seed row(s) write a value into it; leave it to the store.`);
4917
4917
  }
4918
4918
  }
4919
- const label = (at, text2, kind) => {
4920
- if (!text2) return;
4921
- const hit = findBannedLabel(text2, kind);
4922
- if (hit) say(at, `"${text2}" is ${hit.why}. Use the practitioner's own word.`);
4919
+ const label = (at, text3, kind) => {
4920
+ if (!text3) return;
4921
+ const hit = findBannedLabel(text3, kind);
4922
+ if (hit) say(at, `"${text3}" is ${hit.why}. Use the practitioner's own word.`);
4923
4923
  };
4924
4924
  for (const t of own) {
4925
4925
  label(`tables (${t.token}).name`, t.name, "table");
@@ -4952,9 +4952,9 @@ function validateTemplate(raw, options = {}) {
4952
4952
  for (const [k, v] of Object.entries(r.values ?? {})) {
4953
4953
  const f = byKey.get(k);
4954
4954
  if (!f || isRelation(f) || f.parityType === "email" || f.parityType === "url" || f.parityType === "phone") continue;
4955
- const text2 = unwrap(v);
4956
- if (typeof text2 === "string" && !RELATIVE_DATE.test(text2) && STALE.test(text2)) {
4957
- say(`tables (${t.token}).rows (${r.key}).${k}`, `"${text2}" says "${STALE.exec(text2)?.[0]}", which is only true on the day it was written. Put the date in a date field written relative to install day ("@today+1b 10:00"), and keep the text free of "today" and "next week".`);
4955
+ const text3 = unwrap(v);
4956
+ if (typeof text3 === "string" && !RELATIVE_DATE.test(text3) && STALE.test(text3)) {
4957
+ say(`tables (${t.token}).rows (${r.key}).${k}`, `"${text3}" says "${STALE.exec(text3)?.[0]}", which is only true on the day it was written. Put the date in a date field written relative to install day ("@today+1b 10:00"), and keep the text free of "today" and "next week".`);
4958
4958
  }
4959
4959
  }
4960
4960
  }
@@ -4962,14 +4962,14 @@ function validateTemplate(raw, options = {}) {
4962
4962
  for (const t of own) {
4963
4963
  for (const f of t.fields) {
4964
4964
  const at = `tables (${t.token}).fields (${f.key})`;
4965
- const text2 = `${f.key} ${norm(f.label)}`;
4965
+ const text3 = `${f.key} ${norm(f.label)}`;
4966
4966
  const e = effective(t.token, f);
4967
4967
  const floor = sensitivityFloorOf(t, f);
4968
4968
  if (floor === "restricted" && !(e.sensitivity === "restricted" && e.contextPolicy === "exclude")) {
4969
4969
  say(at, `"${f.label}" is the kind of value that is restricted and kept from the AI (restricted + exclude).`);
4970
4970
  } else if (floor === "confidential" && SENSITIVITY_RANK.indexOf(e.sensitivity) < 2) {
4971
4971
  say(at, `"${f.label}" reaches a person or a home, so it is at least confidential.`);
4972
- } else if (/note/.test(text2) && e.sensitivity === "public") {
4972
+ } else if (/note/.test(text3) && e.sensitivity === "public") {
4973
4973
  say(at, `"${f.label}" is somebody's notes; notes are never public.`);
4974
4974
  }
4975
4975
  }
@@ -5154,8 +5154,8 @@ function validateTemplate(raw, options = {}) {
5154
5154
  const status2 = fieldOf(e.table, "status");
5155
5155
  if (!status2) say(at, `A booking table needs a choice field keyed \`status\` whose choices include "booked" and "cancelled"; "${e.table}" has none. Add it, so a held time can be confirmed and given back.`);
5156
5156
  else if (isChoice(status2)) {
5157
- const words = (status2.choices ?? []).map((c) => c.trim().toLowerCase());
5158
- const missing = ["booked", "cancelled"].filter((w) => !words.includes(w));
5157
+ const words2 = (status2.choices ?? []).map((c) => c.trim().toLowerCase());
5158
+ const missing = ["booked", "cancelled"].filter((w) => !words2.includes(w));
5159
5159
  if (missing.length) say(`${at}`, `This table's Status is a list of choices, and it has no choice called ${missing.join(" or ")} \u2014 the booking page writes those words (custom.booking_declare refuses).`);
5160
5160
  }
5161
5161
  const columns = bookingColumnsProblem(tables, e);
@@ -5275,9 +5275,9 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
5275
5275
  if (agent?.question?.expect) {
5276
5276
  const qq = agent.question;
5277
5277
  const ask = norm(qq.ask);
5278
- const words = (t) => norm(t).split(" ").filter((w) => w.length >= 4);
5278
+ const words2 = (t) => norm(t).split(" ").filter((w) => w.length >= 4);
5279
5279
  const askWords = new Set(ask.split(" "));
5280
- const mentions = (t) => !!norm(t) && ask.includes(norm(t)) || words(t).some((w) => ask.includes(w.replace(/s$/, ""))) || words(t).length === 0 && norm(t).split(" ").filter(Boolean).some((w) => w.length >= 3 && (askWords.has(w) || askWords.has(`${w}s`)));
5280
+ const mentions = (t) => !!norm(t) && ask.includes(norm(t)) || words2(t).some((w) => ask.includes(w.replace(/s$/, ""))) || words2(t).length === 0 && norm(t).split(" ").filter(Boolean).some((w) => w.length >= 3 && (askWords.has(w) || askWords.has(`${w}s`)));
5281
5281
  for (const [k, v] of Object.entries(qq.expect.filter ?? {})) {
5282
5282
  if (typeof v === "string" && !mentions(v) && !ask.includes(norm(v))) say("agent.question.ask", `It filters on ${k} = "${v}", and the question never says so.`);
5283
5283
  }
@@ -5359,9 +5359,9 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
5359
5359
  if (!t) return false;
5360
5360
  if (says.includes(norm(t))) return true;
5361
5361
  const long = [...new Set(norm(t).split(" ").filter((w) => w.length >= 4))];
5362
- const words = long.length ? long : [...new Set(norm(t).split(" ").filter((w) => w.length >= 2))];
5362
+ const words2 = long.length ? long : [...new Set(norm(t).split(" ").filter((w) => w.length >= 2))];
5363
5363
  const said = new Set(says.split(" "));
5364
- return words.length > 0 && words.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words.length);
5364
+ return words2.length > 0 && words2.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words2.length);
5365
5365
  };
5366
5366
  if (!a) return;
5367
5367
  if (a.kind === "move" || a.kind === "edit" || a.kind === "archive" || a.kind === "restore") {
@@ -5462,9 +5462,9 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
5462
5462
  const LABEL_MAX = 40;
5463
5463
  const IMPLEMENTATION = /\b(?:the\s+)?(?:ai|a\.i\.|agent|assistant|llm|model)\b[^.]*\b(?:reads?|sees?|never|cannot|can't|won't|doesn't|does not|is kept)\b|\b(?:never|not)\b[^.]*\b(?:ai|agent)\b|\bthe store\b|\bthis field\b|\bthis column\b|\bthe booking page writes\b|\bwrites? (?:a |the )?(?:booked )?time here\b|\bcustom\.[a-z_]+|\{\{|\b[a-z]+_[a-z0-9_]+\b|\b(?:sum|avg|count|min|max)\s*\(|\s=\s/i;
5464
5464
  const STAFF_VOICE = /\bwe\b|\bour system\b/i;
5465
- const screen = (at, text2, slot, opts = {}) => {
5466
- if (!text2?.trim()) return;
5467
- const t = text2.trim();
5465
+ const screen = (at, text3, slot, opts = {}) => {
5466
+ if (!text3?.trim()) return;
5467
+ const t = text3.trim();
5468
5468
  if (slot === "label" && (t.length > LABEL_MAX || t.split(/\s+/).length > 6)) say(at, `"${t}" is a label (${t.length} characters); keep it to a few words \u2014 the name of the thing, no explanation.`);
5469
5469
  if (slot === "secondary" && (t.length > 60 || sentences(t) > 1)) say(at, `"${t}" is ${t.length} characters; help text is one line of at most 60, one sentence.`);
5470
5470
  if (slot === "tooltip" && (t.length > 140 || sentences(t) > 1)) say(at, `"${t.slice(0, 60)}\u2026" is ${t.length} characters; a description is one sentence of at most 140.`);
@@ -5839,14 +5839,14 @@ var holdsPeople = (t) => t.subject ? t.subject === "person" : t.fields.some((f)
5839
5839
  var GOOD_OUTCOME = /^(completed?|done|paid|approved|won|closed won|booked|confirmed|delivered|resolved|published|signed|passed|hired|accepted)$/i;
5840
5840
  var BAD_OUTCOME = /^(cancell?ed|skipped|lost|closed lost|denied|rejected|no[- ]show|failed|overdue|declined|void(ed)?|refunded|churned|expired|blocked)$/i;
5841
5841
  function sensitivityFloorOf(table, f) {
5842
- const text = `${f.key} ${norm(f.label)}`;
5842
+ const text2 = `${f.key} ${norm(f.label)}`;
5843
5843
  const billingTable = /(invoice|bill|statement|receipt|payment|charge|fee|order|account)/i.test(`${table.token} ${table.labelSingular ?? ""}`);
5844
5844
  const criminalCharges = /(^|_)charges?($|_)/.test(f.key) && behaviorOf(f) === "text" && !billingTable;
5845
5845
  const phoneLike = behaviorOf(f) === "text" && /\b(cell|mobile|phone)\b/.test(norm(f.label));
5846
5846
  const personal = PERSONAL_ONLY.test(f.key) || /\b(medical conditions?|medications?|diagnos[ie]s)\b/.test(norm(f.label));
5847
5847
  const floored = (RESTRICTED_KEY.test(f.key) || RESTRICTED_LABEL.test(norm(f.label)) || criminalCharges) && (!personal || holdsPeople(table));
5848
5848
  if (floored) return "restricted";
5849
- if (f.parityType === "phone" || phoneLike || f.parityType === "email" || /address|street/.test(text)) return "confidential";
5849
+ if (f.parityType === "phone" || phoneLike || f.parityType === "email" || /address|street/.test(text2)) return "confidential";
5850
5850
  return null;
5851
5851
  }
5852
5852
 
@@ -6332,6 +6332,7 @@ function describeSpec(template) {
6332
6332
  s.specVersion = 1;
6333
6333
  if (typeof s.version !== "number") s.version = 1;
6334
6334
  if (typeof s.audience !== "string") s.audience = "organization";
6335
+ if (s.audience === "personal") s.audience = "individual";
6335
6336
  if (typeof s.cleanupTag !== "string" && typeof s.id === "string") s.cleanupTag = `describe:${s.id}`;
6336
6337
  for (const k of ["relationships", "sharedBlocks", "views", "forms", "dimensions", "extras"]) if (!Array.isArray(s[k])) s[k] = [];
6337
6338
  if (Array.isArray(s.tables)) s.tables = s.tables.map(describeTable);
@@ -6374,9 +6375,9 @@ function stemWord(w) {
6374
6375
  if (s.length > 4 && (s.endsWith("y") || s.endsWith("e"))) s = s.slice(0, -1);
6375
6376
  return s;
6376
6377
  }
6377
- function meaningWords(text) {
6378
- const words = text.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((w) => w.toLowerCase()).filter((w) => !FILLER.has(w)).map(stemWord).filter(Boolean);
6379
- return [...new Set(words)].sort();
6378
+ function meaningWords(text2) {
6379
+ const words2 = text2.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((w) => w.toLowerCase()).filter((w) => !FILLER.has(w)).map(stemWord).filter(Boolean);
6380
+ return [...new Set(words2)].sort();
6380
6381
  }
6381
6382
  var same = (a, b) => a.length > 0 && a.length === b.length && a.every((w, i) => w === b[i]);
6382
6383
  function sameMeaning(a, b) {
@@ -6916,31 +6917,31 @@ function fixFormulaRefs(spec, fixes) {
6916
6917
  if (f.parityType !== "formula" || typeof f.formula !== "string") continue;
6917
6918
  const others = t.fields.filter((x) => x.key !== f.key);
6918
6919
  const labelFor = (name) => others.find((x) => x.label === name)?.label ?? others.find((x) => x.key === name)?.label ?? others.find((x) => same3(x.key, name))?.label ?? others.find((x) => same3(x.label, name))?.label;
6919
- const text = f.formula.replace(/^\s*=\s*/, "");
6920
+ const text2 = f.formula.replace(/^\s*=\s*/, "");
6920
6921
  let out = "";
6921
6922
  let i = 0;
6922
- while (i < text.length) {
6923
- const c = text[i];
6923
+ while (i < text2.length) {
6924
+ const c = text2[i];
6924
6925
  if (c === "{") {
6925
- const j = text.indexOf("}", i);
6926
+ const j = text2.indexOf("}", i);
6926
6927
  if (j < 0) {
6927
- out += text.slice(i);
6928
+ out += text2.slice(i);
6928
6929
  break;
6929
6930
  }
6930
- const name = text.slice(i + 1, j).trim();
6931
+ const name = text2.slice(i + 1, j).trim();
6931
6932
  out += `{${labelFor(name) ?? name}}`;
6932
6933
  i = j + 1;
6933
6934
  } else if (c === "'" || c === '"') {
6934
- const j = text.indexOf(c, i + 1);
6935
+ const j = text2.indexOf(c, i + 1);
6935
6936
  if (j < 0) {
6936
- out += text.slice(i);
6937
+ out += text2.slice(i);
6937
6938
  break;
6938
6939
  }
6939
- out += text.slice(i, j + 1);
6940
+ out += text2.slice(i, j + 1);
6940
6941
  i = j + 1;
6941
6942
  } else if (/[A-Za-z_]/.test(c)) {
6942
- const m = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text.slice(i))[0];
6943
- const after = text.slice(i + m.length).trimStart()[0];
6943
+ const m = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text2.slice(i))[0];
6944
+ const after = text2.slice(i + m.length).trimStart()[0];
6944
6945
  const label = after === "(" ? void 0 : labelFor(m);
6945
6946
  out += label ? `{${label}}` : m;
6946
6947
  i += m.length;
@@ -7672,7 +7673,7 @@ function describeVocabulary() {
7672
7673
  field_shape: FIELD_SHAPE_FACTS,
7673
7674
  formula_shape: FORMULA_SHAPE_FACTS,
7674
7675
  relationship_shape: RELATIONSHIP_SHAPE_FACTS,
7675
- phone_rule: "seed phone numbers are fictional: 555-0100 to 555-0199 in North America (e.g. (813) 555-0142) or a UK Ofcom drama number (e.g. 020 7946 0123); never a real-looking number.",
7676
+ phone_rule: "seed phone numbers are fictional: 555-0100 to 555-0199 (e.g. (813) 555-0142); never a real-looking number, and never a number from a country the person did not name.",
7676
7677
  team_rule: "the team (name, role, work email, mobile, start date) is the shared team_member block; do not declare a table with those fields \u2014 keep a table of your own to just name and role, or point a relation field at team_member.",
7677
7678
  title_field: "a table's titleField is the key of a plain text-like field of that same table (a name, a title) \u2014 never a link to another table, a formula or a timed date"
7678
7679
  };
@@ -7735,6 +7736,61 @@ function safeReuses(spec, reuses, existingTables) {
7735
7736
  const out = { ...spec, tables: spec.tables.map((t) => rename.has(t.token) ? { ...t, ...rename.get(t.token) } : t) };
7736
7737
  return { spec: out, reuses: kept, notes, converted };
7737
7738
  }
7739
+
7740
+ // src/templates/describe/result-schema.ts
7741
+ var DESCRIBE_RESULT_KIND = "describe_template_result";
7742
+ var text = { type: "string" };
7743
+ var words = (list) => ({ type: "string", enum: [...list] });
7744
+ var jsonText = { type: "string", description: "one JSON object, as text" };
7745
+ var jsonTextList = { type: "array", items: jsonText };
7746
+ var DESCRIBE_TEXT_PARTS = ["tables", "relationships", "views", "forms", "extras"];
7747
+ function describeResultJsonSchema() {
7748
+ return {
7749
+ type: "object",
7750
+ required: ["__kind", "template", "notes", "reuses"],
7751
+ properties: {
7752
+ __kind: { type: "string", enum: [DESCRIBE_RESULT_KIND] },
7753
+ template: {
7754
+ type: "object",
7755
+ required: ["id", "useCase", "industry", "vertical", "job", "teaches", "business", "tables", "forms"],
7756
+ properties: {
7757
+ id: text,
7758
+ useCase: text,
7759
+ industry: words(INDUSTRY_GROUPS),
7760
+ vertical: text,
7761
+ job: words(TEMPLATE_JOBS),
7762
+ audience: words(TEMPLATE_AUDIENCES),
7763
+ teaches: words(TEACHES_FEATURES),
7764
+ business: jsonText,
7765
+ tables: jsonTextList,
7766
+ relationships: jsonTextList,
7767
+ views: jsonTextList,
7768
+ forms: jsonTextList,
7769
+ extras: jsonTextList
7770
+ }
7771
+ },
7772
+ notes: { type: "array", items: text },
7773
+ reuses: { type: "array", items: { type: "object", required: ["token", "existing_table_id"], properties: { token: text, existing_table_id: text } } }
7774
+ }
7775
+ };
7776
+ }
7777
+ function open(value, at) {
7778
+ if (typeof value !== "string") return value;
7779
+ try {
7780
+ return JSON.parse(value);
7781
+ } catch {
7782
+ throw new Error(`${at} was not valid JSON text.`);
7783
+ }
7784
+ }
7785
+ function parseDescribeTemplate(template) {
7786
+ const out = { ...template };
7787
+ if ("business" in out) out.business = open(out.business, "business");
7788
+ for (const k of DESCRIBE_TEXT_PARTS) {
7789
+ const v = out[k];
7790
+ if (Array.isArray(v)) out[k] = v.map((x, i) => open(x, `${k}[${i}]`));
7791
+ }
7792
+ return out;
7793
+ }
7738
7794
  export {
7739
7795
  BAD_OUTCOME,
7740
7796
  BOOKING_AVAILABILITY_FACTS,
@@ -7744,6 +7800,7 @@ export {
7744
7800
  CHOICE_COLORS,
7745
7801
  CHOICE_COLORS_DISTINCT_UP_TO,
7746
7802
  DEFAULT_TEMPLATE_AGENT,
7803
+ DESCRIBE_RESULT_KIND,
7747
7804
  DESIGNATED_REAL_NUMBERS,
7748
7805
  ENTITY_REFERENCE_KINDS,
7749
7806
  FORMULA_FUNCTION_NAMES,
@@ -7801,6 +7858,7 @@ export {
7801
7858
  deferredRelations,
7802
7859
  derivedFieldSpec,
7803
7860
  describeCheck,
7861
+ describeResultJsonSchema,
7804
7862
  describeSpec,
7805
7863
  describeVocabulary,
7806
7864
  digestSpec,
@@ -7829,6 +7887,7 @@ export {
7829
7887
  numberedStreet,
7830
7888
  packageDescribeResult,
7831
7889
  parseAt,
7890
+ parseDescribeTemplate,
7832
7891
  parseGateFormula,
7833
7892
  parseNumeric,
7834
7893
  pathOfAt,