@object-ui/i18n 17.7.0 → 18.0.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.
@@ -17,7 +17,7 @@ const en = {
17
17
  },
18
18
  },
19
19
  // objectui#2600 B5 — capability picker scope group headers (labels come from
20
- // the sys_capability registry; only these group titles are UI strings).
20
+ // the capability registry; only these group titles are UI strings).
21
21
  capability: {
22
22
  group: {
23
23
  platform: 'Platform',
@@ -30,45 +30,13 @@ const en = {
30
30
  manage_users: 'Manage Users',
31
31
  manage_org_users: 'Manage Organization Users',
32
32
  manage_metadata: 'Manage Metadata',
33
- manage_org_presentation: 'Manage Organization Presentation',
33
+ manage_mailboxes: 'Manage Mailboxes',
34
34
  manage_platform_settings: 'Manage Platform Settings',
35
35
  setup_access: 'Setup Access',
36
36
  setup_write: 'Write Settings',
37
37
  studio_access: 'Studio Access',
38
38
  manage_sharing: 'Manage Sharing',
39
- },
40
- },
41
- // objectui#3546 slice six — the read-only facet summary + Studio deep-link a
42
- // `sys_permission_set` record shows for its six authorization facets
43
- // (ADR-0056 P1, plugin-detail's PermissionFacetLink).
44
- //
45
- // The four count labels are plural families. i18next looks up the ONE suffix
46
- // a language's rules ask for, so every pack spells out every CLDR category its
47
- // language selects (`en`: `_one`/`_other`; `ru` adds `_few`/`_many`, `ar`
48
- // `_zero`/`_two`/`_few`/`_many` — objectui#11432); the BASE key (no suffix)
49
- // answers a call made without a count. `all-locales-key-parity.test.ts`
50
- // derives the required slots from `Intl.PluralRules`, and
51
- // `perm-home-namespace-3546.test.tsx` renders every language at counts
52
- // 1/2/3/5/11/21/100.
53
- perm: {
54
- facet: {
55
- none: 'None',
56
- more: '+{{count}} more',
57
- objects: '{{count}} objects',
58
- objects_one: '{{count}} object',
59
- objects_other: '{{count}} objects',
60
- fields: '{{count}} field rules',
61
- fields_one: '{{count}} field rule',
62
- fields_other: '{{count}} field rules',
63
- rls: '{{count}} RLS policies',
64
- rls_one: '{{count}} RLS policy',
65
- rls_other: '{{count}} RLS policies',
66
- tabs: '{{count}} tab rules',
67
- tabs_one: '{{count}} tab rule',
68
- tabs_other: '{{count}} tab rules',
69
- adminScope: 'Delegated admin configured',
70
- designInStudio: 'Design in Studio →',
71
- designInStudioHint: 'Design in Studio',
39
+ view_all_audit_log: 'View All Audit Log',
72
40
  },
73
41
  },
74
42
  lookup: {
@@ -152,6 +120,7 @@ const en = {
152
120
  itemCount_one: '{{count}} item',
153
121
  itemCount_other: '{{count}} items',
154
122
  toggleSidebar: 'Toggle sidebar',
123
+ breadcrumb: 'Breadcrumb',
155
124
  package: 'Package',
156
125
  done: 'Done',
157
126
  editInStudio: 'Edit in studio',
@@ -183,6 +152,12 @@ const en = {
183
152
  // `visible` gate outranks (objectui#4191) — the deep link or host asked
184
153
  // for it, but the author hid it on this surface.
185
154
  notAvailableHere: '"{{action}}" is not available on the current page.',
155
+ // The reason a record action greyed out by its declared `disabled`
156
+ // predicate gives on hover, on focus and as its accessible description
157
+ // (objectui#11811): the generic one, since the action spec carries no
158
+ // author-written reason. Not `notAvailableHere` — that one is about the
159
+ // page, this one about the record.
160
+ notAvailableForRecord: 'Not available for this record',
186
161
  // The success toast the action runner shows when no `outcomeMessages`
187
162
  // entry applies to the answer and the action declares no `successMessage`;
188
163
  // the server's message plays no part (objectui#11344). It is the one
@@ -264,6 +239,15 @@ const en = {
264
239
  // The hint under a field the caller may read but not write, shown when the
265
240
  // field declares no description of its own (objectui#11071).
266
241
  deniedDescription: 'You do not have edit access to this field.',
242
+ // The hint under an empty field on a create form whose default the server
243
+ // resolves at insert — a CEL expression or a runtime token the form cannot
244
+ // evaluate, so it leaves the field empty and omits it (objectui#12108).
245
+ // Shown only while the field is empty: a typed value is saved instead.
246
+ serverDefaultHint: 'Set automatically when saved.',
247
+ // The size-limit hint the flat `ObjectForm` appends to a `file` or `image`
248
+ // field's description when the field declares `maxSize` (objectui#12156).
249
+ // `{{size}}` is the formatted limit ("10.0 MB"); only the words translate.
250
+ maxFileSize: 'Max size: {{size}}',
267
251
  // The master-detail form's own chrome (objectui#11071): the collection
268
252
  // placeholder while its columns resolve, the document totals stack
269
253
  // (`{{rate}}` is the header's tax rate), the row editor's title
@@ -379,6 +363,8 @@ const en = {
379
363
  exceedsMaxSize: '"{{name}}" exceeds max size ({{max}} MB)',
380
364
  uploadFailed: 'Failed to upload "{{name}}": {{error}}',
381
365
  uploadIncomplete: 'Upload of "{{name}}" did not complete: no file id was returned, so nothing was saved',
366
+ restricted: 'Restricted file',
367
+ restrictedHint: 'You do not have access to the details of this file',
382
368
  },
383
369
  image: {
384
370
  upload: 'Upload image',
@@ -389,10 +375,14 @@ const en = {
389
375
  remove: 'Remove image {{index}}',
390
376
  enlarge: 'Enlarge {{name}}',
391
377
  preview: 'Image preview',
378
+ cropPreview: 'Image crop preview',
392
379
  previous: 'Previous image',
393
380
  next: 'Next image',
394
381
  counter: '{{current}} / {{total}}',
395
382
  },
383
+ percent: {
384
+ slider: 'Percentage',
385
+ },
396
386
  richText: {
397
387
  format: 'Format: {{format}}',
398
388
  basicEditorHint: 'Rich text editor (basic)',
@@ -412,6 +402,10 @@ const en = {
412
402
  search: 'Search objects…',
413
403
  empty: 'No objects found',
414
404
  },
405
+ registryRef: {
406
+ loadFailed: 'The list could not be loaded. You can still type the name.',
407
+ notFound: '{{name}} (not found)',
408
+ },
415
409
  recipient: {
416
410
  selectTypeFirst: 'Select a recipient type first.',
417
411
  loading: 'Loading…',
@@ -510,6 +504,16 @@ const en = {
510
504
  dateTime: {
511
505
  impossibleDay: 'The stored value "{{value}}" is not a real date. Pick a date and time to replace it.',
512
506
  },
507
+ // objectui#12622 — the record form's date picker: its two shortcuts,
508
+ // the clear / calendar buttons' accessible names, and the notice for
509
+ // typed text that names no date ({{format}} is the locale pattern).
510
+ datePicker: {
511
+ today: 'Today',
512
+ tomorrow: 'Tomorrow',
513
+ clear: 'Clear date',
514
+ openCalendar: 'Open calendar',
515
+ invalid: 'Not saved: "{{value}}" is not a date. Type it as {{format}}, or pick one from the calendar.',
516
+ },
513
517
  number: {
514
518
  badInput: 'Not saved: the text in this box is not a number. Enter a plain decimal (example: {{example}}).',
515
519
  },
@@ -559,13 +563,22 @@ const en = {
559
563
  // to plural lookup before the base key, and these packs declare the base
560
564
  // key only; a sentence whose grammar does not bend on the number is
561
565
  // correct at 1 without ten plural entries per pack.
566
+ // objectui#11689 — `BooleanCellRenderer`'s own words (every list
567
+ // surface draws them): the badge a status-named column (`active`,
568
+ // `enabled`, …) shows for `false`, where `{{label}}` is the column label
569
+ // the face is handed, and the completion indicator's accessible names.
570
+ boolean: {
571
+ offBadge: '{{label}} — Off',
572
+ completed: 'Completed',
573
+ notCompleted: 'Not completed',
574
+ },
562
575
  textarea: {
563
576
  characterCount: 'Character count: {{count}} of {{max}}',
564
577
  charactersRemaining: 'Characters remaining: {{count}}',
565
578
  },
566
579
  // objectui#11131 — the line-items grid's default chrome (`GridField`):
567
580
  // its Add button, the read-only grid's empty state, and the list-mode
568
- // grid's empty state. An authored `add_label` still wins over `addLine`,
581
+ // grid's empty state. An authored `addLabel` still wins over `addLine`,
569
582
  // and it fills the `{{label}}` hole (`detail.add` when none is authored).
570
583
  //
571
584
  // objectui#11145 — the rest of that chrome: the column chooser's heading,
@@ -598,10 +611,15 @@ const en = {
598
611
  selectAllRows: 'Select all rows',
599
612
  expandRow: 'Expand row',
600
613
  collapseRow: 'Collapse row',
614
+ rowActions: 'Row actions',
601
615
  hideColumn: 'Hide column',
602
616
  freezeColumn: 'Freeze column',
603
617
  unfreezeColumn: 'Unfreeze column',
604
618
  pageInfo: 'Page {{current}} of {{total}}',
619
+ firstPage: 'First page',
620
+ previousPage: 'Previous page',
621
+ nextPage: 'Next page',
622
+ lastPage: 'Last page',
605
623
  totalRecords: '{{count}} total',
606
624
  noResults: 'No results found',
607
625
  noResultsHint: 'Try adjusting your filters or search query.',
@@ -613,6 +631,9 @@ const en = {
613
631
  modified: '{{count}} row modified',
614
632
  modified_one: '{{count}} row modified',
615
633
  modified_other: '{{count}} rows modified',
634
+ saved: '{{count}} row saved',
635
+ saved_one: '{{count}} row saved',
636
+ saved_other: '{{count}} rows saved',
616
637
  saveFailed: 'Save failed',
617
638
  selected: '{{count}} selected',
618
639
  selected_one: '{{count}} selected',
@@ -631,6 +652,7 @@ const en = {
631
652
  pullToRefresh: 'Pull to refresh',
632
653
  refreshing: 'Refreshing…',
633
654
  openRecord: 'Open record',
655
+ recordUnavailable: '{{object}} · record unavailable',
634
656
  openMenu: 'Open menu',
635
657
  bulkSelected: '{{count}} selected',
636
658
  bulkSelected_one: '{{count}} selected',
@@ -642,6 +664,7 @@ const en = {
642
664
  bulkAllOnPage_other: 'All {{count}} on this page are selected.',
643
665
  bulkSelectAllMatching: 'Select all {{count}} matching',
644
666
  bulkAllMatchingSelected: 'All {{count}} matching records are selected.',
667
+ bulkActions: 'Bulk actions',
645
668
  rowHeight: 'Row height: {{mode}}',
646
669
  empty: 'Empty',
647
670
  yes: 'Yes',
@@ -665,11 +688,18 @@ const en = {
665
688
  // right-to-left — so a pack owns the whole shape. Same reasoning as
666
689
  // `collaboration.resolvedSuffix` below.
667
690
  //
691
+ // `pagePattern` is `pattern` for a figure that covers only the page on
692
+ // screen of a larger matched set — the footer's fallback when the server
693
+ // cannot answer the whole set's figure (objectui#12081 item 3). A whole
694
+ // pattern rather than a suffix, for the same reason: where the scope sits
695
+ // is the pack's.
696
+ //
668
697
  // `countEmpty`/`percentEmpty` (and the filled pair) deliberately share a
669
698
  // word: the trailing `%` is what tells the two families apart on screen,
670
699
  // exactly as the renderer's own comment says.
671
700
  summary: {
672
701
  pattern: '{{label}}: {{value}}',
702
+ pagePattern: '{{label}} (this page): {{value}}',
673
703
  count: 'Count',
674
704
  countEmpty: 'Empty',
675
705
  countFilled: 'Filled',
@@ -767,6 +797,8 @@ const en = {
767
797
  resultsTruncated_one: 'Showing the first {{count}} row result (of {{total}}).',
768
798
  resultsTruncated_other: 'Showing the first {{count}} row results (of {{total}}).',
769
799
  importComplete: 'Import Complete',
800
+ importPartial: 'Import finished with errors',
801
+ importFailed: 'Import failed',
770
802
  imported: '{{count}} imported',
771
803
  createdCount: '{{count}} created',
772
804
  createdCount_one: '{{count}} created',
@@ -792,9 +824,6 @@ const en = {
792
824
  needMatchFields: 'Select at least one field to match on.',
793
825
  matchOnlyField: '(match only)',
794
826
  optCreateOptions: 'Keep unknown option values',
795
- optRunAutomations: 'Run automations & triggers',
796
- optTreatHistorical: 'Import as historical data',
797
- optTreatHistoricalHint: '(import completed records as-is — skip state-machine checks and keep their original timestamps & author instead of stamping now)',
798
827
  optSkipBlankKey: 'Skip rows with a blank match value',
799
828
  optBackground: 'Import in the background',
800
829
  optBackgroundHint: '(runs as an undoable job)',
@@ -809,6 +838,7 @@ const en = {
809
838
  invalidBoolean: '"{{value}}" is not a valid true/false value',
810
839
  invalidNumber: '"{{value}}" is not a valid number',
811
840
  invalidDate: '"{{value}}" is not a valid date',
841
+ invalidTime: '"{{value}}" is not a valid time',
812
842
  invalidOption: '"{{value}}" is not one of the allowed options',
813
843
  requiredValue: 'This field is required',
814
844
  matchAmbiguous: 'Matches more than one existing record — use a unique value or the record id',
@@ -831,6 +861,9 @@ const en = {
831
861
  undoing: 'Undoing…',
832
862
  undoConfirm: 'Undo this import? Records it created will be deleted and records it updated will be restored to their previous values.',
833
863
  reverted: 'Undone',
864
+ undoPartial: '{{count}} rows were not undone. Undo again to retry only those rows.',
865
+ undoPartial_one: '{{count}} row was not undone. Undo again to retry only that row.',
866
+ undoPartial_other: '{{count}} rows were not undone. Undo again to retry only those rows.',
834
867
  jobStatus: {
835
868
  pending: 'Pending',
836
869
  running: 'Running',
@@ -926,15 +959,21 @@ const en = {
926
959
  recordCount_one: '{{count}} record',
927
960
  recordCount_other: '{{count}} records',
928
961
  addRecord: 'Add record',
962
+ // objectui#12703 — the compact list's footer link to the object's list or the block's view.
963
+ viewAll: 'View all',
929
964
  tabs: 'Tabs',
930
965
  allRecords: 'All Records',
931
966
  search: 'Search',
932
967
  filter: 'Filter',
933
968
  filterRecords: 'Filter Records',
969
+ filterActive: 'Filter, {{count}} active',
970
+ filterActive_one: 'Filter, {{count}} active',
971
+ filterActive_other: 'Filter, {{count}} active',
934
972
  sort: 'Sort',
935
973
  sortRecords: 'Sort Records',
936
974
  sortByIdSuffix: '(by ID)',
937
975
  sortRelationalHint: 'Columns that link to another record are not listed: they can only be sorted by the stored ID, not by the name shown in the cell. To sort by that name, denormalize it onto this object as a stored field, written when the source changes, and sort by that. Not a formula field: it is virtual, so no column is stored for it and the server refuses to sort by one.',
976
+ sortRelationalPicked: 'A linked column sorts by the stored ID, not the name shown.',
938
977
  resetSortToDefault: 'Reset to view default',
939
978
  group: 'Group',
940
979
  groupBy: 'Group By',
@@ -952,6 +991,7 @@ const en = {
952
991
  firstRunMessage: 'Create your first record to get started.',
953
992
  noMatches: 'No matching records',
954
993
  noMatchesMessage: 'No records match your current filters or search. Try adjusting or clearing them.',
994
+ viewFilterNoMatchesMessage: 'No records match this view’s filter.',
955
995
  loadErrorTitle: 'Couldn\u2019t load records',
956
996
  loadErrorMessage: 'Something went wrong while loading this data. Check your connection and try again.',
957
997
  loadErrorForbiddenTitle: 'You don\u2019t have access',
@@ -993,14 +1033,15 @@ const en = {
993
1033
  print: 'Print',
994
1034
  hideFieldsTitle: 'Hide Fields',
995
1035
  dataLimitReached: 'Showing first {{limit}} records. More data may be available.',
996
- viewSettings: 'View settings',
997
- viewSettingsHint: 'Grouping, color, density, and visible fields. Applies to everyone who uses this view.',
1036
+ display: 'Display',
1037
+ layout: 'Layout',
1038
+ rowNumbers: 'Row numbers',
1039
+ resetToViewDefault: 'Reset to view default',
998
1040
  addGroup: 'Add group field',
999
1041
  collapsedByDefault: 'Collapsed by default',
1000
1042
  removeGroup: 'Remove',
1001
1043
  inlineEditShort: 'Edit inline',
1002
1044
  inlineEditLabel: 'Edit records inline (click a cell to edit)',
1003
- recordEditingTitle: 'Record editing',
1004
1045
  },
1005
1046
  managedByBadge: {
1006
1047
  config: {
@@ -1036,15 +1077,31 @@ const en = {
1036
1077
  deleteCard: 'Delete card',
1037
1078
  deleteColumn: 'Delete column',
1038
1079
  noCards: 'No cards',
1080
+ columnCards: '{{column}} cards',
1081
+ laneCards: '{{column}} - {{lane}} cards',
1039
1082
  cardTitlePlaceholder: 'Enter card title…',
1040
1083
  uncategorized: 'Uncategorized',
1084
+ loadMore: 'Load more',
1041
1085
  columns: 'columns',
1042
1086
  requiredFieldsTitle: 'Complete required fields',
1043
1087
  requiredFieldsDescription: 'This move makes the fields below required. Fill them in to continue.',
1088
+ dnd: {
1089
+ start: 'Picked up {{card}} in {{column}}.',
1090
+ overCard: 'Moving {{card}} over {{target}} in {{column}}.',
1091
+ overColumn: 'Moving {{card}} over {{column}}.',
1092
+ overNone: 'Moving {{card}}. It is not over a column.',
1093
+ moved: 'Moved {{card}} to {{column}}.',
1094
+ dropped: 'Dropped {{card}}. It stays in {{column}}.',
1095
+ cancelled: 'Cancelled moving {{card}}. It stays in {{column}}.',
1096
+ untitledCard: 'an untitled card',
1097
+ unnamedColumn: 'an unnamed column',
1098
+ instructions: 'To move this card to another column, drag it with a pointer or by touch.',
1099
+ dragging: 'Dragging {{card}}',
1100
+ },
1044
1101
  },
1045
1102
  timeline: {
1046
1103
  bucket: {
1047
- overdue: 'Overdue',
1104
+ earlier: 'Earlier',
1048
1105
  today: 'Today',
1049
1106
  tomorrow: 'Tomorrow',
1050
1107
  thisWeek: 'This week',
@@ -1231,6 +1288,12 @@ const en = {
1231
1288
  readonlyAriaLabel: 'Read-only view',
1232
1289
  readonlyTooltip: 'System view — defined in code, read-only.',
1233
1290
  malformedFilter: 'This view’s filter is malformed, so no records are shown: the {{subject}} condition cannot be applied.',
1291
+ // objectui#11605 — an object-bound block whose node names its object in
1292
+ // neither place (no own key, no `dataSource.object`). `{{property}}` is the
1293
+ // block's object key (`objectName`), interpolated and never translated; the
1294
+ // wording was `element.number.noObject`'s with the property as a hole,
1295
+ // before objectui#11880 dropped that notice's flat `object`.
1296
+ noObject: 'No object named: set {{property}} or dataSource.object.',
1234
1297
  },
1235
1298
  detail: {
1236
1299
  back: 'Back',
@@ -1244,10 +1307,12 @@ const en = {
1244
1307
  lockedByApproval: 'Locked for approval',
1245
1308
  lockedTooltip: 'This record has a pending approval request; editing is locked',
1246
1309
  writeStrippedTitle: 'Saved — but some fields did not take effect',
1310
+ writeWarningsTitle: 'Saved — with warnings',
1247
1311
  writeStrippedReadonly: 'Read-only, so it did not take effect: {{fields}}',
1248
1312
  writeStrippedByState: "Not editable in this record's current state, so it did not take effect: {{fields}}",
1249
1313
  writeStrippedPrimaryKey: "The record's identifier cannot be changed by a save, so it did not take effect: {{fields}}",
1250
1314
  writeStrippedComputed: 'Calculated by the server from a formula, so the value sent did not take effect: {{fields}}',
1315
+ writeStrippedStoredExpression: 'Computed from the record, so the computed value was saved instead of the one sent: {{fields}}',
1251
1316
  writeStrippedUnknownReason: 'Not applied by the server: {{fields}}',
1252
1317
  approvalPendingEditable: 'In approval · editable',
1253
1318
  approvalPendingTooltip: 'This record has a pending approval request; this step still allows editing',
@@ -1276,6 +1341,14 @@ const en = {
1276
1341
  linkCopied: 'Link copied to clipboard',
1277
1342
  commentFailed: 'Your comment was not posted. Nothing was saved — please try again.',
1278
1343
  reactionFailed: 'Your reaction was not saved. Please try again.',
1344
+ // objectui#12268 — the author's Edit and Delete on their own comment in the
1345
+ // record feed: the two buttons' names, the delete confirm, and the two
1346
+ // refusals the record page raises.
1347
+ editComment: 'Edit comment',
1348
+ deleteComment: 'Delete comment',
1349
+ deleteCommentConfirm: 'Are you sure you want to delete this comment?',
1350
+ commentEditFailed: 'Your edit was not saved. The comment keeps its previous text.',
1351
+ commentDeleteFailed: 'The comment was not deleted. Please try again.',
1279
1352
  linkCopyFailed: 'Failed to copy link',
1280
1353
  cancel: 'Cancel',
1281
1354
  cancelEdit: 'Discard changes',
@@ -1400,6 +1473,7 @@ const en = {
1400
1473
  noAttachments: 'No attachments yet. Upload a file to get started.',
1401
1474
  downloadAttachment: 'Download',
1402
1475
  deleteAttachment: 'Delete attachment',
1476
+ deleteAttachmentConfirm: 'Are you sure you want to delete the attachment "{{name}}"?',
1403
1477
  attachmentDeleteDenied: 'Only the uploader or someone who can edit this record may delete this attachment.',
1404
1478
  attachmentParentAccessDenied: "You don't have access to attach files to this record.",
1405
1479
  attachmentDownloadDenied: "You don't have access to download this attachment.",
@@ -1540,6 +1614,8 @@ const en = {
1540
1614
  loading: 'Loading…',
1541
1615
  failedToLoad: 'Failed to load matrix: {{message}}',
1542
1616
  needsAcross: 'Matrix report requires at least one `groupingsAcross` field.',
1617
+ // objectui#12330 — the report's no-access state; its title is `dashboard.widgetForbiddenTitle`.
1618
+ forbiddenMessage: 'You don’t have permission to view the data behind this report.',
1543
1619
  aggregate: {
1544
1620
  count: 'Count',
1545
1621
  countDistinct: 'Distinct Count',
@@ -1570,6 +1646,8 @@ const en = {
1570
1646
  designer: {
1571
1647
  undo: 'Undo',
1572
1648
  redo: 'Redo',
1649
+ canvasMinimap: 'Canvas minimap',
1650
+ versionHistory: 'Version history',
1573
1651
  },
1574
1652
  dashboard: {
1575
1653
  addWidget: 'Add widget',
@@ -1916,11 +1994,14 @@ const en = {
1916
1994
  },
1917
1995
  },
1918
1996
  console: {
1919
- // The Studio front door's wordmark (objectui#10043). Its sibling one
1920
- // route away -- `StudioDesignSurface`'s header Home button -- walks back
1921
- // to the same place, so both read as the same affordance.
1997
+ // The fixed crumb `AppHeader`'s `studio` variant draws on the Studio front
1998
+ // door (objectui#11863), as `organizations.title` is the `orgs` variant's.
1999
+ // A product name, which every pack writes as is.
1922
2000
  studio: {
1923
- backToHome: 'Back to home',
2001
+ title: 'Studio',
2002
+ // What a principal without `studio.access` reads at the Studio URL they
2003
+ // opened (objectui#12035), in place of the silent redirect home.
2004
+ accessRequired: 'You need Studio access to open Studio.',
1924
2005
  },
1925
2006
  saveAdvisoryTitle: 'Saved — the authoring check raised {{count}} advisory finding(s)',
1926
2007
  saveAdvisoryTitle_one: 'Saved — the authoring check raised {{count}} advisory finding',
@@ -1935,12 +2016,10 @@ const en = {
1935
2016
  savedViewsRefused: 'The server refused this request, so this list is empty because it could not be read — not because this object has no saved views. Sign in again, or ask an administrator for access.',
1936
2017
  savedViewsUnreadable: 'This list is empty because it could not be read, not because this object has no saved views. Try again, and report this if it keeps happening.',
1937
2018
  title: 'ObjectOS',
1938
- initializing: 'Initializing application…',
2019
+ initializing: 'Opening your console…',
2020
+ skipToContent: 'Skip to content',
1939
2021
  search: 'Search…',
1940
2022
  breadcrumb: {
1941
- dashboards: 'Dashboards',
1942
- pages: 'Pages',
1943
- reports: 'Reports',
1944
2023
  system: 'System',
1945
2024
  // The Setup system page segment after `System` (objectui#10900).
1946
2025
  marketplace: 'Marketplace',
@@ -1955,15 +2034,21 @@ const en = {
1955
2034
  nav: {
1956
2035
  pinItem: 'Pin {{name}}',
1957
2036
  unpinItem: 'Unpin {{name}}',
1958
- dragToReorder: 'Drag to reorder',
1959
2037
  favorites: 'Favorites',
1960
2038
  launcherLabel: 'App launcher',
1961
2039
  menuLabel: 'App navigation',
1962
2040
  menuEmpty: 'This app has no navigation entries you can open.',
2041
+ // objectui#12427 — the ⋯ menu a sidebar entry shows on hover (`SidebarItemMenu`).
2042
+ itemMenu: 'More actions for {{name}}',
2043
+ openInNewTab: 'Open in new tab',
2044
+ copyLink: 'Copy link',
2045
+ linkCopied: 'Link copied to clipboard',
2046
+ linkCopyFailed: 'Failed to copy link',
2047
+ design: 'Design',
1963
2048
  },
1964
2049
  settingsHub: {
1965
2050
  title: 'Settings',
1966
- subtitle: 'Configure your workspace, integrations, and feature flags.',
2051
+ subtitle: 'Configure your system, integrations, and feature flags.',
1967
2052
  loadError: 'Failed to load settings',
1968
2053
  empty: 'No settings registered. Plugins can register settings manifests via the SettingsService.',
1969
2054
  settingsCount: '{{n}} settings',
@@ -1971,7 +2056,7 @@ const en = {
1971
2056
  // Section headers, keyed by the manifest `category` value. Unknown
1972
2057
  // (plugin-authored) categories fall back to the literal category string.
1973
2058
  categories: {
1974
- Workspace: 'Workspace',
2059
+ Workspace: 'General',
1975
2060
  Communication: 'Communication',
1976
2061
  Security: 'Security',
1977
2062
  Infrastructure: 'Infrastructure',
@@ -2016,6 +2101,13 @@ const en = {
2016
2101
  unsavedCount: '{{count}} unsaved changes',
2017
2102
  unsavedCount_one: '{{count}} unsaved change',
2018
2103
  unsavedCount_other: '{{count}} unsaved changes',
2104
+ // The toast of a save the server refused field by field (objectui#13146).
2105
+ // `{{settings}}` is the refused settings' labels, as their rows draw them,
2106
+ // joined with `validation.formInvalidJoiner`; each row shows its own
2107
+ // reason, so the toast names the settings and gives no reason.
2108
+ fieldErrorsToast: '{{count}} settings need attention: {{settings}}',
2109
+ fieldErrorsToast_one: '{{count}} setting needs attention: {{settings}}',
2110
+ fieldErrorsToast_other: '{{count}} settings need attention: {{settings}}',
2019
2111
  // The fail-closed crypto refusal (objectstack#8396). objectui#4579 added
2020
2112
  // these as English literals on purpose — routing one string through i18n
2021
2113
  // would have left a single translated string among a dozen hardcoded
@@ -2027,13 +2119,38 @@ const en = {
2027
2119
  cryptoRefusalNoSubject: 'The declared-encrypted value was refused, so nothing was written.',
2028
2120
  cryptoRefusalToast: 'Cannot encrypt secrets: {{subject}}',
2029
2121
  cryptoRefusalToastNoSubject: 'Cannot encrypt secrets',
2122
+ // The source badge beside a settings row's label (objectui#12694): the
2123
+ // layer a value comes from. `{{source}}` is that layer's label, which the
2124
+ // server translates under `settingsCommon.sourceLabels`. One sentence per
2125
+ // badge, so a pack puts the layer where its own grammar wants it.
2126
+ sourceBadgeInherited: 'Inherited from {{source}}',
2127
+ sourceBadgeOverrides: 'Overrides {{source}}',
2128
+ // The action beside an `Overrides` badge (objectui#13145): it clears this
2129
+ // layer's value in the draft, and Save sends it as `null` (unset), so the
2130
+ // row falls back to the value the layer above carries.
2131
+ resetToDefault: 'Reset to default',
2132
+ // The chips on a settings row's header (objectui#12821): the env-lock
2133
+ // chip and the title it shows when the server sends no reason, and the
2134
+ // `Deprecated` chip, with `{{replacedBy}}` the key that replaces it.
2135
+ // `unsupportedSpecifierType` is the row drawn for a specifier type the
2136
+ // page has no control for, `{{type}}` that type.
2137
+ envLockBadge: 'Locked by env',
2138
+ envLockBadgeTitle: 'Pinned by environment variable — cannot be edited from the UI.',
2139
+ deprecatedBadge: 'Deprecated',
2140
+ deprecatedBadgeReplacedBy: 'Deprecated → {{replacedBy}}',
2141
+ unsupportedSpecifierType: 'Unsupported specifier type: {{type}}',
2142
+ },
2143
+ // The one-time workspace-timezone prompt (objectui#11758): asked of an
2144
+ // administrator while `localization.timezone` is still the manifest default.
2145
+ // `{{current}}` is that default, `{{zone}}` the zone the admin confirmed.
2146
+ workspaceTimezonePrompt: {
2147
+ title: 'Set the system timezone',
2148
+ description: 'This system still uses the platform default timezone, {{current}}. The system timezone decides what "today" means in formulas, how reports group dates and how dates and times are shown, for everyone in the system. Your browser timezone is filled in below.',
2149
+ laterHint: 'You can change it at any time on the Settings page.',
2150
+ decline: 'Keep the default',
2151
+ confirm: 'Set timezone',
2152
+ saved: 'System timezone set to {{zone}}',
2030
2153
  },
2031
- loadingSteps: {
2032
- connecting: 'Connecting to data source',
2033
- loadingConfig: 'Loading configuration',
2034
- preparingWorkspace: 'Preparing workspace',
2035
- },
2036
- loadingHint: 'Setting up a new environment can take a few moments.',
2037
2154
  error: {
2038
2155
  connectionFailed: 'Cannot connect to server',
2039
2156
  serverUnreachable: 'The server at {{url}} is unreachable.',
@@ -2059,21 +2176,20 @@ const en = {
2059
2176
  groups: {
2060
2177
  general: 'General',
2061
2178
  navigation: 'Navigation',
2062
- dataViews: 'Data Views',
2063
2179
  aiChat: 'AI assistant',
2064
- preferences: 'Preferences',
2065
2180
  },
2066
2181
  openCommandPalette: 'Open command palette',
2067
2182
  showShortcuts: 'Show keyboard shortcuts',
2068
2183
  closeDialog: 'Close dialog / panel',
2069
2184
  toggleSidebar: 'Toggle sidebar',
2070
- focusSearch: 'Focus search',
2071
- createRecord: 'Create new record',
2072
- refreshData: 'Refresh data',
2073
- editRecord: 'Edit selected record',
2074
2185
  newChat: 'New chat',
2075
2186
  toggleChatsList: 'Toggle conversations list',
2076
- toggleDarkMode: 'Toggle dark mode',
2187
+ goHome: 'Back to home',
2188
+ },
2189
+ reportIndex: {
2190
+ title: 'Reports',
2191
+ emptyTitle: 'No reports',
2192
+ emptyDescription: 'This app has no reports you can open.',
2077
2193
  },
2078
2194
  commandPalette: {
2079
2195
  title: 'Command palette',
@@ -2083,6 +2199,8 @@ const en = {
2083
2199
  records: 'Records',
2084
2200
  recentRecords: 'Recently viewed',
2085
2201
  objects: 'Objects',
2202
+ packages: 'Packages',
2203
+ flows: 'Flows',
2086
2204
  dashboards: 'Dashboards',
2087
2205
  pages: 'Pages',
2088
2206
  reports: 'Reports',
@@ -2106,8 +2224,11 @@ const en = {
2106
2224
  },
2107
2225
  usage: {
2108
2226
  title: 'AI usage',
2109
- meterBuild: 'Build',
2110
- meterAsk: 'Ask',
2227
+ // objectui#11658 — the popover's ONE figure: the share of the single
2228
+ // AI pool already used (a formatted percentage, never a token count).
2229
+ // It replaced the build / data-Q&A split, which could not attribute a
2230
+ // single-composer turn honestly.
2231
+ poolUsed: '{{percent}} used',
2111
2232
  statusOk: 'Plenty left',
2112
2233
  statusLow: 'Running low',
2113
2234
  statusFull: 'Limit reached',
@@ -2127,10 +2248,6 @@ const en = {
2127
2248
  ctaUpgrade: 'Upgrade to keep going',
2128
2249
  ctaTopUp: 'Add credits to continue',
2129
2250
  ariaLabel: 'AI usage: {{status}}',
2130
- // objectui#8524 — heading over the pool's read-only split (`breakdown`:
2131
- // app-building vs data Q&A) in the popover. The rows reuse `meterBuild` /
2132
- // `meterAsk`; each is a share of the ONE pool, never a second budget.
2133
- breakdownTitle: 'Used so far',
2134
2251
  },
2135
2252
  workspaceTitle: 'AI Workspace',
2136
2253
  workspaceSubtitle: 'Ask, inspect, and resume conversations',
@@ -2194,6 +2311,8 @@ const en = {
2194
2311
  liveCanvasUnlisted: 'Live app — {{app}} (unlisted until published)',
2195
2312
  loadingAgents: 'Loading agents…',
2196
2313
  askAnything: 'Ask anything…',
2314
+ askOrChangeApp: 'Ask about your data, or ask me to change this app…',
2315
+ describeAppToBuild: 'Describe the app you want to build, or what to change…',
2197
2316
  emptyTitle: 'Start a conversation',
2198
2317
  emptyDescription: 'Ask anything — the assistant has access to your current app context.',
2199
2318
  switchAssistant: 'Switch assistant',
@@ -2213,7 +2332,7 @@ const en = {
2213
2332
  // NOT the same thing as the platform's manual automation surfaces, which
2214
2333
  // are real and stay as they are: `home.build.subtitle` (that card opens
2215
2334
  // Studio, which does author flows), `engine.studio.landing.description`,
2216
- // `dataImport.optRunAutomations`, `packagedAutomation.*` and the
2335
+ // `packagedAutomation.*` and the
2217
2336
  // marketplace `automation` category. The boundary is v1 AI AUTHORING, not
2218
2337
  // the word "automation".
2219
2338
  //
@@ -2238,12 +2357,21 @@ const en = {
2238
2357
  },
2239
2358
  clearConversation: 'Clear',
2240
2359
  sendHint: 'to send',
2360
+ newlineHint: 'for a new line',
2241
2361
  agentActivity: 'Agent activity',
2242
2362
  toolCompleted: 'Completed',
2243
2363
  toolRunning: 'Running',
2244
2364
  toolAwaitingApproval: 'Awaiting approval',
2245
2365
  toolFailed: 'Failed',
2246
2366
  toolDetailsHidden: 'Tool inputs and raw results are hidden in this view.',
2367
+ // objectui#11667 — the inline HITL deny reason (stored on the pending
2368
+ // action as `rejection_reason`, read as prose) and the ADR-0057 P4
2369
+ // "Open in Builder" handoff card. The card's Approve / Reject buttons
2370
+ // borrow `aiApprovals.approveAndExecute` / `aiApprovals.reject`.
2371
+ toolDenyReason: 'Operator rejected from chat',
2372
+ builderHandoffTitle: 'Build this in the Builder',
2373
+ builderHandoffOpen: 'Open in Builder →',
2374
+ builderHandoffSuperseded: 'A newer request is available',
2247
2375
  copy: 'Copy',
2248
2376
  copied: 'Copied',
2249
2377
  regenerate: 'Regenerate',
@@ -2260,7 +2388,7 @@ const en = {
2260
2388
  publishOk: 'Published — objects are now live.',
2261
2389
  seedWarn: 'Published, but some sample data failed to load.',
2262
2390
  openBuiltApp: 'Open app',
2263
- designBuiltApp: 'Design in Studio',
2391
+ viewBuiltAppInStudio: 'View in Studio',
2264
2392
  previewDraft: 'Preview',
2265
2393
  previewApp: 'Preview app',
2266
2394
  resizeSplit: 'Resize chat and preview',
@@ -2397,6 +2525,8 @@ const en = {
2397
2525
  collapse: 'Collapse chat',
2398
2526
  maximize: 'Open full page',
2399
2527
  open: 'Open assistant',
2528
+ // objectui#11666 — the launchers' marker while a proposed plan awaits approval.
2529
+ planAwaitingApproval: 'A proposed plan is waiting for your approval',
2400
2530
  },
2401
2531
  group: {
2402
2532
  today: 'Today',
@@ -2413,9 +2543,9 @@ const en = {
2413
2543
  // from the wire; this repo holds no copy of the line. Report only — the copy
2414
2544
  // states that nothing is limited or blocked, and must keep doing so.
2415
2545
  readRate: {
2416
- ratioTitle: 'Unusual read volume in this environment',
2546
+ ratioTitle: 'Unusual read volume in this system',
2417
2547
  ratio: 'Reads are running at {{ratio}} rows for every row written. The platform flags anything above {{threshold}}. Nothing is limited or blocked; this is a report so the read pattern can be reviewed.',
2418
- noWritesTitle: 'Reads with no writes at all in this environment',
2548
+ noWritesTitle: 'Reads with no writes at all in this system',
2419
2549
  noWrites: 'Rows are being read while none at all are being written, so the read rate has no upper bound. This is the most severe reading. The platform flags anything above {{threshold}}. Nothing is limited or blocked; this is a report so the read pattern can be reviewed.',
2420
2550
  },
2421
2551
  // objectui#10439 — the environment admin's storage-capacity banner (cloud#2135).
@@ -2479,6 +2609,7 @@ const en = {
2479
2609
  objectNotFound: 'Object Not Found',
2480
2610
  objectNotFoundDescription: 'The object "{{objectName}}" does not exist in the current configuration.',
2481
2611
  objectNotFoundHint: 'Check your app navigation settings or select a different object from the sidebar.',
2612
+ objectPackageDisabled: 'The object "{{objectName}}" belongs to a package that is disabled, so it is not being served.',
2482
2613
  filterOrNotSavable: 'This filter uses OR between conditions, which a saved view cannot store yet. It still applies to this list — remove the OR grouping to save it to the view.',
2483
2614
  filterNestedNotSavable: 'This filter uses nested condition groups, which a saved view cannot store. Flatten it to a single list of conditions to save it to the view.',
2484
2615
  systemViewReadonly: 'System view defined in code — read-only.',
@@ -2486,7 +2617,8 @@ const en = {
2486
2617
  // (rename / pin / set-as-default / configure), so the copy has to cover
2487
2618
  // any change to a built-in view rather than name one operation.
2488
2619
  cannotEditMetaView: 'This view is built in and defined in code — it cannot be changed.',
2489
- viewConfigPermissionDenied: 'View settings apply to everyone who uses this view, so changing them requires the Manage Metadata permission. Ask an administrator to make this change.',
2620
+ resetView: 'Reset view',
2621
+ resetViewTitle: 'Set this view back to its own sort, filters and column widths. Only yours change.',
2490
2622
  cannotDeleteMetaView: 'This view is built in and defined in code — it cannot be deleted.',
2491
2623
  expandToPage: 'Open as full page',
2492
2624
  allRecords: 'All Records',
@@ -2582,6 +2714,12 @@ const en = {
2582
2714
  ufAddField: '+ Add filter field…',
2583
2715
  ufShowAllRecords: 'Show "All records" tab',
2584
2716
  },
2717
+ // The runtime draft bar's Publish / Discard refusals (RuntimeDraftBar,
2718
+ // objectui#11583). The toast's description is the refusal itself.
2719
+ runtimeDraft: {
2720
+ publishFailed: 'Publish failed',
2721
+ discardFailed: 'Discard failed',
2722
+ },
2585
2723
  localeSwitcher: {
2586
2724
  label: 'Language',
2587
2725
  },
@@ -2622,10 +2760,28 @@ const en = {
2622
2760
  // it — the same convention as `{seconds}` above (objectui#10900).
2623
2761
  socialButton: 'Continue with {provider}',
2624
2762
  orText: 'or continue with email',
2763
+ // SSO sign-in (objectui#12762): the SSO button, and under SSO-only
2764
+ // ("enforced") mode the line that says how to sign in, the break-glass
2765
+ // link to the password form and the link back. Each English value is
2766
+ // `LoginForm`'s own default for that label, so an English session reads
2767
+ // the same with or without the pack.
2768
+ ssoButton: 'Sign in with SSO',
2769
+ ssoOnlyDescription: "Sign in with your organization's single sign-on",
2770
+ usePasswordText: 'Use a password instead',
2771
+ backToSsoText: 'Back to single sign-on',
2772
+ // objectui#12600 — the console login card's own header, the password
2773
+ // field's reveal toggle, and the footer's legal links.
2774
+ welcomeTitle: 'Welcome back',
2775
+ welcomeDescription: 'Sign in to continue your work',
2776
+ showPasswordText: 'Show password',
2777
+ hidePasswordText: 'Hide password',
2778
+ footer: {
2779
+ privacy: 'Privacy',
2780
+ terms: 'Terms',
2781
+ },
2625
2782
  devAdminHint: {
2626
- title: 'Development instance',
2627
- body: 'Sign in with the seeded dev admin:',
2628
- dismiss: 'Dismiss',
2783
+ title: 'Local development instance',
2784
+ signIn: 'Sign in as dev admin',
2629
2785
  },
2630
2786
  errors: {
2631
2787
  invalidCredentials: 'Invalid email or password. Please try again.',
@@ -2655,7 +2811,7 @@ const en = {
2655
2811
  orText: 'or continue with email',
2656
2812
  errors: {
2657
2813
  userExists: 'An account with this email already exists. Try signing in instead.',
2658
- selfRegistrationClosed: 'Self-registration is not open on this environment. Ask an administrator for an invitation.',
2814
+ selfRegistrationClosed: 'Self-registration is not open on this system. Ask an administrator for an invitation.',
2659
2815
  emailDomainNotAllowed: "This email's domain is not allowed to register here. Use your organization email, or ask an administrator for an invitation.",
2660
2816
  },
2661
2817
  verifyInbox: {
@@ -2728,7 +2884,7 @@ const en = {
2728
2884
  resentSuccess: 'Verification email sent!',
2729
2885
  resentDescription: 'Please check your inbox and click the verification link.',
2730
2886
  resendFailed: 'Cannot resend verification email',
2731
- resendUnavailable: 'Email delivery may not be configured for this environment. Contact support if this persists.',
2887
+ resendUnavailable: 'Email delivery may not be configured for this system. Contact support if this persists.',
2732
2888
  signInLink: 'Go to sign in',
2733
2889
  backToSignIn: 'Back to sign in',
2734
2890
  backToLogin: 'Back to login',
@@ -2778,14 +2934,14 @@ const en = {
2778
2934
  cancel: 'Cancel',
2779
2935
  },
2780
2936
  shell: {
2781
- tenantHostHint: 'You are signing in to this workspace',
2937
+ tenantHostHint: 'You are signing in to this system',
2782
2938
  },
2783
2939
  // These were previously supplied only as inline `defaultValue:` args at the
2784
2940
  // SetPasswordPage call sites, so `zh` was the only pack that could carry a
2785
2941
  // translation. Owning them here makes the page translatable everywhere.
2786
2942
  setPassword: {
2787
2943
  title: 'Set a recovery password',
2788
- description: 'You signed in via single sign-on. Set a local password so you can still sign in to this environment directly if SSO ever becomes unavailable.',
2944
+ description: 'You signed in via single sign-on. Set a local password so you can still sign in directly if SSO ever becomes unavailable.',
2789
2945
  email: 'Email',
2790
2946
  newPassword: 'New password',
2791
2947
  confirmPassword: 'Confirm password',
@@ -2807,6 +2963,7 @@ const en = {
2807
2963
  signOut: 'Sign out instead',
2808
2964
  password: {
2809
2965
  title: 'Your password has expired',
2966
+ resetTitle: 'You must change your password',
2810
2967
  fallbackMessage: 'Please set a new password to continue.',
2811
2968
  current: 'Current password',
2812
2969
  next: 'New password',
@@ -2832,6 +2989,14 @@ const en = {
2832
2989
  verifying: 'Verifying…',
2833
2990
  invalidCode: 'Invalid code. Try again.',
2834
2991
  },
2992
+ // objectui#13208 — the overlay on an IMPERSONATION session: the held
2993
+ // credential is the impersonated user's, so it offers the way out instead
2994
+ // of their forms. `{{user}}` is the impersonated user's display name.
2995
+ impersonation: {
2996
+ passwordTitle: '{{user}} must change their password',
2997
+ mfaTitle: '{{user}} must set up two-factor authentication',
2998
+ body: 'You are impersonating {{user}}, and only they can do this themselves. Stop impersonating to return to your own account.',
2999
+ },
2835
3000
  },
2836
3001
  },
2837
3002
  // The OAuth authorization-code consent screen (`/oauth/consent`). A third
@@ -2840,21 +3005,28 @@ const en = {
2840
3005
  // language — objectui#3546 slice three.
2841
3006
  oauth: {
2842
3007
  consent: {
2843
- // `{{appName}}` is the client's registered name, or `unknownApp` when the
2844
- // client metadata carries none. `{{suffix}}` is the parenthesised account
2845
- // hint the page passes (empty when no user is loaded), so it must stay
2846
- // attached to the sentence's last word.
3008
+ // `{{appName}}` is the client's registered name, or `unknownApp` while the
3009
+ // lookup is in flight or when it gives no name. `{{suffix}}` is the
3010
+ // parenthesised account hint the page passes (empty when no user is
3011
+ // loaded), so it must stay attached to the sentence's last word.
2847
3012
  title: '{{appName}} wants to access your account',
2848
3013
  request: '{{appName}} is requesting permission{{suffix}}.',
2849
3014
  unknownApp: 'an application',
3015
+ // Shown when the lookup gives no registered name, above the raw
3016
+ // `client_id` labelled `clientId` — the id is never shown as the name.
3017
+ unidentified: 'This application could not be identified.',
3018
+ clientId: 'Client ID',
2850
3019
  willAllow: 'This app will be able to:',
2851
- // Only the four scopes the page maps by name; anything else renders the
3020
+ // Only the seven scopes the page maps by name; anything else renders the
2852
3021
  // raw scope string, which is why there is no generic entry here.
2853
3022
  scope: {
2854
3023
  openid: 'Confirm your identity',
2855
3024
  profile: 'Read your basic profile (name, picture)',
2856
3025
  email: 'Read your email address',
2857
3026
  offlineAccess: 'Stay signed in (refresh access)',
3027
+ dataRead: 'Read records, within your own permissions',
3028
+ dataWrite: 'Create, change and delete records, within your own permissions',
3029
+ actionsExecute: 'Run actions on your behalf, within your own permissions',
2858
3030
  },
2859
3031
  deny: 'Deny',
2860
3032
  authorize: 'Authorize',
@@ -2897,8 +3069,8 @@ const en = {
2897
3069
  password: {
2898
3070
  changeTitle: 'Change Password',
2899
3071
  setTitle: 'Set Local Password',
2900
- changeDescription: 'Update the password you use to sign in to this environment.',
2901
- setDescription: 'You signed in via single sign-on. Set a local password to also sign in with email and password on this environment.',
3072
+ changeDescription: 'Update the password you use to sign in.',
3073
+ setDescription: 'You signed in via single sign-on. Set a local password to also sign in with email and password.',
2902
3074
  current: 'Current password',
2903
3075
  new: 'New password',
2904
3076
  password: 'Password',
@@ -2907,7 +3079,7 @@ const en = {
2907
3079
  mismatch: 'Passwords do not match',
2908
3080
  enterCurrent: 'Enter your current password',
2909
3081
  changed: 'Password changed.',
2910
- localSet: 'Local password set. You can now sign in with email and password on this environment.',
3082
+ localSet: 'Local password set. You can now sign in with email and password.',
2911
3083
  changeAction: 'Change password',
2912
3084
  setAction: 'Set password',
2913
3085
  },
@@ -2922,21 +3094,21 @@ const en = {
2922
3094
  unknown: 'An unexpected error occurred.',
2923
3095
  },
2924
3096
  workspace: {
2925
- label: 'Workspaces',
2926
- default: 'My Workspace',
2927
- switch: 'Switch workspace',
2928
- createTitle: 'Create a workspace',
2929
- createDescription: 'A workspace is a shared space for your team to collaborate.',
2930
- createButton: 'Create workspace',
2931
- nameLabel: 'Workspace name',
3097
+ label: 'Organizations',
3098
+ default: 'My Organization',
3099
+ switch: 'Switch organization',
3100
+ createTitle: 'Create an organization',
3101
+ createDescription: 'An organization is a shared space for your team to collaborate.',
3102
+ createButton: 'Create organization',
3103
+ nameLabel: 'Organization name',
2932
3104
  namePlaceholder: 'e.g., Acme Inc',
2933
3105
  slugLabel: 'URL slug',
2934
3106
  slugHint: 'Used in URLs. Only lowercase letters, numbers, and hyphens.',
2935
3107
  invite: 'Invite member',
2936
3108
  members: 'Members',
2937
- settings: 'Workspace settings',
3109
+ settings: 'Organization settings',
2938
3110
  multiOrgDisabled: 'Creating new organizations is disabled on this instance.',
2939
- createFailed: 'Failed to create workspace',
3111
+ createFailed: 'Failed to create organization',
2940
3112
  },
2941
3113
  help: {
2942
3114
  onThisPage: 'On this page',
@@ -2944,6 +3116,12 @@ const en = {
2944
3116
  allDocs: 'All documentation',
2945
3117
  keyboardShortcuts: 'Keyboard shortcuts',
2946
3118
  onlineDocs: 'Online documentation',
3119
+ loadingDocumentation: 'Loading documentation',
3120
+ about: 'About',
3121
+ aboutTitle: 'About this console',
3122
+ aboutDescription: 'The build this console was compiled from.',
3123
+ aboutBuild: 'Console build',
3124
+ aboutBuildUnknown: 'Unknown build (no version was set when this console was built)',
2947
3125
  },
2948
3126
  sidebar: {
2949
3127
  settings: 'Settings',
@@ -2958,20 +3136,19 @@ const en = {
2958
3136
  packageManagement: 'Package management',
2959
3137
  searchNavigation: 'Search navigation…',
2960
3138
  recent: 'Recent',
2961
- favorites: 'Favorites',
2962
3139
  starred: 'Starred',
2963
3140
  removeFromFavorites: 'Remove {{name}} from favorites',
3141
+ allReports: 'All reports',
2964
3142
  },
2965
3143
  topbar: {
2966
3144
  aiAssistant: 'AI Assistant',
2967
3145
  designInStudio: 'Design in Studio',
3146
+ editApp: 'Edit app',
2968
3147
  openAssistant: 'Open {{name}} assistant',
2969
3148
  offline: 'Offline',
2970
3149
  usersOnline: 'Users currently online',
2971
3150
  switchView: 'Switch view',
2972
- switchObject: 'Switch Object',
2973
3151
  connection: {
2974
- connected: 'Connected',
2975
3152
  connecting: 'Connecting…',
2976
3153
  reconnecting: 'Reconnecting…',
2977
3154
  disconnected: 'Disconnected',
@@ -2992,34 +3169,63 @@ const en = {
2992
3169
  showMoreApps: 'More',
2993
3170
  showLess: 'Show less',
2994
3171
  continueEmpty: 'Items you open will show up here.',
2995
- actionCenter: {
2996
- title: 'Needs your attention',
2997
- empty: "You're all caught up",
3172
+ // objectui#12602 — Home's "My work" section: its heading, the link to the
3173
+ // full inbox, each column's title, "view all" link and empty line.
3174
+ myWork: {
3175
+ title: "My work",
3176
+ openInbox: "Open inbox",
3177
+ viewAll: "View all",
3178
+ approvals: "Awaiting approval",
3179
+ approvalsEmpty: "Nothing waiting for your approval",
3180
+ notifications: "Notifications",
3181
+ notificationsEmpty: "No unread notifications",
2998
3182
  },
2999
3183
  greetingMorning: 'Good morning',
3000
3184
  greetingAfternoon: 'Good afternoon',
3001
3185
  greetingEvening: 'Good evening',
3002
3186
  greetingNight: 'Working late',
3003
- heroTagline: 'Pick up where you left off, or explore something new.',
3187
+ // objectui#11689 — the greeting's two joiners: the separator between the
3188
+ // greeting and the person's name (rendered only when there is a name), and
3189
+ // the closing mark. Punctuation is a locale property: zh-CN and ja write
3190
+ // full-width marks, ar its own comma.
3191
+ greetingSeparator: ', ',
3192
+ greetingEnd: '.',
3193
+ // objectui#12601 — the field in Home's top bar that opens the command palette.
3194
+ search: 'Search apps, records, pages…',
3195
+ // objectui#12601 — the line under the greeting that sums up what is
3196
+ // waiting: the approvals count, or `none` at zero.
3197
+ summary: {
3198
+ approvals: 'You have {{count}} approval(s) waiting today',
3199
+ approvals_one: 'You have {{count}} approval waiting today',
3200
+ approvals_other: 'You have {{count}} approvals waiting today',
3201
+ none: 'Nothing is waiting for you today',
3202
+ },
3203
+ // objectui#12601 — an admin's trailing tile in the apps strip; opens the marketplace.
3204
+ addApp: 'Add app',
3205
+ // objectui#12601 — the line under a Home app tile: when the user last had
3206
+ // the app open, `time` a compact relative time ("2 hr. ago"). The line is
3207
+ // 11 px in a 112 px tile and never cut, so a pack adds a verb only where
3208
+ // verb and time still fit (zh "{{time}}打开"); English does not have the
3209
+ // room for "Opened". Held to its width budget in every pack by
3210
+ // `appTileOpenedLine-12601.test.ts` (app-shell).
3211
+ appOpened: '{{time}}',
3004
3212
  build: {
3005
3213
  title: 'Build an app',
3006
- subtitle: 'Start from scratch — design objects, forms, automations and interfaces.',
3007
- noCapability: 'Building apps isn\'t available in this workspace — it requires the “Manage Metadata” permission, which your account doesn\'t have.',
3214
+ noCapability: 'Building apps isn\'t available in this system — it requires the “Manage Metadata” permission, which your account doesn\'t have.',
3008
3215
  },
3009
3216
  template: {
3010
3217
  title: 'Start with a template',
3011
- subtitle: 'Install a template app from the marketplace and customize it.',
3012
3218
  marketplaceDisabled: 'This runtime has no app marketplace configured, so there are no templates to install here.',
3013
3219
  },
3014
3220
  open: 'Open',
3015
- loading: 'Loading workspace…',
3221
+ loading: 'Loading…',
3016
3222
  welcome: 'Build your business system with AI',
3017
3223
  welcomeDescription: 'Describe your business in one sentence — AI generates the objects, screens, APIs and agent tools. Or start from scratch.',
3018
3224
  welcomeAdminDescription: 'Describe your business in one sentence — AI generates the objects, screens, APIs and agent tools. Or set things up yourself from the menu on the left.',
3019
3225
  welcomeAdminDescriptionNoBuild: 'Set up your first application from the Administration menu on the left. Once you have data, the AI assistant can help you explore it.',
3020
3226
  welcomeAdminDescriptionNoAi: 'Set up your first application from the Administration menu on the left.',
3021
3227
  noAppsTitle: 'No applications yet',
3022
- noAppsDescription: 'Your workspace is being set up — apps your admin shares with you will show up here.',
3228
+ noAppsDescription: 'The system is being set up — apps your admin shares with you will show up here.',
3023
3229
  buildWithAI: 'Build with AI',
3024
3230
  askAI: 'Ask AI',
3025
3231
  recoveryReminder: {
@@ -3028,9 +3234,15 @@ const en = {
3028
3234
  dismiss: 'Dismiss',
3029
3235
  },
3030
3236
  pendingDrafts: {
3031
- message: 'You have {{count}} unpublished change(s) — publish to make them live.',
3032
- message_one: 'You have {{count}} unpublished change — publish to make it live.',
3033
- message_other: 'You have {{count}} unpublished changes — publish to make them live.',
3237
+ // objectui#12602 — the drafts row in Home's "My work" section: the
3238
+ // count, then the first draft names joined by `nameSeparator`, in
3239
+ // their package when they share one.
3240
+ title: "{{count}} unpublished change(s)",
3241
+ title_one: "{{count}} unpublished change",
3242
+ title_other: "{{count}} unpublished changes",
3243
+ inPackage: "{{names}} waiting to publish in {{package}}",
3244
+ waiting: "{{names}} waiting to publish",
3245
+ nameSeparator: ", ",
3034
3246
  cta: 'Publish',
3035
3247
  publishing: 'Publishing…',
3036
3248
  published: 'Published! Your changes are live.',
@@ -3053,7 +3265,7 @@ const en = {
3053
3265
  manageObjects: 'Manage Objects',
3054
3266
  manageObjectsDesc: 'Configure data models',
3055
3267
  systemSettings: 'System Settings',
3056
- systemSettingsDesc: 'Configure your workspace',
3268
+ systemSettingsDesc: 'Configure your system',
3057
3269
  },
3058
3270
  recentApps: {
3059
3271
  title: 'Recently Accessed',
@@ -3062,6 +3274,8 @@ const en = {
3062
3274
  dashboard: 'Dashboard',
3063
3275
  page: 'Page',
3064
3276
  report: 'Report',
3277
+ package: 'Package',
3278
+ view: 'List view',
3065
3279
  record: 'Record',
3066
3280
  metadata: 'Metadata',
3067
3281
  },
@@ -3090,6 +3304,11 @@ const en = {
3090
3304
  manageAllApps: 'Manage All Apps',
3091
3305
  systemConsole: 'System Console',
3092
3306
  noAppsConfigured: 'No apps configured',
3307
+ allApps: 'All apps',
3308
+ editAppInStudio: 'Edit {{app}} in Studio',
3309
+ backToHome: 'Back to home',
3310
+ settings: 'Settings',
3311
+ productHome: '{{product}} home',
3093
3312
  },
3094
3313
  systemNav: {
3095
3314
  systemSettings: 'System Settings',
@@ -3108,6 +3327,7 @@ const en = {
3108
3327
  title: 'Recent Activity',
3109
3328
  filter: 'Filter',
3110
3329
  empty: 'No recent activity',
3330
+ accessDenied: "You don't have permission to view activity.",
3111
3331
  viewAll: 'View all activity',
3112
3332
  ariaLabel: 'Activity feed',
3113
3333
  typeCreate: 'Create',
@@ -3157,6 +3377,10 @@ const en = {
3157
3377
  interfacePageSourceMissing: 'This interface page references "{{name}}", which is not available.',
3158
3378
  recordNotFound: 'Record not found',
3159
3379
  recordNotFoundDescription: 'The record you are looking for does not exist or may have been deleted.',
3380
+ recordAccessDenied: 'You don’t have access to {{object}} records',
3381
+ recordAccessDeniedDescription: 'You don’t have permission to view records of this type. Contact your administrator if you think you should have access.',
3382
+ recordLoadFailed: 'Couldn’t load this record',
3383
+ recordLoadFailedDescription: 'Something went wrong while loading it. Check your connection and try again.',
3160
3384
  pageNotFound: 'Page Not Found',
3161
3385
  pageNotFoundDescription: 'The page "{{name}}" could not be found. It may have been removed or renamed.',
3162
3386
  dashboardNotFound: 'Dashboard Not Found',
@@ -3174,6 +3398,11 @@ const en = {
3174
3398
  appAccessDenied: "You don't have access to this app",
3175
3399
  appAccessDeniedDescription: 'This app exists, but your account is not authorized to open it. Ask an administrator to grant you access.',
3176
3400
  appAccessDeniedHome: 'Back to home',
3401
+ // objectui#12079 — the app root when the app serves this caller no navigation (`AppNoAccessEmptyState`).
3402
+ appNothingAvailable: 'Nothing in {{app}} is available to you yet',
3403
+ appNothingAvailableDescription: 'This app has no pages your account can open. Ask an administrator to grant you access.',
3404
+ appNothingAvailableGrantDescription: 'This app has no pages your account can open. You can grant access in Setup.',
3405
+ openSetup: 'Open Setup',
3177
3406
  createFirstApp: 'Create Your First App',
3178
3407
  systemSettings: 'System Settings',
3179
3408
  back: 'Back',
@@ -3194,6 +3423,10 @@ const en = {
3194
3423
  publishing: 'Publishing…',
3195
3424
  exit: 'Exit preview',
3196
3425
  changes: 'Changes',
3426
+ // objectui#12968 — what is pending on the surface the preview shows.
3427
+ pendingHere: 'Draft preview · {{count}} unpublished changes on this page',
3428
+ pendingHere_one: 'Draft preview · {{count}} unpublished change on this page',
3429
+ pendingHere_other: 'Draft preview · {{count}} unpublished changes on this page',
3197
3430
  // Magic-moment hint: a freshly-built draft renders empty (dashboards at 0,
3198
3431
  // lists "Nothing here yet") because seed/sample rows only load on publish.
3199
3432
  // Say so plainly so an empty preview never reads as a broken build.
@@ -3216,7 +3449,61 @@ const en = {
3216
3449
  confirmNote: 'Publishing releases all {{count}} pending drafts of this package atomically.',
3217
3450
  confirmNote_one: 'Publishing releases the {{count}} pending draft of this package atomically.',
3218
3451
  confirmNote_other: 'Publishing releases all {{count}} pending drafts of this package atomically.',
3452
+ // objectui#11591 — the package-less sheet: no package to batch, so each
3453
+ // draft publishes by itself and one that fails stays pending.
3454
+ confirmNoteSeparate: 'Publishing releases the {{count}} pending drafts one at a time: a draft that fails stays pending while the others go live.',
3455
+ confirmNoteSeparate_one: 'Publishing releases the {{count}} pending draft on its own: if it fails, it stays pending.',
3456
+ confirmNoteSeparate_other: 'Publishing releases the {{count}} pending drafts one at a time: a draft that fails stays pending while the others go live.',
3219
3457
  publishConfirm: 'Publish all',
3458
+ // objectui#12517 — the confirm posture's summary line above the list:
3459
+ // the item count, then one `{{n}} {{type}}` per type group.
3460
+ summaryItems: '{{count}} items',
3461
+ summaryItems_one: '{{count}} item',
3462
+ summaryItems_other: '{{count}} items',
3463
+ summaryType: '{{n}} {{type}}',
3464
+ // objectui#13147 — one count family per known metadata type, so the summary
3465
+ // reads "2 flows", not "2 flow". A type with no row here keeps `summaryType`.
3466
+ typeCount: {
3467
+ object: '{{count}} objects',
3468
+ object_one: '{{count}} object',
3469
+ object_other: '{{count}} objects',
3470
+ view: '{{count}} views',
3471
+ view_one: '{{count}} view',
3472
+ view_other: '{{count}} views',
3473
+ page: '{{count}} pages',
3474
+ page_one: '{{count}} page',
3475
+ page_other: '{{count}} pages',
3476
+ dashboard: '{{count}} dashboards',
3477
+ dashboard_one: '{{count}} dashboard',
3478
+ dashboard_other: '{{count}} dashboards',
3479
+ app: '{{count}} apps',
3480
+ app_one: '{{count}} app',
3481
+ app_other: '{{count}} apps',
3482
+ action: '{{count}} actions',
3483
+ action_one: '{{count}} action',
3484
+ action_other: '{{count}} actions',
3485
+ report: '{{count}} reports',
3486
+ report_one: '{{count}} report',
3487
+ report_other: '{{count}} reports',
3488
+ flow: '{{count}} flows',
3489
+ flow_one: '{{count}} flow',
3490
+ flow_other: '{{count}} flows',
3491
+ permission: '{{count}} permission sets',
3492
+ permission_one: '{{count}} permission set',
3493
+ permission_other: '{{count}} permission sets',
3494
+ agent: '{{count}} agents',
3495
+ agent_one: '{{count}} agent',
3496
+ agent_other: '{{count}} agents',
3497
+ email_template: '{{count}} email templates',
3498
+ email_template_one: '{{count}} email template',
3499
+ email_template_other: '{{count}} email templates',
3500
+ },
3501
+ // objectui#12929 — the unchecked choice under an added object field whose
3502
+ // literal default the batch publish can write into the existing records.
3503
+ backfillOption: 'Backfill default ({{count}} existing records)',
3504
+ backfillOption_one: 'Backfill default ({{count}} existing record)',
3505
+ backfillOption_other: 'Backfill default ({{count}} existing records)',
3506
+ backfillOptionNoCount: 'Backfill default',
3220
3507
  // [`7a90afdf9`] Pre-publish security-posture findings, shown next to
3221
3508
  // the confirm button so a refusal the door would issue is read BEFORE
3222
3509
  // the click rather than as a toast after the batch rolled back.
@@ -3306,9 +3593,11 @@ const en = {
3306
3593
  deleteFailed: 'Failed to delete {{label}}',
3307
3594
  noRecordId: 'No record ID provided',
3308
3595
  deleteConfirm: 'Are you sure you want to delete this record?',
3309
- resetPackageSetConfirm: 'This permission set ships with an installed package and cannot be removed. ' +
3310
- 'Deleting resets it to the shipped baseline and discards your environment customization. Continue?',
3311
- resetPackageSetSuccess: 'Permission set reset to its shipped baseline',
3596
+ deleteConfirmTitle: 'Delete {{label}} "{{name}}"?',
3597
+ bulkDeleteConfirmTitle: 'Delete {{count}} {{label}} records?',
3598
+ bulkDeleteConfirmTitle_one: 'Delete {{count}} {{label}} record?',
3599
+ bulkDeleteConfirmTitle_other: 'Delete {{count}} {{label}} records?',
3600
+ deleteConfirmButton: 'Delete',
3312
3601
  bulkDeleteSuccess: 'Deleted {{count}} {{label}} records',
3313
3602
  bulkDeleteSuccess_one: 'Deleted {{count}} {{label}} record',
3314
3603
  bulkDeleteSuccess_other: 'Deleted {{count}} {{label}} records',
@@ -3332,18 +3621,18 @@ const en = {
3332
3621
  language: 'Language',
3333
3622
  },
3334
3623
  organizations: {
3335
- mine: 'My Workspaces',
3336
- create: 'Create workspace',
3337
- title: 'Workspaces',
3338
- heading: 'Your Workspaces',
3339
- subtitle: 'Select a workspace to continue, or create a new one.',
3340
- searchPlaceholder: 'Search for a workspace',
3341
- new: 'New workspace',
3342
- current: 'Current workspace',
3624
+ mine: 'My Organizations',
3625
+ create: 'Create organization',
3626
+ title: 'Organizations',
3627
+ heading: 'Your Organizations',
3628
+ subtitle: 'Select an organization to continue, or create a new one.',
3629
+ searchPlaceholder: 'Search for an organization',
3630
+ new: 'New organization',
3631
+ current: 'Current organization',
3343
3632
  manage: 'Manage',
3344
- emptyTitle: 'No workspaces yet',
3345
- emptyDescription: 'Create your first workspace to get started.',
3346
- noMatches: 'No workspaces match your search.',
3633
+ emptyTitle: 'No organizations yet',
3634
+ emptyDescription: 'Create your first organization to get started.',
3635
+ noMatches: 'No organizations match your search.',
3347
3636
  },
3348
3637
  // Organization MANAGEMENT (packages/app-shell/src/console/organizations/**
3349
3638
  // plus the workspace switcher). Distinct from `organizations` above, which
@@ -3437,6 +3726,7 @@ const en = {
3437
3726
  // The org's URL segment. `deleteConfirmSlugLabel` asks the user to
3438
3727
  // retype it, so the two must keep naming the same thing.
3439
3728
  slugLabel: 'Slug',
3729
+ slugLockedNote: 'This organization has active environments, so its slug can’t be changed here: renaming it also moves their subdomains.',
3440
3730
  logoLabel: 'Logo',
3441
3731
  logoUpload: 'Upload',
3442
3732
  logoReplace: 'Replace',
@@ -3515,8 +3805,12 @@ const en = {
3515
3805
  // and pending approvals, then clamps at "9+". These three spell the sum
3516
3806
  // out inside the popover so the number is explainable.
3517
3807
  badgeTotal: '{{total}} total',
3518
- badgeNotifications: '{{unread}} notifications',
3519
- badgeApprovals: '{{approvals}} pending approvals',
3808
+ badgeNotifications: '{{count}} notifications',
3809
+ badgeNotifications_one: '{{count}} notification',
3810
+ badgeNotifications_other: '{{count}} notifications',
3811
+ badgeApprovals: '{{count}} pending approvals',
3812
+ badgeApprovals_one: '{{count}} pending approval',
3813
+ badgeApprovals_other: '{{count}} pending approvals',
3520
3814
  // objectui#7011 — the arrival announcement (toast / desktop notification)
3521
3815
  // and the two switches that govern it.
3522
3816
  arrivalMany: '{{count}} new messages',
@@ -3566,10 +3860,10 @@ const en = {
3566
3860
  body: 'The MCP surface is off (OS_MCP_SERVER_ENABLED=false), so there is nothing to connect. Ask your operator to re-enable it.',
3567
3861
  },
3568
3862
  url: {
3569
- title: 'This environment\'s MCP endpoint',
3863
+ title: 'This system\'s MCP endpoint',
3570
3864
  body: 'Any MCP-capable AI client connects with this URL. Identity is self-serve: the deployment is its own OAuth 2.1 authorization server, so interactive clients just open a browser login — you connect as yourself, and every call runs under your own permissions and row-level security.',
3571
3865
  downloadSkill: 'Download SKILL.md',
3572
- skillHint: 'The portable agent skill: teaches any skills-capable agent how to work with this environment.',
3866
+ skillHint: 'The portable agent skill: teaches any skills-capable agent how to work with this system.',
3573
3867
  },
3574
3868
  claude: {
3575
3869
  body: 'Settings → Connectors → Add custom connector, then paste this URL. Sign in through the browser when prompted.',
@@ -3612,16 +3906,11 @@ const en = {
3612
3906
  importAction: 'Import',
3613
3907
  dismiss: 'Dismiss',
3614
3908
  },
3615
- cloudOnboarding: {
3616
- hintCreate: 'Spin up your first environment — a private workspace with its own URL, database, and plan. Building happens inside it.',
3617
- hintReady: 'Your production environment is ready. Open it to build and run your apps — that all happens inside the environment.',
3618
- createEnvironment: 'Create your environment',
3619
- openProduction: 'Open Production',
3620
- manageEnvironments: 'Manage environments',
3621
- },
3622
- // `cloud:plan-status` — the Cloud pricing page's current-plan marker (objectui#10919).
3623
- cloudPlanStatus: {
3624
- current: 'Current plan',
3909
+ // `cloud:workspace-timezone-notice` — the Cloud welcome page's line naming the
3910
+ // timezone a workspace was seeded with at creation (objectui#11930). `{{zone}}`
3911
+ // is the seed, an IANA id printed verbatim.
3912
+ cloudWorkspaceTimezoneNotice: {
3913
+ seeded: 'The environment timezone was set to {{zone}} from your browser when the environment was created. You can change it in Settings → Localization.',
3625
3914
  },
3626
3915
  // `@object-ui/plugin-ai` — the `nl-query`, `ai-form-assist` and
3627
3916
  // `ai-recommendations` components (objectui#10232). The two count labels are
@@ -3709,8 +3998,8 @@ const en = {
3709
3998
  rowConversational: 'Build / Ask model',
3710
3999
  rowStructured: 'Structured (blueprint / seed)',
3711
4000
  rowReasoning: 'Reasoning effort',
3712
- readFailed: 'Couldn\'t read the effective AI model. This environment may not run an AI service, or you may lack the ai:read permission.',
3713
- readFailedWithStatus: 'Couldn\'t read the effective AI model (HTTP {{status}}). This environment may not run an AI service, or you may lack the ai:read permission.',
4001
+ readFailed: 'Couldn\'t read the effective AI model. This system may not run an AI service, or you may lack the ai:read permission.',
4002
+ readFailedWithStatus: 'Couldn\'t read the effective AI model (HTTP {{status}}). This system may not run an AI service, or you may lack the ai:read permission.',
3714
4003
  overridesInEffect: 'Overrides in effect: ',
3715
4004
  noOverrides: 'none — running the deployed code defaults.',
3716
4005
  adapter: 'Adapter: ',
@@ -3728,9 +4017,13 @@ const en = {
3728
4017
  // against). `humanizeToolName` looks each up as
3729
4018
  // `chatbot.tool.<tool_name>` and falls back to its English
3730
4019
  // title-caser for a custom / third-party tool, so a name
3731
- // missing here is degraded, never broken. The `en` values
3732
- // are deliberately EQUAL to what that title-caser produces:
3733
- // adding the key must not silently reword the English UI.
4020
+ // missing here is degraded, never broken. Every value, `en`
4021
+ // included, is a short sentence in the pack's language
4022
+ // saying what the step does (cloud#2927 Target 3, ruled
4023
+ // 「同意」; objectui#12724): never the tool id, and never
4024
+ // the title-caser's output for it, which is how the step
4025
+ // reads for a tool the pack has no entry for.
4026
+ // `toolLabels-locale-parity-7481` holds both.
3734
4027
  // `toolState.*` — the card-header badge + activity-chip vocabulary. ONE
3735
4028
  // set for both surfaces (they used to carry separate
3736
4029
  // tables and disagreed on casing).
@@ -3741,6 +4034,9 @@ const en = {
3741
4034
  // `building`/`built` interpolate `appFallback` when the
3742
4035
  // build has no app label, so each pack must keep BOTH
3743
4036
  // frames in the one case/gender that noun phrase is in.
4037
+ // `verifying`/`verifyStep`/`verified` are the post-apply
4038
+ // verification line and `unknownPhase` the warning for a
4039
+ // phase outside the spec's vocabulary (objectui#11988).
3744
4040
  // `plan.*` — the "N objects · N views · N dashboards" strip. Plural
3745
4041
  // FAMILIES: one slot per CLDR category the pack's language
3746
4042
  // selects (objectui#11432), plus the base key for a call
@@ -3755,42 +4051,48 @@ const en = {
3755
4051
  // pin advances, `chatbotToolLabels-locale-parity-7481` starts checking them
3756
4052
  // against the registry instead of against its own hand-held list.
3757
4053
  chatbot: {
4054
+ answer: {
4055
+ showFull: 'Show full answer',
4056
+ collapse: 'Collapse',
4057
+ expandTable: 'Expand',
4058
+ exitExpandedTable: 'Close',
4059
+ },
3758
4060
  tool: {
3759
- aggregate_data: 'Aggregate data',
3760
- get_record: 'Get record',
3761
- query_data: 'Query data',
3762
- query_records: 'Query records',
3763
- search_knowledge: 'Search knowledge',
3764
- visualize_data: 'Visualize data',
3765
- add_field: 'Add field',
3766
- apply_blueprint: 'Apply blueprint',
3767
- apply_edit: 'Apply edit',
3768
- create_metadata: 'Create metadata',
3769
- create_object: 'Create object',
3770
- create_package: 'Create package',
3771
- create_seed: 'Create seed',
3772
- delete_field: 'Delete field',
3773
- describe_metadata: 'Describe metadata',
3774
- describe_object: 'Describe object',
3775
- get_active_package: 'Get active package',
3776
- get_authoring_rules: 'Get authoring rules',
3777
- get_metadata_schema: 'Get metadata schema',
3778
- get_package: 'Get package',
3779
- list_metadata: 'List metadata',
3780
- list_objects: 'List objects',
3781
- list_packages: 'List packages',
3782
- load_tools: 'Load tools',
3783
- modify_field: 'Modify field',
3784
- open_record: 'Open record',
3785
- propose_blueprint: 'Propose blueprint',
3786
- set_active_package: 'Set active package',
3787
- suggest_builder: 'Suggest builder',
3788
- test_flow: 'Test flow',
3789
- todo_write: 'Todo write',
3790
- toggle_flow: 'Toggle flow',
3791
- update_metadata: 'Update metadata',
3792
- validate_expression: 'Validate expression',
3793
- verify_build: 'Verify build',
4061
+ aggregate_data: 'Aggregate the data',
4062
+ get_record: 'Read the record',
4063
+ query_data: 'Query the data',
4064
+ query_records: 'Look up the records',
4065
+ search_knowledge: 'Search the knowledge base',
4066
+ visualize_data: 'Chart the data',
4067
+ add_field: 'Add a field',
4068
+ apply_blueprint: 'Build the app from the plan',
4069
+ apply_edit: 'Apply the change',
4070
+ create_metadata: 'Create a metadata item',
4071
+ create_object: 'Create an object',
4072
+ create_package: 'Create a package',
4073
+ create_seed: 'Generate sample data',
4074
+ delete_field: 'Delete a field',
4075
+ describe_metadata: 'Look at the metadata',
4076
+ describe_object: 'Look at the object structure',
4077
+ get_active_package: 'Check the active package',
4078
+ get_authoring_rules: 'Read the authoring rules',
4079
+ get_metadata_schema: 'Read the metadata format',
4080
+ get_package: 'Look at the package',
4081
+ list_metadata: 'List the existing metadata',
4082
+ list_objects: 'List the existing objects',
4083
+ list_packages: 'List the existing packages',
4084
+ load_tools: 'Load more tools',
4085
+ modify_field: 'Change a field',
4086
+ open_record: 'Open the record',
4087
+ propose_blueprint: 'Draft the app plan',
4088
+ set_active_package: 'Switch to the target package',
4089
+ suggest_builder: 'Suggest building it with AI',
4090
+ test_flow: 'Try out the flow',
4091
+ todo_write: 'Note follow-up checks',
4092
+ toggle_flow: 'Turn the flow on or off',
4093
+ update_metadata: 'Update a metadata item',
4094
+ validate_expression: 'Check the expression',
4095
+ verify_build: 'Check the build',
3794
4096
  },
3795
4097
  toolState: {
3796
4098
  agentActivity: 'Agent activity',
@@ -3803,6 +4105,15 @@ const en = {
3803
4105
  denied: 'Denied',
3804
4106
  failed: 'Failed',
3805
4107
  },
4108
+ phase: {
4109
+ build: 'Build',
4110
+ design: 'Design the plan',
4111
+ stepCount: '{{count}} steps',
4112
+ stepCount_one: '{{count}} step',
4113
+ stepCount_other: '{{count}} steps',
4114
+ expand: 'Show steps',
4115
+ collapse: 'Hide steps',
4116
+ },
3806
4117
  plan: {
3807
4118
  countObjects: '{{count}} objects',
3808
4119
  countObjects_one: '{{count}} object',
@@ -3814,10 +4125,17 @@ const en = {
3814
4125
  countDashboards_one: '{{count}} dashboard',
3815
4126
  countDashboards_other: '{{count}} dashboards',
3816
4127
  countSeedData: 'sample data',
4128
+ extendTarget: 'Adding to existing app: {{app}}',
4129
+ awaitingConfirm: 'Awaiting confirmation',
4130
+ objectsAndFields: 'Objects and fields',
4131
+ views: 'Views',
4132
+ suggestedField: 'suggested',
4133
+ nameField: 'Name: {{field}}',
3817
4134
  },
3818
4135
  build: {
3819
4136
  building: 'Building {{app}}…',
3820
4137
  built: 'Built {{app}}',
4138
+ builtAndLive: 'Built and live · {{app}}',
3821
4139
  appFallback: 'your app',
3822
4140
  addingSampleData: 'adding sample data',
3823
4141
  group: {
@@ -3828,6 +4146,43 @@ const en = {
3828
4146
  seed: 'Sample data',
3829
4147
  },
3830
4148
  moreArtifacts: '+{{n}} more',
4149
+ verifying: 'Checking the change…',
4150
+ verifyStep: 'step {{n}}',
4151
+ verified: 'Checked the change',
4152
+ unknownPhase: 'Unknown build phase',
4153
+ nextStepsLead: 'Next, you can say: {{steps}}',
4154
+ nextStepQuote: '“{{step}}”',
4155
+ draftPosture: 'Later changes are saved as drafts, and you publish them in Studio.',
4156
+ checksPassed: 'Checks passed {{passed}}/{{total}}',
4157
+ },
4158
+ changes: {
4159
+ planTitle: 'Change plan · {{count}} changes',
4160
+ planTitle_one: 'Change plan · {{count}} change',
4161
+ planTitle_other: 'Change plan · {{count}} changes',
4162
+ saveDraft: 'Save as draft',
4163
+ reviewAndPublish: 'Review changes and publish',
4164
+ undo: 'Undo',
4165
+ undoWithOthers: 'Undo (and {{count}} other drafts)',
4166
+ undoWithOthers_one: 'Undo (and {{count}} other draft)',
4167
+ undoWithOthers_other: 'Undo (and {{count}} other drafts)',
4168
+ undoConfirm: 'Undo discards all {{total}} unpublished drafts of this package, including {{count}} that are not part of this change.',
4169
+ undoConfirm_one: 'Undo discards all {{total}} unpublished drafts of this package, including {{count}} that is not part of this change.',
4170
+ undoConfirm_other: 'Undo discards all {{total}} unpublished drafts of this package, including {{count}} that are not part of this change.',
4171
+ undoConfirmUnknown: 'Undo discards every unpublished draft of this package, not only this change.',
4172
+ undoConfirmAction: 'Undo all',
4173
+ undoCancel: 'Cancel',
4174
+ undoing: 'Undoing…',
4175
+ undone: 'Undone',
4176
+ undoFailed: 'Undo failed',
4177
+ kind: {
4178
+ field: 'Field',
4179
+ object: 'Object',
4180
+ view: 'View',
4181
+ dashboard: 'Dashboard',
4182
+ app: 'App',
4183
+ seed: 'Sample data',
4184
+ package: 'App package',
4185
+ },
3831
4186
  },
3832
4187
  },
3833
4188
  chatbotError: {
@@ -3843,10 +4198,18 @@ const en = {
3843
4198
  buyCredits: 'Buy a credit pack',
3844
4199
  upgradePlan: 'Upgrade plan',
3845
4200
  },
4201
+ // Plan-tier labels, keyed by the TIER rather than by the surface that draws
4202
+ // them, so every plan-locked mark reuses one string (objectui#12190). The zh
4203
+ // value follows the cloud control plane's own zh plan label.
4204
+ planTier: {
4205
+ teamAndUp: 'Team plan and up',
4206
+ },
3846
4207
  environment: {
3847
- addEnvironment: 'Add environment',
3848
4208
  setUpProduction: 'Set up your production environment',
3849
4209
  addDevelopment: 'Add development environment',
4210
+ // The plan-locked stand-in for the create action (objectui#12190).
4211
+ // `{{tier}}` is a `planTier.*` label.
4212
+ developmentLocked: 'Development environments · {{tier}}',
3850
4213
  // Plan/capacity dialog (EnvironmentEntitlementDialog). Shown on a paid
3851
4214
  // conversion path, so it must read in the user's language — cloud#959.
3852
4215
  entitlement: {
@@ -3895,7 +4258,7 @@ const en = {
3895
4258
  },
3896
4259
  unbound: {
3897
4260
  title: 'Not connected',
3898
- body: 'Connect this runtime to an ObjectStack control plane to browse your organization\'s private packages and install them here. Approval is a single click in your cloud account — no ids or credentials are typed into this page.',
4261
+ body: 'This runtime is not connected to a control plane. Connect opens your cloud account in a new window, where one click approves the link — no ids or credentials are typed into this page.',
3899
4262
  connect: 'Connect',
3900
4263
  },
3901
4264
  },
@@ -3912,21 +4275,26 @@ const en = {
3912
4275
  noMatchFilters: 'No apps match your filters.',
3913
4276
  noDescription: 'No description provided.',
3914
4277
  back: 'Back to marketplace',
3915
- installedTitle: 'Installed Apps',
3916
- installedSubtitle: 'Marketplace packages currently installed into this runtime\'s kernel. Cached manifests live in <code>.objectstack/installed-packages/</code> and survive restarts.',
3917
- installedEmpty: 'No marketplace apps installed in this runtime yet.',
3918
4278
  browseLink: 'Browse the marketplace →',
3919
- installedAdditiveNote: '<strong>Note:</strong> The kernel API is additive only — uninstall removes the on-disk manifest so the package won\'t load on next boot, but the running kernel keeps the app registered until you restart the runtime.',
3920
- installedAt: 'Installed {{when}}',
3921
- installedBy: 'by {{user}}',
3922
- installedPackageId: 'package',
3923
- cachedAs: 'Cached as <code>{{path}}</code>',
4279
+ installedAdditiveNote: 'Uninstall removes the app from the running kernel at once, together with its permission sets and their grants, and deletes the cached manifest so the package does not load at the next start. Records stored in its objects stay in the database.',
3924
4280
  versionBadge: 'v{{version}}',
3925
4281
  installedBadge: 'Installed v{{version}}',
4282
+ // objectui#11645 — an install-local entry this runtime refused to load at
4283
+ // startup (the listing's `notLoaded` marker), read on Installed Apps.
4284
+ notLoaded: {
4285
+ badge: 'Not loaded',
4286
+ protocolIncompatible: 'This runtime did not load this package: it targets protocol {{requiredRange}}, which this runtime does not support.',
4287
+ otherReason: 'This runtime did not load this package ({{code}}).',
4288
+ },
3926
4289
  load: {
3927
4290
  failed: 'Failed to load marketplace',
3928
4291
  failedHintConfigured: 'This runtime reaches the marketplace through the control plane at {{url}}. Check that it is online and reachable from here.',
3929
- failedHintSameOrigin: 'This runtime serves the marketplace catalog itself. Check that the runtime is online.',
4292
+ failedHintSameOrigin: 'The marketplace catalog is reached through this runtime. Check that the runtime is online and can reach the catalog.',
4293
+ loading: 'Loading the marketplace catalog…',
4294
+ slow: 'Still loading — the marketplace catalog is slow to answer.',
4295
+ retry: 'Retry',
4296
+ unreachable: 'The marketplace catalog could not be reached.',
4297
+ answeredError: 'The marketplace catalog answered with an error (HTTP {{status}}).',
3930
4298
  packageFailed: 'Failed to load package',
3931
4299
  notFound: 'Not found.',
3932
4300
  },
@@ -3968,6 +4336,7 @@ const en = {
3968
4336
  installToCloud: 'Install to cloud…',
3969
4337
  installed: 'Installed',
3970
4338
  installing: 'Installing…',
4339
+ updating: 'Updating…',
3971
4340
  uninstall: 'Uninstall',
3972
4341
  uninstalling: 'Uninstalling…',
3973
4342
  details: 'Details',
@@ -3985,15 +4354,50 @@ const en = {
3985
4354
  environmentPlaceholder: 'Pick an environment',
3986
4355
  includeSampleData: 'Include sample data',
3987
4356
  noEnvs: 'No environments found in your active organization.',
3988
- noPermission: 'You do not have permission to install apps in any environment. Only organization owners and admins can install — ask your workspace admin.',
4357
+ noPermission: 'You do not have permission to install apps in any environment. Only organization owners and admins can install — ask your organization admin.',
3989
4358
  signInFirst: 'You need to sign into ObjectStack Cloud first. Click "Open on cloud" below.',
3990
4359
  success: 'Installed successfully. Open the environment to see the new app.',
3991
4360
  localSuccess: 'Installed v{{version}} to this runtime. "{{name}}" should now appear in the app switcher.',
4361
+ // objectui#12098 — the install answered `hotLoaded: false`: installed, and
4362
+ // the running kernel did not register it (objectstack#22695), so nothing
4363
+ // of it is served before the next restart.
4364
+ localLoadsAtRestart: 'Installed v{{version}} to this runtime. "{{name}}" loads when the runtime next restarts; it does not appear in the app switcher until then.',
3992
4365
  localManifestConflict: '{{message}}\nTip: a local app already owns this manifest_id. Remove it from objectstack.config.ts first.',
3993
4366
  localUnauthorized: 'Sign in to this runtime first, then try again.',
3994
4367
  localMarketplaceUnavailable: 'This runtime has no OS_CLOUD_URL configured, so the marketplace catalog is unreachable.',
3995
4368
  updateTo: 'Update → v{{version}}',
3996
4369
  installedVersion: 'Installed v{{version}}',
4370
+ // objectui#12087 — an install into THIS environment, from its answer
4371
+ // until the runtime serves the package's app (MarketplacePackagePage).
4372
+ deploying: 'Deploying the app…',
4373
+ deployed: 'The app is deployed and ready.',
4374
+ openApp: 'Open {{name}}',
4375
+ deployTimeout: 'The install was recorded, but this environment is not serving the app yet. It may still be deploying — check again shortly. If it never appears, the package may not have loaded, may include no app, or its app may need a permission you do not hold.',
4376
+ checkAgain: 'Check again',
4377
+ // ADR-0131 D6 — the install modes a package's manifest permits, and
4378
+ // what an unmanaged install answers (MarketplacePackagePage).
4379
+ mode: {
4380
+ label: 'Install mode',
4381
+ managed: 'Managed',
4382
+ managedHint: 'The package stays the authority: it is registered as code, receives its upgrades, and its items are not edited here.',
4383
+ unmanaged: 'Unmanaged copy',
4384
+ unmanagedHint: 'Copied once into this runtime as its own metadata: every item is editable here, and the copy receives no upgrade.',
4385
+ required: 'Choose an install mode to install this package.',
4386
+ },
4387
+ unmanagedSuccess: 'Copied v{{version}} of "{{name}}" into this runtime as its own metadata, in the base {{base}}. The copy is editable and receives no upgrade.',
4388
+ unmanagedStrippedLocks: 'The package locked these items. The copy is editable, so their locks were not copied:',
4389
+ unmanagedIgnored: 'This runtime does not support unmanaged installs, so "{{name}}" was installed managed (registered as code) instead of copied. Upgrade the runtime, then uninstall the package and install it again as an unmanaged copy.',
4390
+ },
4391
+ // objectui#12146 — the install dialog opened as an UPDATE of the copy
4392
+ // this environment holds (MarketplacePackagePage).
4393
+ update: {
4394
+ dialogTitle: 'Update {{name}}',
4395
+ dialogDescCurrent: 'Update the copy installed in this environment ({{host}}).',
4396
+ dialogDescPicker: 'Choose the environment whose installed copy to update. You need to be signed into ObjectStack Cloud.',
4397
+ majorNotice: 'This is a major version update (v{{fromMajor}} → v{{toMajor}}), which may include breaking changes.',
4398
+ releaseNotes: 'Read the v{{version}} release notes',
4399
+ success: 'Updated to v{{version}}.',
4400
+ deployTimeout: 'The update was recorded, but this environment is not serving v{{version}} yet. It may still be deploying — check again shortly.',
3997
4401
  },
3998
4402
  // objectui#3546 — the MarketplacePage "Your organization" strip.
3999
4403
  org: {
@@ -4036,11 +4440,20 @@ const en = {
4036
4440
  dismiss: 'Dismiss',
4037
4441
  confirmedToast: '"{{set}}" is now granted to {{anchor}}.',
4038
4442
  dismissedToast: 'Suggestion for "{{set}}" dismissed.',
4443
+ guestUnsupported: 'Cannot be granted here: the Guest position takes no sets from accepted suggestions.',
4444
+ acceptedState: '"{{set}}" was accepted for all signed-in users (the Everyone position).',
4445
+ notInForceState: '"{{set}}" was accepted but is not in force yet: the Everyone position did not change on this request. The server log says why.',
4446
+ dismissedState: '"{{set}}" is not granted: the suggestion was dismissed or revoked.',
4447
+ revoke: 'Revoke',
4448
+ revoking: 'Revoking…',
4449
+ revokedToast: 'Acceptance of "{{set}}" revoked.',
4039
4450
  },
4040
4451
  uninstall: {
4041
- confirm: 'Uninstall {{manifestId}} v{{version}} from this runtime?\n\nThe cached manifest will be removed. The app will remain loaded in the running kernel until the next restart.',
4042
- successInList: 'Removed {{manifestId}}. Restart the runtime to fully unload it from the running kernel.',
4043
- successInDetail: 'Removed cached manifest for {{manifestId}}. Restart the runtime to fully unload the app from the running kernel.',
4452
+ confirm: 'Uninstall {{manifestId}} v{{version}} from this runtime?\n\nThe app will leave the running kernel at once, together with its permission sets and their grants, and its cached manifest will be removed. Records stored in its objects stay in the database.',
4453
+ successInList: 'Removed {{manifestId}}: the app has left the running kernel, with its permission sets and their grants. Records stored in its objects stay in the database.',
4454
+ successInDetail: 'Removed {{manifestId}} and its cached manifest: the app has left the running kernel, with its permission sets and their grants. Records stored in its objects stay in the database.',
4455
+ confirmNotLoaded: 'Uninstall {{manifestId}} v{{version}} from this runtime?\n\nThe cached manifest will be removed. This runtime did not load the package, so none of it is running.',
4456
+ successNotLoaded: 'Removed {{manifestId}}. It was not loaded, so no restart is needed.',
4044
4457
  },
4045
4458
  accessDenied: {
4046
4459
  title: 'App Marketplace is admin-only',
@@ -4116,6 +4529,7 @@ const en = {
4116
4529
  progressEligible_other: '{{count}} eligible approvers',
4117
4530
  progressBar: 'Decision progress',
4118
4531
  declaredActions: 'Actions',
4532
+ decisionPanelOffRequestPage: 'The approval decision panel only works on approval request pages.',
4119
4533
  attachmentChip: 'Attachment',
4120
4534
  attachmentOpenFailed: 'Could not open the attachment — please try again',
4121
4535
  approveOneTitle: 'Approve "{{title}}"?',
@@ -4181,6 +4595,9 @@ const en = {
4181
4595
  emptyPending: "You're all caught up — nothing is waiting on you.",
4182
4596
  emptyOther: 'Nothing here yet.',
4183
4597
  emptyViewAll: 'Browse all requests',
4598
+ waitingOnOthers: '{{count}} requests are waiting on other approvers',
4599
+ waitingOnOthers_one: '{{count}} request is waiting on other approvers',
4600
+ waitingOnOthers_other: '{{count}} requests are waiting on other approvers',
4184
4601
  noMatches: 'No matches for current filters.',
4185
4602
  keyboardHint: 'Keyboard: j/k move · Enter open · x select · a approve · r reject',
4186
4603
  drawerTitle: 'Approval Request',
@@ -4198,12 +4615,12 @@ const en = {
4198
4615
  overrideActionLabel: 'Override {{action}}',
4199
4616
  overrideNotice: 'You hold no approver slot on this step. Continuing uses your admin override: it finalises the step immediately, bypassing any approver who has not acted. The decision is recorded as an admin override.',
4200
4617
  overrideNoticeWho: 'You hold no approver slot on this step. Continuing uses your admin override: it finalises the step immediately and bypasses the approvers who have not acted — {{who}}. The decision is recorded as an admin override.',
4618
+ overrideReassignNotice: 'You hold no approver slot on this step. Continuing uses your admin override: the step moves to the new approver you pick, replacing any approver who has not acted. The request stays pending and waits on the new approver. The reassignment is recorded as an admin override.',
4619
+ overrideReassignNoticeWho: 'You hold no approver slot on this step. Continuing uses your admin override: the step moves to the new approver you pick, replacing the approvers who have not acted — {{who}}. The request stays pending and waits on the new approver. The reassignment is recorded as an admin override.',
4620
+ overrideRecallNotice: 'You did not submit this request. Continuing uses your admin override: the request is withdrawn, any approver who has not acted can no longer act on it, and the record is unlocked.',
4621
+ overrideRecallNoticeWho: 'You did not submit this request. Continuing uses your admin override: the request is withdrawn, the record is unlocked, and the approvers who have not acted can no longer act on it — {{who}}.',
4201
4622
  viaOverrideChip: 'Admin override',
4202
4623
  viaOverrideHint: 'The actor held no approver slot on this step — admitted by the admin-override path.',
4203
- rawData: 'Raw data (JSON)',
4204
- copy: 'Copy',
4205
- copied: 'Copied',
4206
- copyFailed: 'Copy failed',
4207
4624
  overrideActor: 'Act as another identity (admin)',
4208
4625
  actor: 'Actor',
4209
4626
  auto: 'Auto',
@@ -4310,6 +4727,10 @@ const en = {
4310
4727
  exists: 'Is set',
4311
4728
  notExists: 'Is not set',
4312
4729
  },
4730
+ emptyCheckHint: {
4731
+ text: '"{{isEmpty}}" also matches blank text; "{{isNull}}" matches only a missing value.',
4732
+ list: '"{{isEmpty}}" also matches an empty list; "{{isNull}}" matches only a missing value.',
4733
+ },
4313
4734
  },
4314
4735
  sortBuilder: {
4315
4736
  sortBy: 'Sort by',
@@ -4514,6 +4935,11 @@ const en = {
4514
4935
  setDefaultFailed: 'Failed to set default app: {{reason}}',
4515
4936
  appDeleted: '{{name}} deleted',
4516
4937
  deleteFailed: 'Failed to delete app: {{reason}}',
4938
+ // A `reset: false` answer: no customization row existed, so nothing was
4939
+ // removed. `{{reason}}` is the server's own sentence, passed through raw.
4940
+ nothingToDelete: 'Nothing to delete for {{name}}: {{reason}}',
4941
+ // `{{reason}}` above when that answer carried no sentence of its own.
4942
+ alreadyAtDefault: 'it is already at its package default',
4517
4943
  // `{{n}}` is the count that actually LANDED, not the selection size — a
4518
4944
  // bulk toggle is N independent writes with no transaction behind them.
4519
4945
  bulkEnabled: '{{n}} apps enabled',
@@ -4560,6 +4986,11 @@ const en = {
4560
4986
  toggleLabel: 'Activation for {{label}}',
4561
4987
  on: 'On',
4562
4988
  off: 'Off',
4989
+ // The Activation badge on a flow whose switch is ON but whose trigger the
4990
+ // engine has not armed on this deployment (objectui#13159): the switch
4991
+ // keeps the flag, this says the flow does not run. The same words as
4992
+ // Studio's rail for the same state (`engine.studio.auto.notRunning`).
4993
+ notRunning: 'Not running here',
4563
4994
  clone: 'Clone',
4564
4995
  cloneTitle: 'Clone packaged flow',
4565
4996
  cloneBody: 'The copy carries the whole definition and takes a new machine name and label. Edit the copy in Studio.',
@@ -4568,6 +4999,12 @@ const en = {
4568
4999
  cancel: 'Cancel',
4569
5000
  cloneConfirm: 'Create clone',
4570
5001
  cloneCreated: 'Created flow "{{name}}".',
5002
+ // The clone result's next steps (objectui#13270): switch the flow the
5003
+ // admin cloned from off through its own toggle, or open the clone where
5004
+ // it is edited. The sharing-rule clone's words for the same offer.
5005
+ cloneSwitchSourceOff: 'Switch "{{label}}" off',
5006
+ cloneSourceOff: 'The packaged flow "{{label}}" is switched off.',
5007
+ cloneOpen: 'Open the clone in Studio',
4571
5008
  emptyTitle: 'No packaged flows',
4572
5009
  emptyBody: 'No installed package ships an automation flow on this deployment. Flows you author yourself live in Studio.',
4573
5010
  loadFailed: 'Could not load packaged automation.',
@@ -4581,6 +5018,12 @@ const en = {
4581
5018
  toggleFailed: 'Could not change activation.',
4582
5019
  cloneFailedHttp: 'Could not clone this flow (HTTP {{status}}).',
4583
5020
  cloneFailed: 'Could not clone this flow.',
5021
+ // The chip an unarmed flow row's platform sentence opens from
5022
+ // (objectui#12609). ⛔ Generic on purpose: the same word on every row that
5023
+ // carries a sentence, whatever the sentence says. The sentence itself is
5024
+ // the server's and is never kept in a pack; a label naming its cause would
5025
+ // be the console classifying a field the contract says not to parse.
5026
+ reasonDetails: 'Details',
4584
5027
  // ── Packaged ACTIONS section (ADR-0126 §8 item 2, ruling 3) ────────────
4585
5028
  // ⛔ No clone key here on purpose: the action-clone half is unchartered,
4586
5029
  // and a string is the cheapest way for an unchartered surface to appear.
@@ -4596,10 +5039,104 @@ const en = {
4596
5039
  },
4597
5040
  element: {
4598
5041
  // objectui#10951 — `element:number` authored with an aggregate and no
4599
- // object (neither `object` nor `dataSource.object`). Kept terse: this pack
4600
- // is eager, and the console closure budget weighs it.
5042
+ // `dataSource.object` (objectui#11880: the flat `object` is not read). Kept
5043
+ // terse: this pack is eager, and the console closure budget weighs it.
4601
5044
  number: {
4602
- noObject: 'No object named: set object or dataSource.object.',
5045
+ noObject: 'No object named: set dataSource.object.',
5046
+ // objectui#12910 — the title of the panel this block draws when its
5047
+ // `dataSource.view` names nothing.
5048
+ sourceUnresolved: 'This metric’s data source could not be resolved',
5049
+ },
5050
+ // objectui#12910 — `element:image` with no `src`.
5051
+ image: {
5052
+ noSource: 'No image source',
5053
+ },
5054
+ // objectui#12910 — `element:record_picker`'s panel title, same case.
5055
+ recordPicker: {
5056
+ sourceUnresolved: 'This record picker’s data source could not be resolved',
5057
+ },
5058
+ // objectui#12920 — the same panel title for every other data-bound block,
5059
+ // one key per block kind. `element:number` above also titles the
5060
+ // dashboard's `object-metric`; `component` is the @object-ui/react
5061
+ // panel's own default, for a block that passes no title.
5062
+ calendar: {
5063
+ sourceUnresolved: 'This calendar’s data source could not be resolved',
5064
+ },
5065
+ chart: {
5066
+ sourceUnresolved: 'This chart’s data source could not be resolved',
5067
+ },
5068
+ pivotTable: {
5069
+ sourceUnresolved: 'This pivot table’s data source could not be resolved',
5070
+ },
5071
+ detailView: {
5072
+ sourceUnresolved: 'This detail view’s data source could not be resolved',
5073
+ },
5074
+ relatedList: {
5075
+ sourceUnresolved: 'This related list’s data source could not be resolved',
5076
+ // The panel drawn when the list's `parentDataSource` read fails.
5077
+ parentUnreadable: 'This related list’s parent record could not be read',
5078
+ },
5079
+ form: {
5080
+ sourceUnresolved: 'This form’s data source could not be resolved',
5081
+ },
5082
+ lineItems: {
5083
+ sourceUnresolved: 'This line-items panel’s data source could not be resolved',
5084
+ },
5085
+ gantt: {
5086
+ sourceUnresolved: 'This gantt chart’s data source could not be resolved',
5087
+ },
5088
+ grid: {
5089
+ sourceUnresolved: 'This grid’s data source could not be resolved',
5090
+ },
5091
+ board: {
5092
+ sourceUnresolved: 'This board’s data source could not be resolved',
5093
+ },
5094
+ listView: {
5095
+ sourceUnresolved: 'This list view’s data source could not be resolved',
5096
+ },
5097
+ map: {
5098
+ sourceUnresolved: 'This map’s data source could not be resolved',
5099
+ },
5100
+ timeline: {
5101
+ sourceUnresolved: 'This timeline’s data source could not be resolved',
5102
+ },
5103
+ component: {
5104
+ sourceUnresolved: 'This component’s data source could not be resolved',
5105
+ // The panel drawn when a block resolved no adapter at all.
5106
+ noDataSource: 'No data source resolved',
5107
+ // objectui#12197 — the two titles of a page element's API binding
5108
+ // (`dataSource: { provider: 'api', … }`): refused by the spec's schema,
5109
+ // or read and failed.
5110
+ apiRefused: 'This component’s API data source is refused',
5111
+ apiUnreadable: 'This component’s API data source could not be read',
5112
+ },
5113
+ // objectui#12910 — `element:metadata_viewer` (the ```metadata doc fence).
5114
+ // A `{{name}}`-style slot that the renderer draws as a `<code>` chip is
5115
+ // filled with a private-use mark and split on, so each language places
5116
+ // the chip. Counts read as "Label: N" so no key needs a plural family.
5117
+ metadataViewer: {
5118
+ missingKey: 'Missing {{key}} for this view.',
5119
+ loading: 'Loading {{name}}…',
5120
+ loadFailed: 'Failed to load {{name}}: {{message}}',
5121
+ notFound: '{{name}} not found.',
5122
+ stateMachine: 'State machine',
5123
+ flow: 'Flow',
5124
+ permission: 'Permission',
5125
+ noStateMachine: 'No state machine on {{object}}.',
5126
+ noStateMachineNamed: 'No state machine named “{{name}}” on {{object}}.',
5127
+ lifecycle: 'Lifecycle of {{object}}',
5128
+ field: 'field {{field}}',
5129
+ initial: 'initial',
5130
+ final: 'final',
5131
+ steps: 'Steps: {{count}}',
5132
+ noSteps: 'No steps to show.',
5133
+ untitledStep: '(step)',
5134
+ hiddenSteps: 'Technical steps hidden: {{count}} · set {{setting}} to show all',
5135
+ objectAccess: 'Object access: {{count}}',
5136
+ noPermissions: 'No object permissions declared.',
5137
+ object: 'Object',
5138
+ unknownType: 'Unknown metadata view type. Expected {{a}}, {{b}} or {{c}}.',
5139
+ unknownTypeNamed: 'Unknown metadata view type “{{type}}”. Expected {{a}}, {{b}} or {{c}}.',
4603
5140
  },
4604
5141
  },
4605
5142
  };