@sema-agent/settings-schema 11.1.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/README.md +14 -1
  3. package/bin/settings-schema.mjs +5 -9
  4. package/conformance/VERSION +1 -1
  5. package/conformance/cases/c73-projects-extended-registration-reads/expected.json +150 -0
  6. package/conformance/cases/c73-projects-extended-registration-reads/input.json +42 -0
  7. package/conformance/cases/c73-projects-extended-registration-reads/meta.json +6 -0
  8. package/conformance/cases/c74-projects-over-bound-refused/expected.json +89 -0
  9. package/conformance/cases/c74-projects-over-bound-refused/input.json +29 -0
  10. package/conformance/cases/c74-projects-over-bound-refused/meta.json +5 -0
  11. package/conformance/cases/c75-projects-patch-remote-uniqueness/expected.json +89 -0
  12. package/conformance/cases/c75-projects-patch-remote-uniqueness/input.json +35 -0
  13. package/conformance/cases/c75-projects-patch-remote-uniqueness/meta.json +5 -0
  14. package/dist/api/feedback.js +2 -3
  15. package/dist/api/scopes.js +2 -1
  16. package/dist/atomic-write.d.ts +7 -1
  17. package/dist/atomic-write.js +43 -5
  18. package/dist/cli.d.ts +34 -6
  19. package/dist/cli.js +80 -130
  20. package/dist/config-d-file.d.ts +11 -0
  21. package/dist/config-d-file.js +35 -1
  22. package/dist/config-dir-io.d.ts +2 -0
  23. package/dist/config-dir-io.js +14 -0
  24. package/dist/config-dir-migration.d.ts +67 -0
  25. package/dist/config-dir-migration.js +181 -0
  26. package/dist/cross-domain.d.ts +8 -3
  27. package/dist/cross-domain.js +23 -13
  28. package/dist/file-edit.js +7 -5
  29. package/dist/file-store.js +2 -1
  30. package/dist/fleet.js +3 -4
  31. package/dist/hooks.d.ts +14 -1
  32. package/dist/hooks.js +61 -16
  33. package/dist/host-path.d.ts +17 -0
  34. package/dist/host-path.js +22 -0
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.js +1 -0
  37. package/dist/integer.js +2 -1
  38. package/dist/local-load.d.ts +1 -1
  39. package/dist/local-load.js +9 -31
  40. package/dist/migration-receipt.d.ts +3 -2
  41. package/dist/node.d.ts +2 -0
  42. package/dist/node.js +3 -0
  43. package/dist/one-time-migrations.d.ts +5 -3
  44. package/dist/one-time-migrations.js +21 -7
  45. package/dist/previous-web-admin-env.d.ts +15 -0
  46. package/dist/previous-web-admin-env.js +20 -0
  47. package/dist/quoted-issue.d.ts +41 -0
  48. package/dist/quoted-issue.js +35 -0
  49. package/dist/remote-exec.d.ts +3 -0
  50. package/dist/remote-exec.js +12 -7
  51. package/dist/retired-envs.js +13 -2
  52. package/dist/retired-form.d.ts +6 -1
  53. package/dist/retired-form.js +10 -2
  54. package/dist/rfc3339.d.ts +10 -0
  55. package/dist/rfc3339.js +12 -0
  56. package/dist/runtime-lift-targets.d.ts +7 -0
  57. package/dist/runtime-lift-targets.js +7 -0
  58. package/dist/shell-quote.d.ts +1 -0
  59. package/dist/shell-quote.js +14 -0
  60. package/dist/types.d.ts +140 -20
  61. package/dist/types.js +224 -114
  62. package/dist/web-admin-credential.d.ts +2 -2
  63. package/dist/web-admin-credential.js +5 -10
  64. package/dist/web-admin-env.d.ts +2 -1
  65. package/dist/web-admin-env.js +2 -1
  66. package/dist/web-admin-session-url.d.ts +17 -0
  67. package/dist/web-admin-session-url.js +64 -0
  68. package/package.json +1 -1
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 包内私有(不进主桶、不进 exports 表):**一只** shell 引用 —— 命令行印出来、要让人粘贴去跑的命令里,路径一律过它。
3
+ *
4
+ * POSIX 单引号规则:整串包进 `'…'`,串里的 `'` 写成 `'\''`(结束引号 + 转义的引号 + 重新开引号);单引号里除 `'` 外一切字面,所以 `$` / 反引号 / 反斜杠 / 空格 /
5
+ * 换行都不再被 shell 解释。**只有安全字符集里的串原样返回、不加引号**:ASCII 字母数字与 `_ @ + : , . / -`。其余一律引用 —— 包括行首的 `~`(否则被展开成家目录)、
6
+ * `=`(zsh 里行首 `=cmd` 展开成命令路径)、`%`、通配符与非 ASCII(保守:引用永远安全,多包一层引号不会让命令失效)。空串写成 `''`(否则命令少一个参数)。
7
+ * 目标是 POSIX shell(sh / bash / zsh);Windows cmd.exe 不认单引号,不在范围内。
8
+ */
9
+ const SHELL_SAFE = /^[A-Za-z0-9_@+:,./-]+$/;
10
+ export function shellQuote(arg) {
11
+ if (SHELL_SAFE.test(arg))
12
+ return arg;
13
+ return `'${arg.replaceAll("'", "'\\''")}'`;
14
+ }
package/dist/types.d.ts CHANGED
@@ -32,19 +32,11 @@ export declare const ENV_NAME: z.ZodString;
32
32
  * fs path — so the worker dies at exec/boot, not at config edit. A NUL is never legitimate in a command / path
33
33
  * / host / image, so reject it on every exec-bound string field (mcp stdio + the whole remoteExec contract). R20. */
34
34
  export declare const hasNul: (s: string) => boolean;
35
- /** The params of a custom issue whose sentence QUOTES values (S-1075, 11.0.0) —— plain data: the sentence's fixed parts and the
36
- * values between them, in order, so `message` is exactly {@link renderQuotedSentence} of them. A reader that has to treat the
37
- * user-written parts of a sentence differently from its fixed words (a log boundary fingerprinting each value, the sanitizer
38
- * bounding each value's length) reads them HERE instead of guessing where a value starts in the sentence. Every custom issue this
39
- * package's schemas raise with a value in its sentence carries them (`issue.params`; a few fixed sentences raised through the same
40
- * helpers carry them with no operands). */
41
- export interface QuotedIssueParams {
42
- readonly template: readonly string[];
43
- readonly operands: readonly (string | number)[];
44
- }
45
- /** The one rendering of a quoted sentence: `template[0] + show(operands[0]) + template[1] + … + template[n]`. `show` defaults to
46
- * the value as written (that is how `message` is minted); a sanitizer / log boundary passes its own. */
47
- export declare function renderQuotedSentence(p: QuotedIssueParams, show?: (operand: string | number) => string): string;
35
+ /** The params of a custom issue's sentence and their one rendering live in the package-private minting module `./quoted-issue`
36
+ * (one minting point for the whole package); re-exported here unchanged. */
37
+ export { renderQuotedSentence, type QuotedIssueParams } from "./quoted-issue.js";
38
+ /** The one host-path shape judge (a task's `cwd`, a project's `folder` / `file` entries) lives in its leaf module `./host-path`. */
39
+ export { ABSOLUTE_HOST_PATH_MAX, AbsoluteHostPath, isAbsoluteHostPath } from "./host-path.js";
48
40
  /** Does `s` contain a secret-shaped token? —— **the one scanner** (11.0.0, S-1274): the write side (this detector, behind every
49
41
  * free-text write port — NON_SECRET_URL, mcp stdio, execution coords, ssh login, worker env, extraBody, …) and the display side
50
42
  * (`redactSecrets`) read the SAME normalized forms ({@link secretScanForms} in the package-private `./secret-scan`: the raw string,
@@ -62,15 +54,16 @@ export declare function urlQueryFragmentHasSecret(u: URL): boolean;
62
54
  /** A URL handed to `fetch` that carries no credential: judged by THE URL shape judge ({@link httpUrlFlaws}, `./url-shape`) — a
63
55
  * hierarchical http(s) URL with neither userinfo nor a fragment (an empty `#` included, 11.0.0) — and with no secret-shaped value
64
56
  * in its path or query ({@link urlQueryFragmentHasSecret}). One issue per flaw, its message the judge's rule sentence (no value
65
- * echoed; a fragment's also names its migration, {@link nonSecretUrlSentence}); `params.flaw` carries the rule word.
57
+ * echoed; a fragment's also names its migration, {@link nonSecretUrlIssue}); `params` carries the sentence (`template` / `operands`,
58
+ * no operands) and `flaw`, the rule word.
66
59
  *
67
- * This is the seat of every URL in a stored DOMAIN document (models `baseUrl`, mcp `url`, `sessionMirror.engineUrl`, workers
68
- * `gitApiBaseUrl`). A URL outside the domain documents — `remote-exec.json`'s endpoints, the web-admin credential envelope's
69
- * `issuer` — uses {@link NON_SECRET_URL_NO_MIGRATION}.
60
+ * This is the seat of every URL in a STORED document the one-time migration rewrites: the domain documents (models `baseUrl`, mcp `url`,
61
+ * `sessionMirror.engineUrl`, workers `gitApiBaseUrl`) and `config.d/remote-exec.json` (k8s `apiUrl`, `s3Snapshot.endpoint`). A URL
62
+ * that is not stored data — the web-admin credential envelope's `issuer`, a wire input — uses {@link NON_SECRET_URL_NO_MIGRATION}.
70
63
  *
71
64
  * The value is kept EXACTLY as written: nothing here trims or normalizes it (zod's own `.url()` would hand back a rewritten string). */
72
65
  export declare const NON_SECRET_URL: z.ZodString;
73
- /** {@link NON_SECRET_URL}'s judge for a seat no one-time migration reaches (not a domain document): identical rules and rule
66
+ /** {@link NON_SECRET_URL}'s judge for a seat no one-time migration reaches (not stored data): identical rules and rule
74
67
  * sentences, but a fragment's refusal carries no migration signpost — pointing at a migration that cannot rewrite the value would
75
68
  * send the operator to a command that does nothing for it. */
76
69
  export declare const NON_SECRET_URL_NO_MIGRATION: z.ZodString;
@@ -580,6 +573,27 @@ export declare const LimitsConfig: z.ZodObject<{
580
573
  toolResultTtlSec: z.ZodOptional<z.ZodNumber>;
581
574
  }, z.core.$loose>;
582
575
  export type LimitsConfig = z.infer<typeof LimitsConfig>;
576
+ /** The autonomy ladder —— the closed set as a RUNTIME VALUE (same form as `REF_CHECKED_DOMAINS`): {@link AutonomyMode} (the zod enum)
577
+ * and its type are DERIVED from this table, so a consumer that needs the words at runtime (an env parser, a catalog's enum column) imports
578
+ * it instead of reaching into `GovernanceConfig.shape.autonomy.unwrap().options` or writing the four words again. */
579
+ export declare const AUTONOMY_MODES: readonly ["read-only", "ask", "plan", "auto"];
580
+ export type AutonomyMode = (typeof AUTONOMY_MODES)[number];
581
+ /** `governance.autonomy`'s enum, derived from {@link AUTONOMY_MODES}. */
582
+ export declare const AutonomyMode: z.ZodEnum<{
583
+ auto: "auto";
584
+ "read-only": "read-only";
585
+ ask: "ask";
586
+ plan: "plan";
587
+ }>;
588
+ /** A `commandPolicy[]` rule's decision —— the closed set as a RUNTIME VALUE; {@link CommandDecision} and its type are DERIVED from it. */
589
+ export declare const COMMAND_DECISIONS: readonly ["allow", "ask", "deny"];
590
+ export type CommandDecision = (typeof COMMAND_DECISIONS)[number];
591
+ /** `commandPolicy[].decision`'s enum, derived from {@link COMMAND_DECISIONS}. */
592
+ export declare const CommandDecision: z.ZodEnum<{
593
+ ask: "ask";
594
+ allow: "allow";
595
+ deny: "deny";
596
+ }>;
583
597
  export declare const GovernanceConfig: z.ZodObject<{
584
598
  autonomy: z.ZodOptional<z.ZodEnum<{
585
599
  auto: "auto";
@@ -1094,6 +1108,35 @@ export type ExecutionPolicy = z.infer<typeof ExecutionPolicy>;
1094
1108
  * flags:本常量刻意**不带** `i`,因为它是登记簿 Record 的**键**,大小写不同的同一个 UUID 会变成两条登记行
1095
1109
  * (同一 project 双注册);引擎侧是识别语义(读 marker / 找回身份),放宽合理。 */
1096
1110
  export declare const PROJECT_ID_REGEX: RegExp;
1111
+ /** The bounds of a project registration's free-form fields —— the ONE source of these numbers: the schema below reads them, and so do
1112
+ * the server's project routes and the admin / client forms (they import this, never copy a number). The path bound of `folder` / `file`
1113
+ * entries is the host-path judge's own ({@link ABSOLUTE_HOST_PATH_MAX}). */
1114
+ export declare const PROJECT_LIMITS: {
1115
+ readonly displayNameMax: 200;
1116
+ readonly goalMax: 2000;
1117
+ readonly contextItemsMax: 64;
1118
+ readonly noteMax: 4000;
1119
+ };
1120
+ /** A project context item's kind —— the closed set as a RUNTIME VALUE: `folder` / `file` = a host path (judged by the same
1121
+ * {@link isAbsoluteHostPath} as a task's `cwd`), `note` = free text. */
1122
+ export declare const PROJECT_CONTEXT_ITEM_KINDS: readonly ["folder", "file", "note"];
1123
+ export type ProjectContextItemKind = (typeof PROJECT_CONTEXT_ITEM_KINDS)[number];
1124
+ /** A project's icon: a token (lowercase letter first, then lowercase letters / digits / `-`, at most 64). Absent = the default icon. */
1125
+ export declare const PROJECT_ICON_REGEX: RegExp;
1126
+ /** A project's colour: `#` + six lowercase hex digits. Absent = the default colour. */
1127
+ export declare const PROJECT_COLOR_REGEX: RegExp;
1128
+ /** One context item of a project. */
1129
+ export declare const ProjectContextItem: z.ZodDiscriminatedUnion<[z.ZodObject<{
1130
+ kind: z.ZodLiteral<"folder">;
1131
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1132
+ }, z.core.$strip>, z.ZodObject<{
1133
+ kind: z.ZodLiteral<"file">;
1134
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1135
+ }, z.core.$strip>, z.ZodObject<{
1136
+ kind: z.ZodLiteral<"note">;
1137
+ value: z.ZodString;
1138
+ }, z.core.$strip>], "kind">;
1139
+ export type ProjectContextItem = z.infer<typeof ProjectContextItem>;
1097
1140
  export declare const ProjectRegistration: z.ZodObject<{
1098
1141
  displayName: z.ZodString;
1099
1142
  gitRemotes: z.ZodPrefault<z.ZodArray<z.ZodString>>;
@@ -1101,6 +1144,20 @@ export declare const ProjectRegistration: z.ZodObject<{
1101
1144
  registeredBy: z.ZodString;
1102
1145
  registeredAt: z.ZodString;
1103
1146
  notes: z.ZodOptional<z.ZodString>;
1147
+ goal: z.ZodOptional<z.ZodString>;
1148
+ contextItems: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1149
+ kind: z.ZodLiteral<"folder">;
1150
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1151
+ }, z.core.$strip>, z.ZodObject<{
1152
+ kind: z.ZodLiteral<"file">;
1153
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1154
+ }, z.core.$strip>, z.ZodObject<{
1155
+ kind: z.ZodLiteral<"note">;
1156
+ value: z.ZodString;
1157
+ }, z.core.$strip>], "kind">>>;
1158
+ archivedAt: z.ZodOptional<z.ZodISODateTime>;
1159
+ icon: z.ZodOptional<z.ZodString>;
1160
+ color: z.ZodOptional<z.ZodString>;
1104
1161
  }, z.core.$strip>;
1105
1162
  export type ProjectRegistration = z.infer<typeof ProjectRegistration>;
1106
1163
  export declare const ProjectsConfig: z.ZodObject<{
@@ -1111,9 +1168,57 @@ export declare const ProjectsConfig: z.ZodObject<{
1111
1168
  registeredBy: z.ZodString;
1112
1169
  registeredAt: z.ZodString;
1113
1170
  notes: z.ZodOptional<z.ZodString>;
1171
+ goal: z.ZodOptional<z.ZodString>;
1172
+ contextItems: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1173
+ kind: z.ZodLiteral<"folder">;
1174
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1175
+ }, z.core.$strip>, z.ZodObject<{
1176
+ kind: z.ZodLiteral<"file">;
1177
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1178
+ }, z.core.$strip>, z.ZodObject<{
1179
+ kind: z.ZodLiteral<"note">;
1180
+ value: z.ZodString;
1181
+ }, z.core.$strip>], "kind">>>;
1182
+ archivedAt: z.ZodOptional<z.ZodISODateTime>;
1183
+ icon: z.ZodOptional<z.ZodString>;
1184
+ color: z.ZodOptional<z.ZodString>;
1114
1185
  }, z.core.$strip>>>;
1115
1186
  }, z.core.$strip>;
1116
1187
  export type ProjectsConfig = z.infer<typeof ProjectsConfig>;
1188
+ /** The PATCH form of one registration: every key a PATCH may change, all optional; `registeredBy` / `registeredAt` (and any key
1189
+ * the registration does not have) are refused (`.strict()`). An optional key given `null` is cleared (merge-patch: `archivedAt: null`
1190
+ * un-archives). Each field is the registration's own schema — one bound, one shape. */
1191
+ export declare const ProjectRegistrationPatch: z.ZodObject<{
1192
+ displayName: z.ZodOptional<z.ZodString>;
1193
+ gitRemotes: z.ZodOptional<z.ZodArray<z.ZodString>>;
1194
+ defaultScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
1195
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1196
+ goal: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1197
+ contextItems: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1198
+ kind: z.ZodLiteral<"folder">;
1199
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1200
+ }, z.core.$strip>, z.ZodObject<{
1201
+ kind: z.ZodLiteral<"file">;
1202
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
1203
+ }, z.core.$strip>, z.ZodObject<{
1204
+ kind: z.ZodLiteral<"note">;
1205
+ value: z.ZodString;
1206
+ }, z.core.$strip>], "kind">>>>;
1207
+ archivedAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
1208
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1209
+ color: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1210
+ }, z.core.$strict>;
1211
+ export type ProjectRegistrationPatch = z.infer<typeof ProjectRegistrationPatch>;
1212
+ /**
1213
+ * Apply a PATCH to one registration and judge the whole document with **the same** {@link ProjectsConfig} (the same remote-uniqueness rule a
1214
+ * full write meets — a PATCH has no rule of its own). The patch is judged here by {@link ProjectRegistrationPatch} first — whatever the caller
1215
+ * did before (a request body handed over as is cannot rewrite `registeredBy` / `registeredAt` or carry an unknown key) — and only its parsed
1216
+ * keys are merged. The patched project is judged LAST, so a remote another project already holds is refused on the patched project and the
1217
+ * sentence names the holder, whatever the document's key order; a successful result keeps the document's key order. Every issue path is a
1218
+ * document coordinate (`["projects", <projectId>, …]`), the patch's own included. `projectId` must be registered (the caller answers "no such
1219
+ * project" first) —— otherwise this throws.
1220
+ */
1221
+ export declare function applyProjectPatch(doc: ProjectsConfig, projectId: string, patch: unknown): ReturnType<typeof ProjectsConfig.safeParse>;
1117
1222
  export declare const CollabTopology: z.ZodEnum<{
1118
1223
  star: "star";
1119
1224
  ring: "ring";
@@ -1874,12 +1979,14 @@ export declare const PluginsConfig: z.ZodObject<{
1874
1979
  export type PluginsConfig = z.infer<typeof PluginsConfig>;
1875
1980
  /** 提示声明的槽位闭集(core `PromptTextDeclaration.slot` 同形):identity = 角色卡、scenario = 场景说明、behavior = 行为守则。
1876
1981
  * declaration 轴与 catalog 轴({@link PromptArtifactSection})共用这一只。 */
1982
+ export declare const PROMPT_SLOTS: readonly ["identity", "scenario", "behavior"];
1983
+ export type PromptSlot = (typeof PROMPT_SLOTS)[number];
1984
+ /** The slot enum, DERIVED from {@link PROMPT_SLOTS} (the runtime member table —— same form as `REF_CHECKED_DOMAINS`). */
1877
1985
  export declare const PromptSlot: z.ZodEnum<{
1878
1986
  scenario: "scenario";
1879
1987
  identity: "identity";
1880
1988
  behavior: "behavior";
1881
1989
  }>;
1882
- export type PromptSlot = z.infer<typeof PromptSlot>;
1883
1990
  /** core `PromptTextDeclaration` 的契约层同形(core prompts/default.d.ts 逐字:id/slot 闭集/text)。
1884
1991
  * slot ↔ 三卡:identity=角色卡、scenario=场景说明、behavior=行为守则([1051]①)。 */
1885
1992
  export declare const PromptTextDeclaration: z.ZodObject<{
@@ -2781,6 +2888,20 @@ export declare const DOMAIN_SCHEMAS: {
2781
2888
  registeredBy: z.ZodString;
2782
2889
  registeredAt: z.ZodString;
2783
2890
  notes: z.ZodOptional<z.ZodString>;
2891
+ goal: z.ZodOptional<z.ZodString>;
2892
+ contextItems: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
2893
+ kind: z.ZodLiteral<"folder">;
2894
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
2895
+ }, z.core.$strip>, z.ZodObject<{
2896
+ kind: z.ZodLiteral<"file">;
2897
+ value: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
2898
+ }, z.core.$strip>, z.ZodObject<{
2899
+ kind: z.ZodLiteral<"note">;
2900
+ value: z.ZodString;
2901
+ }, z.core.$strip>], "kind">>>;
2902
+ archivedAt: z.ZodOptional<z.ZodISODateTime>;
2903
+ icon: z.ZodOptional<z.ZodString>;
2904
+ color: z.ZodOptional<z.ZodString>;
2784
2905
  }, z.core.$strip>>>;
2785
2906
  }, z.core.$strip>;
2786
2907
  readonly prompts: z.ZodObject<{
@@ -3027,4 +3148,3 @@ export declare const DOMAINS: DomainName[];
3027
3148
  * filtering arbitrary keys (e.g. a `config.d/` directory scan that also turns up the non-domain
3028
3149
  * `remote-exec.json`) — `remote-exec` is NOT a domain (it's the exec backend; see writeRemoteExec). */
3029
3150
  export declare function isDomainName(x: unknown): x is DomainName;
3030
- export {};