@company-semantics/contracts 78.1.0 → 79.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "78.1.0",
3
+ "version": "79.1.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,6 +31,7 @@ function makeItem(over: Partial<Record<string, unknown>> = {}) {
31
31
  title: "Maya Chen wants access",
32
32
  detail: "Reviewing the cross-team roadmap",
33
33
  contextLabel: "Sales.md",
34
+ provider: null,
34
35
  href: "/@acme/md/doc-1?share=1&request=req-1",
35
36
  createdAt: "2026-07-27T00:00:00.000Z",
36
37
  ...over,
@@ -139,6 +140,15 @@ describe("ActionItemSchema", () => {
139
140
  expect(parsed.unitPath).toBeNull();
140
141
  });
141
142
 
143
+ it("requires a provider — null when the item is about the product", () => {
144
+ const { provider: _omitted, ...withoutProvider } = makeItem();
145
+ expect(ActionItemSchema.safeParse(withoutProvider).success).toBe(false);
146
+ expect(
147
+ ActionItemSchema.safeParse(makeItem({ provider: "google_drive" }))
148
+ .success,
149
+ ).toBe(true);
150
+ });
151
+
142
152
  it("rejects a kind outside the vocabulary", () => {
143
153
  expect(() =>
144
154
  ActionItemSchema.parse(makeItem({ kind: "org.invite" })),
@@ -69,6 +69,16 @@ export const ActionItemSchema = z.object({
69
69
  detail: z.string().nullable(),
70
70
  /** The thing it is about, as the user names it, e.g. "Sales.md". */
71
71
  contextLabel: z.string(),
72
+ /**
73
+ * The external system this row is ABOUT, when it is about one — the open
74
+ * provider id the identity-link vocabulary uses system-wide ('bamboohr',
75
+ * 'google_drive', 'slack'). A surface shows that system's own mark.
76
+ *
77
+ * Set by the producer, because only it knows: an org's structure findings
78
+ * come from whichever HRIS it connected, which the kind cannot say.
79
+ * `null` when the row is about the product itself (a doc, a chat, billing).
80
+ */
81
+ provider: z.string().min(1).nullable(),
72
82
  /**
73
83
  * Where to go to RESOLVE it — a RELATIVE app path, e.g.
74
84
  * `/@acme/md/{docId}?share=1&request={id}`.
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '5fb16e310c8b' as const;
3
- export const SPEC_HASH_FULL = '5fb16e310c8baf449866b5b84ae859bd3933c7835ba47b6758452fe4dfcceba5' as const;
2
+ export const SPEC_HASH = 'c6eea14298b3' as const;
3
+ export const SPEC_HASH_FULL = 'c6eea14298b3f6282e821b61fac860d7c18fbb8af4b5ecf660bc09665a215d9b' as const;
@@ -4589,6 +4589,30 @@ export interface paths {
4589
4589
  patch?: never;
4590
4590
  trace?: never;
4591
4591
  };
4592
+ "/api/source-sync/settings": {
4593
+ parameters: {
4594
+ query?: never;
4595
+ header?: never;
4596
+ path?: never;
4597
+ cookie?: never;
4598
+ };
4599
+ /**
4600
+ * Read whether Source Sync is on for the org
4601
+ * @description The org switch every Source Sync route, job and sweep gates on, and who last changed it and when. Off until an admin turns it on.
4602
+ */
4603
+ get: operations["getSourceSyncSettings"];
4604
+ /**
4605
+ * Switch Source Sync on or off for the org
4606
+ * @description On lets Source Sync search the connected Drive and propose company.md updates for review. Off pauses it: nothing is read or run, and nothing already brought in is deleted. The caller is recorded as the person who changed it.
4607
+ */
4608
+ put: operations["putSourceSyncSettings"];
4609
+ post?: never;
4610
+ delete?: never;
4611
+ options?: never;
4612
+ head?: never;
4613
+ patch?: never;
4614
+ trace?: never;
4615
+ };
4592
4616
  }
4593
4617
  export type webhooks = Record<string, never>;
4594
4618
  export interface components {
@@ -7470,6 +7494,7 @@ export interface components {
7470
7494
  title: string;
7471
7495
  detail: string | null;
7472
7496
  contextLabel: string;
7497
+ provider: string | null;
7473
7498
  href: string;
7474
7499
  createdAt: string;
7475
7500
  }[];
@@ -7491,6 +7516,7 @@ export interface components {
7491
7516
  title: string;
7492
7517
  detail: string | null;
7493
7518
  contextLabel: string;
7519
+ provider: string | null;
7494
7520
  href: string;
7495
7521
  createdAt: string;
7496
7522
  };
@@ -7510,6 +7536,7 @@ export interface components {
7510
7536
  title: string;
7511
7537
  detail: string | null;
7512
7538
  contextLabel: string;
7539
+ provider: string | null;
7513
7540
  href: string | null;
7514
7541
  createdAt: string;
7515
7542
  readAt: string | null;
@@ -9293,6 +9320,14 @@ export interface components {
9293
9320
  /** @constant */
9294
9321
  confirm: true;
9295
9322
  };
9323
+ SourceSyncSettingsResponse: {
9324
+ enabled: boolean;
9325
+ changedAt: string | null;
9326
+ changedByLabel: string | null;
9327
+ };
9328
+ SourceSyncPutSettingsRequest: {
9329
+ enabled: boolean;
9330
+ };
9296
9331
  /** @description Server-enforced collaboration size limits, published so clients can pre-check. */
9297
9332
  CollabSyncLimits: {
9298
9333
  maxUpdateBytes: number;
@@ -17245,14 +17280,7 @@ export interface operations {
17245
17280
  "application/json": components["schemas"]["SourceSyncDiscoveryRunResponse"];
17246
17281
  };
17247
17282
  };
17248
- /** @description Source Sync is not enabled */
17249
- 404: {
17250
- headers: {
17251
- [name: string]: unknown;
17252
- };
17253
- content?: never;
17254
- };
17255
- /** @description The org has no active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), or a discovery run is already running (SOURCE_DISCOVERY_ALREADY_RUNNING) */
17283
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The org has no active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), or a discovery run is already running (SOURCE_DISCOVERY_ALREADY_RUNNING) */
17256
17284
  409: {
17257
17285
  headers: {
17258
17286
  [name: string]: unknown;
@@ -17279,13 +17307,20 @@ export interface operations {
17279
17307
  "application/json": components["schemas"]["SourceSyncCandidateSetResponse"];
17280
17308
  };
17281
17309
  };
17282
- /** @description Source Sync is not enabled, or the org has no draft candidate set */
17310
+ /** @description The org has no draft candidate set */
17283
17311
  404: {
17284
17312
  headers: {
17285
17313
  [name: string]: unknown;
17286
17314
  };
17287
17315
  content?: never;
17288
17316
  };
17317
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17318
+ 409: {
17319
+ headers: {
17320
+ [name: string]: unknown;
17321
+ };
17322
+ content?: never;
17323
+ };
17289
17324
  };
17290
17325
  };
17291
17326
  patchSourceCandidateItem: {
@@ -17327,14 +17362,14 @@ export interface operations {
17327
17362
  };
17328
17363
  content?: never;
17329
17364
  };
17330
- /** @description Source Sync is not enabled, or the set, item or target document is not the org’s */
17365
+ /** @description The set, item or target document is not the org’s */
17331
17366
  404: {
17332
17367
  headers: {
17333
17368
  [name: string]: unknown;
17334
17369
  };
17335
17370
  content?: never;
17336
17371
  };
17337
- /** @description The set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the item’s scope was already approved (SOURCE_SYNC_CANDIDATE_ITEM_FROZEN) */
17372
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the item’s scope was already approved (SOURCE_SYNC_CANDIDATE_ITEM_FROZEN) */
17338
17373
  409: {
17339
17374
  headers: {
17340
17375
  [name: string]: unknown;
@@ -17374,14 +17409,14 @@ export interface operations {
17374
17409
  "application/json": components["schemas"]["SourceSyncCandidateSetResponse"];
17375
17410
  };
17376
17411
  };
17377
- /** @description Source Sync is not enabled, or the set, the file or the target document is not the org’s */
17412
+ /** @description The set, the file or the target document is not the org’s */
17378
17413
  404: {
17379
17414
  headers: {
17380
17415
  [name: string]: unknown;
17381
17416
  };
17382
17417
  content?: never;
17383
17418
  };
17384
- /** @description No active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), the set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the file is already on the list for that document (SOURCE_SYNC_CANDIDATE_ALREADY_IN_SET) */
17419
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or No active Google Drive connection (SOURCE_SYNC_DRIVE_NOT_CONNECTED), the set is no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT), or the file is already on the list for that document (SOURCE_SYNC_CANDIDATE_ALREADY_IN_SET) */
17385
17420
  409: {
17386
17421
  headers: {
17387
17422
  [name: string]: unknown;
@@ -17425,14 +17460,14 @@ export interface operations {
17425
17460
  };
17426
17461
  content?: never;
17427
17462
  };
17428
- /** @description Source Sync is not enabled, or the set is not the org’s */
17463
+ /** @description The set is not the org’s */
17429
17464
  404: {
17430
17465
  headers: {
17431
17466
  [name: string]: unknown;
17432
17467
  };
17433
17468
  content?: never;
17434
17469
  };
17435
- /** @description Stale revision (SOURCE_SYNC_CANDIDATE_SET_STALE), an unresolved widening (SOURCE_SYNC_TREATMENT_UNRESOLVED), a file with no document (SOURCE_SYNC_TARGET_UNRESOLVED), a scope already approved (SOURCE_SYNC_SCOPE_ALREADY_APPROVED), or a set no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT) */
17470
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or Stale revision (SOURCE_SYNC_CANDIDATE_SET_STALE), an unresolved widening (SOURCE_SYNC_TREATMENT_UNRESOLVED), a file with no document (SOURCE_SYNC_TARGET_UNRESOLVED), a scope already approved (SOURCE_SYNC_SCOPE_ALREADY_APPROVED), or a set no longer a draft (SOURCE_SYNC_CANDIDATE_SET_NOT_DRAFT) */
17436
17471
  409: {
17437
17472
  headers: {
17438
17473
  [name: string]: unknown;
@@ -17459,8 +17494,8 @@ export interface operations {
17459
17494
  "application/json": components["schemas"]["SourceSyncCurrentSynthesisResponse"];
17460
17495
  };
17461
17496
  };
17462
- /** @description Source Sync is not enabled */
17463
- 404: {
17497
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17498
+ 409: {
17464
17499
  headers: {
17465
17500
  [name: string]: unknown;
17466
17501
  };
@@ -17488,13 +17523,20 @@ export interface operations {
17488
17523
  "application/json": components["schemas"]["SourceSyncSynthesisResponse"];
17489
17524
  };
17490
17525
  };
17491
- /** @description Source Sync is not enabled, or the batch is not the org’s */
17526
+ /** @description The batch is not the org’s */
17492
17527
  404: {
17493
17528
  headers: {
17494
17529
  [name: string]: unknown;
17495
17530
  };
17496
17531
  content?: never;
17497
17532
  };
17533
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17534
+ 409: {
17535
+ headers: {
17536
+ [name: string]: unknown;
17537
+ };
17538
+ content?: never;
17539
+ };
17498
17540
  };
17499
17541
  };
17500
17542
  applySourceSynthesis: {
@@ -17534,14 +17576,14 @@ export interface operations {
17534
17576
  };
17535
17577
  content?: never;
17536
17578
  };
17537
- /** @description Source Sync is not enabled, or the batch or an included change is not the org’s */
17579
+ /** @description The batch or an included change is not the org’s */
17538
17580
  404: {
17539
17581
  headers: {
17540
17582
  [name: string]: unknown;
17541
17583
  };
17542
17584
  content?: never;
17543
17585
  };
17544
- /** @description An included document still has an open question (SOURCE_SYNC_DOC_BLOCKED), or the review or a change is no longer open to apply (SOURCE_SYNC_SYNTHESIS_NOT_OPEN) */
17586
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or An included document still has an open question (SOURCE_SYNC_DOC_BLOCKED), or the review or a change is no longer open to apply (SOURCE_SYNC_SYNTHESIS_NOT_OPEN) */
17545
17587
  409: {
17546
17588
  headers: {
17547
17589
  [name: string]: unknown;
@@ -17568,8 +17610,8 @@ export interface operations {
17568
17610
  "application/json": components["schemas"]["SourceSyncRulesResponse"];
17569
17611
  };
17570
17612
  };
17571
- /** @description Source Sync is not enabled */
17572
- 404: {
17613
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17614
+ 409: {
17573
17615
  headers: {
17574
17616
  [name: string]: unknown;
17575
17617
  };
@@ -17606,14 +17648,7 @@ export interface operations {
17606
17648
  };
17607
17649
  content?: never;
17608
17650
  };
17609
- /** @description Source Sync is not enabled */
17610
- 404: {
17611
- headers: {
17612
- [name: string]: unknown;
17613
- };
17614
- content?: never;
17615
- };
17616
- /** @description An active rule already stands for this subject (SOURCE_SYNC_RULE_DUPLICATE); nothing changed */
17651
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or An active rule already stands for this subject (SOURCE_SYNC_RULE_DUPLICATE); nothing changed */
17617
17652
  409: {
17618
17653
  headers: {
17619
17654
  [name: string]: unknown;
@@ -17642,13 +17677,20 @@ export interface operations {
17642
17677
  "application/json": components["schemas"]["SourceSyncRule"];
17643
17678
  };
17644
17679
  };
17645
- /** @description Source Sync is not enabled, or the rule is not the org’s or is already retired */
17680
+ /** @description The rule is not the org’s or is already retired */
17646
17681
  404: {
17647
17682
  headers: {
17648
17683
  [name: string]: unknown;
17649
17684
  };
17650
17685
  content?: never;
17651
17686
  };
17687
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17688
+ 409: {
17689
+ headers: {
17690
+ [name: string]: unknown;
17691
+ };
17692
+ content?: never;
17693
+ };
17652
17694
  };
17653
17695
  };
17654
17696
  listSourceSyncFindings: {
@@ -17676,8 +17718,8 @@ export interface operations {
17676
17718
  };
17677
17719
  content?: never;
17678
17720
  };
17679
- /** @description Source Sync is not enabled */
17680
- 404: {
17721
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17722
+ 409: {
17681
17723
  headers: {
17682
17724
  [name: string]: unknown;
17683
17725
  };
@@ -17723,14 +17765,14 @@ export interface operations {
17723
17765
  };
17724
17766
  content?: never;
17725
17767
  };
17726
- /** @description Source Sync is not enabled, or the finding is not the org’s or names no source */
17768
+ /** @description The finding is not the org’s or names no source */
17727
17769
  404: {
17728
17770
  headers: {
17729
17771
  [name: string]: unknown;
17730
17772
  };
17731
17773
  content?: never;
17732
17774
  };
17733
- /** @description The finding already settled on its own (SOURCE_SYNC_FINDING_NOT_OPEN); nothing changed */
17775
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or The finding already settled on its own (SOURCE_SYNC_FINDING_NOT_OPEN); nothing changed */
17734
17776
  409: {
17735
17777
  headers: {
17736
17778
  [name: string]: unknown;
@@ -17764,8 +17806,8 @@ export interface operations {
17764
17806
  };
17765
17807
  content?: never;
17766
17808
  };
17767
- /** @description Source Sync is not enabled */
17768
- 404: {
17809
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17810
+ 409: {
17769
17811
  headers: {
17770
17812
  [name: string]: unknown;
17771
17813
  };
@@ -17811,8 +17853,8 @@ export interface operations {
17811
17853
  };
17812
17854
  content?: never;
17813
17855
  };
17814
- /** @description Source Sync is not enabled */
17815
- 404: {
17856
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17857
+ 409: {
17816
17858
  headers: {
17817
17859
  [name: string]: unknown;
17818
17860
  };
@@ -17845,8 +17887,8 @@ export interface operations {
17845
17887
  };
17846
17888
  content?: never;
17847
17889
  };
17848
- /** @description Source Sync is not enabled */
17849
- 404: {
17890
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF) */
17891
+ 409: {
17850
17892
  headers: {
17851
17893
  [name: string]: unknown;
17852
17894
  };
@@ -17890,22 +17932,80 @@ export interface operations {
17890
17932
  };
17891
17933
  content?: never;
17892
17934
  };
17893
- /** @description Source Sync is not enabled */
17894
- 404: {
17935
+ /** @description Source Sync is off for this org (SOURCE_SYNC_OFF), or Workspace-wide access is off or not set up, Drive is not connected or is not a Workspace account, reach is already domain, or Google did not accept the delegation */
17936
+ 409: {
17895
17937
  headers: {
17896
17938
  [name: string]: unknown;
17897
17939
  };
17898
17940
  content?: never;
17899
17941
  };
17900
- /** @description Workspace-wide access is off or not set up, Drive is not connected or is not a Workspace account, reach is already domain, or Google did not accept the delegation */
17901
- 409: {
17942
+ /** @description Google could not be reached to verify the delegation */
17943
+ 502: {
17902
17944
  headers: {
17903
17945
  [name: string]: unknown;
17904
17946
  };
17905
17947
  content?: never;
17906
17948
  };
17907
- /** @description Google could not be reached to verify the delegation */
17908
- 502: {
17949
+ };
17950
+ };
17951
+ getSourceSyncSettings: {
17952
+ parameters: {
17953
+ query?: never;
17954
+ header?: never;
17955
+ path?: never;
17956
+ cookie?: never;
17957
+ };
17958
+ requestBody?: never;
17959
+ responses: {
17960
+ /** @description The org’s Source Sync switch */
17961
+ 200: {
17962
+ headers: {
17963
+ [name: string]: unknown;
17964
+ };
17965
+ content: {
17966
+ "application/json": components["schemas"]["SourceSyncSettingsResponse"];
17967
+ };
17968
+ };
17969
+ /** @description The caller may not manage integrations */
17970
+ 403: {
17971
+ headers: {
17972
+ [name: string]: unknown;
17973
+ };
17974
+ content?: never;
17975
+ };
17976
+ };
17977
+ };
17978
+ putSourceSyncSettings: {
17979
+ parameters: {
17980
+ query?: never;
17981
+ header?: never;
17982
+ path?: never;
17983
+ cookie?: never;
17984
+ };
17985
+ requestBody: {
17986
+ content: {
17987
+ "application/json": components["schemas"]["SourceSyncPutSettingsRequest"];
17988
+ };
17989
+ };
17990
+ responses: {
17991
+ /** @description The switch as it now stands */
17992
+ 200: {
17993
+ headers: {
17994
+ [name: string]: unknown;
17995
+ };
17996
+ content: {
17997
+ "application/json": components["schemas"]["SourceSyncSettingsResponse"];
17998
+ };
17999
+ };
18000
+ /** @description Invalid body */
18001
+ 400: {
18002
+ headers: {
18003
+ [name: string]: unknown;
18004
+ };
18005
+ content?: never;
18006
+ };
18007
+ /** @description The caller may not manage integrations */
18008
+ 403: {
17909
18009
  headers: {
17910
18010
  [name: string]: unknown;
17911
18011
  };
@@ -191,6 +191,7 @@ export const openApiRoutes = {
191
191
  '/api/source-sync/reach/upgrade': ['POST'],
192
192
  '/api/source-sync/rules': ['GET', 'POST'],
193
193
  '/api/source-sync/rules/{ruleId}/retire': ['POST'],
194
+ '/api/source-sync/settings': ['GET', 'PUT'],
194
195
  '/api/source-sync/standing-orders': ['GET'],
195
196
  '/api/source-sync/standing-orders/{scopeKey}': ['PUT'],
196
197
  '/api/source-sync/syntheses/current': ['GET'],
@@ -22,6 +22,7 @@ function makeNotification(over: Record<string, unknown> = {}) {
22
22
  title: "Dev Patel approved your request",
23
23
  detail: null,
24
24
  contextLabel: "Q3 OKRs",
25
+ provider: null,
25
26
  href: "/@acme/md/doc-1",
26
27
  createdAt: "2026-07-30T12:00:00.000Z",
27
28
  readAt: null,
@@ -138,6 +139,30 @@ describe("UserNotificationSchema", () => {
138
139
  });
139
140
  });
140
141
 
142
+ describe("provider — the external system a row is about", () => {
143
+ it("carries a provider id when the row is about one", () => {
144
+ expect(
145
+ UserNotificationSchema.safeParse(
146
+ makeNotification({ provider: "bamboohr" }),
147
+ ).success,
148
+ ).toBe(true);
149
+ });
150
+
151
+ it("is REQUIRED — null says 'about the product', absence says nothing", () => {
152
+ const { provider: _omitted, ...withoutProvider } = makeNotification();
153
+ expect(UserNotificationSchema.safeParse(withoutProvider).success).toBe(
154
+ false,
155
+ );
156
+ });
157
+
158
+ it("rejects an empty id — a mark nobody can look up", () => {
159
+ expect(
160
+ UserNotificationSchema.safeParse(makeNotification({ provider: "" }))
161
+ .success,
162
+ ).toBe(false);
163
+ });
164
+ });
165
+
141
166
  describe("FeedItem discriminates on `row`", () => {
142
167
  it("accepts an informational row", () => {
143
168
  const parsed = FeedItemSchema.safeParse({
@@ -158,6 +183,7 @@ describe("FeedItem discriminates on `row`", () => {
158
183
  title: "Maya Chen wants access",
159
184
  detail: null,
160
185
  contextLabel: "Q3 OKRs",
186
+ provider: null,
161
187
  href: "/@acme/md/doc-1?share=1&request=req-1",
162
188
  createdAt: "2026-07-30T12:00:00.000Z",
163
189
  },
@@ -49,6 +49,16 @@ export const UserNotificationSchema = z.object({
49
49
  detail: z.string().nullable(),
50
50
  /** The thing it is about, as the user names it, e.g. "Sales.md". */
51
51
  contextLabel: z.string(),
52
+ /**
53
+ * The external system this row is ABOUT, when it is about one — the open
54
+ * provider id the identity-link vocabulary uses system-wide ('bamboohr',
55
+ * 'google_drive', 'slack'). A surface shows that system's own mark.
56
+ *
57
+ * Set by the producer, because only it knows: an org's structure findings
58
+ * come from whichever HRIS it connected, which the kind cannot say.
59
+ * `null` when the row is about the product itself (a doc, a chat, billing).
60
+ */
61
+ provider: z.string().min(1).nullable(),
52
62
  /**
53
63
  * Where to go to SEE it — a RELATIVE app path.
54
64
  *