@dokebi/cli 0.4.2 → 0.4.26

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 (188) hide show
  1. package/AI.md +262 -57
  2. package/README.md +35 -10
  3. package/catalog.json +2519 -257
  4. package/describe.schema.json +748 -0
  5. package/dist/api-app.d.ts +2 -0
  6. package/dist/api-app.js +35 -0
  7. package/dist/app-urls.js +3 -2
  8. package/dist/bin.js +518 -35
  9. package/dist/capability-guide.d.ts +30 -0
  10. package/dist/capability-guide.js +122 -0
  11. package/dist/catalog.d.ts +16 -2
  12. package/dist/catalog.js +19 -7
  13. package/dist/check/asset-rules.d.ts +6 -0
  14. package/dist/check/asset-rules.js +163 -0
  15. package/dist/check/browser-sources.d.ts +20 -0
  16. package/dist/check/browser-sources.js +89 -0
  17. package/dist/check/console-rules.d.ts +6 -0
  18. package/dist/check/console-rules.js +40 -0
  19. package/dist/check/error-rules.d.ts +21 -0
  20. package/dist/check/error-rules.js +212 -0
  21. package/dist/check/form-rules.d.ts +12 -0
  22. package/dist/check/form-rules.js +69 -6
  23. package/dist/check/formatter-rules.d.ts +2 -0
  24. package/dist/check/formatter-rules.js +71 -0
  25. package/dist/check/i18n-rules.d.ts +27 -0
  26. package/dist/check/i18n-rules.js +353 -0
  27. package/dist/check/index.d.ts +15 -1
  28. package/dist/check/index.js +89 -11
  29. package/dist/check/mail-rules.d.ts +4 -0
  30. package/dist/check/mail-rules.js +72 -0
  31. package/dist/check/module-rules.d.ts +13 -0
  32. package/dist/check/module-rules.js +104 -0
  33. package/dist/check/packages.d.ts +8 -0
  34. package/dist/check/packages.js +16 -0
  35. package/dist/check/pool-rules.d.ts +8 -0
  36. package/dist/check/pool-rules.js +164 -0
  37. package/dist/check/problems.d.ts +6 -1
  38. package/dist/check/problems.js +100 -2
  39. package/dist/check/project-rules.d.ts +23 -3
  40. package/dist/check/project-rules.js +265 -23
  41. package/dist/check/seal-rules.d.ts +6 -0
  42. package/dist/check/seal-rules.js +68 -0
  43. package/dist/check/security-rules.d.ts +10 -0
  44. package/dist/check/security-rules.js +450 -0
  45. package/dist/check/shared-state-rules.d.ts +2 -0
  46. package/dist/check/shared-state-rules.js +114 -0
  47. package/dist/check/source-rules.d.ts +26 -3
  48. package/dist/check/source-rules.js +249 -28
  49. package/dist/check/structure-rules.d.ts +23 -0
  50. package/dist/check/structure-rules.js +502 -0
  51. package/dist/check/timer-rules.d.ts +7 -0
  52. package/dist/check/timer-rules.js +543 -0
  53. package/dist/check/typescript.d.ts +35 -5
  54. package/dist/check/typescript.js +163 -17
  55. package/dist/check/vite-rules.d.ts +2 -0
  56. package/dist/check/vite-rules.js +136 -0
  57. package/dist/check/wait-rules.d.ts +16 -0
  58. package/dist/check/wait-rules.js +337 -0
  59. package/dist/commands.d.ts +7 -0
  60. package/dist/commands.js +307 -31
  61. package/dist/config-diff.d.ts +42 -0
  62. package/dist/config-diff.js +289 -0
  63. package/dist/config-edit.d.ts +35 -2
  64. package/dist/config-edit.js +145 -13
  65. package/dist/config-init.d.ts +15 -0
  66. package/dist/config-init.js +61 -0
  67. package/dist/config-paths.d.ts +22 -0
  68. package/dist/config-paths.js +82 -0
  69. package/dist/config-show.d.ts +82 -0
  70. package/dist/config-show.js +563 -0
  71. package/dist/config-values.d.ts +8 -0
  72. package/dist/config-values.js +68 -0
  73. package/dist/configuration-scaffold.d.ts +42 -0
  74. package/dist/configuration-scaffold.js +258 -4
  75. package/dist/configuration.d.ts +63 -3
  76. package/dist/configuration.js +178 -4
  77. package/dist/deployment.d.ts +2 -0
  78. package/dist/deployment.js +111 -0
  79. package/dist/describe-db.d.ts +22 -0
  80. package/dist/describe-db.js +176 -0
  81. package/dist/describe.d.ts +92 -0
  82. package/dist/describe.js +417 -0
  83. package/dist/dev-compose.d.ts +20 -0
  84. package/dist/dev-compose.js +154 -0
  85. package/dist/dev-guard.js +44 -0
  86. package/dist/dev-host.d.ts +13 -0
  87. package/dist/dev-host.js +55 -0
  88. package/dist/dev-infra.d.ts +72 -4
  89. package/dist/dev-infra.js +237 -17
  90. package/dist/dev-watch.d.ts +34 -0
  91. package/dist/dev-watch.js +192 -0
  92. package/dist/diagnostics.d.ts +10 -7
  93. package/dist/diagnostics.js +22 -4
  94. package/dist/drift.d.ts +50 -0
  95. package/dist/drift.js +218 -0
  96. package/dist/env-file.d.ts +25 -1
  97. package/dist/env-file.js +64 -6
  98. package/dist/errors.d.ts +7 -1
  99. package/dist/example-config.d.ts +2 -0
  100. package/dist/example-config.js +3 -0
  101. package/dist/first-admin.d.ts +43 -0
  102. package/dist/first-admin.js +175 -0
  103. package/dist/formatter-ignore.d.ts +37 -0
  104. package/dist/formatter-ignore.js +344 -0
  105. package/dist/generator.d.ts +45 -3
  106. package/dist/generator.js +205 -15
  107. package/dist/guide.d.ts +1 -1
  108. package/dist/guide.js +42 -21
  109. package/dist/install-module.d.ts +20 -2
  110. package/dist/install-module.js +45 -8
  111. package/dist/install-plan.js +5 -3
  112. package/dist/layout.d.ts +12 -1
  113. package/dist/layout.js +19 -6
  114. package/dist/log-writer-control.d.ts +2 -0
  115. package/dist/log-writer-control.js +17 -2
  116. package/dist/log-writer.js +43 -10
  117. package/dist/logging-config.d.ts +8 -3
  118. package/dist/logging-config.js +19 -5
  119. package/dist/manifest.d.ts +29 -1
  120. package/dist/manifest.js +84 -6
  121. package/dist/merge-install-defaults.d.ts +0 -1
  122. package/dist/merge-install-defaults.js +13 -47
  123. package/dist/npm-client.d.ts +40 -4
  124. package/dist/npm-client.js +152 -15
  125. package/dist/npm-paths.js +18 -4
  126. package/dist/openapi.d.ts +27 -0
  127. package/dist/openapi.js +649 -0
  128. package/dist/option-fixes.d.ts +39 -0
  129. package/dist/option-fixes.js +130 -0
  130. package/dist/output.d.ts +1 -1
  131. package/dist/output.js +5 -5
  132. package/dist/plugin-lifecycle.d.ts +34 -2
  133. package/dist/plugin-lifecycle.js +195 -16
  134. package/dist/plugin-options.d.ts +19 -4
  135. package/dist/plugin-options.js +138 -6
  136. package/dist/plugins-command.js +44 -7
  137. package/dist/process-group.d.ts +39 -0
  138. package/dist/process-group.js +132 -0
  139. package/dist/project-guide.d.ts +19 -1
  140. package/dist/project-guide.js +119 -20
  141. package/dist/project-inspector.d.ts +15 -0
  142. package/dist/project-inspector.js +481 -33
  143. package/dist/project-state.d.ts +5 -0
  144. package/dist/project-state.js +8 -0
  145. package/dist/project.d.ts +203 -19
  146. package/dist/project.js +3006 -333
  147. package/dist/recipe-facts.d.ts +127 -0
  148. package/dist/recipe-facts.js +563 -0
  149. package/dist/recipe-login.d.ts +63 -0
  150. package/dist/recipe-login.js +464 -0
  151. package/dist/recipe-mail.d.ts +21 -0
  152. package/dist/recipe-mail.js +214 -0
  153. package/dist/recipe-members.d.ts +35 -0
  154. package/dist/recipe-members.js +178 -0
  155. package/dist/recipe-record.d.ts +82 -7
  156. package/dist/recipe-record.js +226 -22
  157. package/dist/recipe-reset.d.ts +2 -0
  158. package/dist/recipe-reset.js +117 -0
  159. package/dist/recipe-site.d.ts +48 -0
  160. package/dist/recipe-site.js +396 -0
  161. package/dist/recipe-step.d.ts +42 -0
  162. package/dist/recipe-step.js +89 -0
  163. package/dist/recipe.d.ts +56 -20
  164. package/dist/recipe.js +703 -131
  165. package/dist/registry.d.ts +98 -2
  166. package/dist/registry.js +171 -5
  167. package/dist/reloadable.d.ts +35 -0
  168. package/dist/reloadable.js +257 -0
  169. package/dist/server.d.ts +43 -4
  170. package/dist/server.js +601 -52
  171. package/dist/settings.d.ts +48 -0
  172. package/dist/settings.js +168 -0
  173. package/dist/site-auth.d.ts +39 -0
  174. package/dist/site-auth.js +195 -0
  175. package/dist/template-fixes.d.ts +26 -0
  176. package/dist/template-fixes.js +285 -0
  177. package/dist/test-reporter.d.ts +49 -0
  178. package/dist/test-reporter.js +190 -0
  179. package/dist/transaction.d.ts +47 -0
  180. package/dist/transaction.js +241 -7
  181. package/dist/verify-tests.d.ts +98 -0
  182. package/dist/verify-tests.js +449 -0
  183. package/dist/verify.d.ts +103 -3
  184. package/dist/verify.js +272 -21
  185. package/dist/view-choice.d.ts +58 -0
  186. package/dist/view-choice.js +131 -0
  187. package/dist/vite-watch.js +4 -2
  188. package/package.json +8 -6
@@ -103,6 +103,13 @@ export function readState(value) {
103
103
  throw new CliError('INVALID_STATE', 'Invalid module name');
104
104
  });
105
105
  }
106
+ let settings;
107
+ if (input.settings !== undefined) {
108
+ settings = stringList(input.settings, (name) => {
109
+ if (!/^[a-z][a-z0-9-]{0,63}$/.test(name) || name === 'logging' || name === 'reload')
110
+ throw new CliError('INVALID_STATE', 'Invalid settings section');
111
+ });
112
+ }
106
113
  return {
107
114
  schemaVersion: 2,
108
115
  plugins,
@@ -111,6 +118,7 @@ export function readState(value) {
111
118
  generatedHash: input.generatedHash,
112
119
  ...(apps?.length ? { apps } : {}),
113
120
  ...(modules?.length ? { modules } : {}),
121
+ ...(settings?.length ? { settings } : {}),
114
122
  };
115
123
  }
116
124
  export function readConfig(value) {
package/dist/project.d.ts CHANGED
@@ -1,6 +1,10 @@
1
+ import { type ConfigDiffResult } from './config-diff.js';
1
2
  import { type SetOption, type Warning } from './config-edit.js';
3
+ import { type OptionPaths } from './config-paths.js';
4
+ import { ENV_FILE } from './dev-infra.js';
2
5
  import { NpmClient } from './npm-client.js';
3
6
  import { type Resolution } from './registry.js';
7
+ import { type AppView } from './view-choice.js';
4
8
  export interface ConfigRequirement {
5
9
  plugin: string;
6
10
  errors: Array<{
@@ -11,12 +15,24 @@ export interface ConfigRequirement {
11
15
  }
12
16
  export interface PreservedDetail {
13
17
  path: string;
14
- reason: 'MODIFIED' | 'DELETED' | 'SHARED';
18
+ reason: 'MODIFIED' | 'DELETED' | 'SHARED' | 'RETIRED_USER_FILE';
15
19
  update?: string;
16
20
  }
17
21
  export interface OperationResult {
18
22
  changed: string[];
19
23
  preserved: string[];
24
+ /** config set, unset, secret and diff --write: the option paths each file lost, changed or gained. */
25
+ paths?: Record<string, OptionPaths>;
26
+ /** D-0098: the EJS app `add` created with the apps host (`main`), whose view the CLI records. */
27
+ firstApp?: string;
28
+ /**
29
+ * `app add`: the view the app got (`ejs`, `none`, `inertia-vue`, `inertia-vue-ssr`) and where
30
+ * it came from: `recipe` when the project's recipe built no screens and no flag chose the view.
31
+ */
32
+ appView?: {
33
+ value: string;
34
+ from: 'flags' | 'recipe';
35
+ };
20
36
  preservedDetails?: PreservedDetail[];
21
37
  configRequired?: ConfigRequirement[];
22
38
  /** Required plugins installed together with the requested one (manifest `package`). */
@@ -25,8 +41,12 @@ export interface OperationResult {
25
41
  packageName: string;
26
42
  version: string;
27
43
  }>;
44
+ /** `deprecated`: an install plan field this CLI still takes but a later one drops. */
28
45
  warnings?: Array<Warning & {
29
46
  plugin?: string;
47
+ deprecated?: string;
48
+ hint?: string;
49
+ count?: number;
30
50
  }>;
31
51
  /** What to do after this command: a command (or an edit) and why (D-0065). */
32
52
  nextSteps?: NextStep[];
@@ -34,26 +54,53 @@ export interface OperationResult {
34
54
  resolved?: Resolution;
35
55
  from?: string;
36
56
  to?: string;
37
- /** Why an upgrade to the same version was applied: the installed manifest differs (D-0037). */
38
- reason?: 'MANIFEST_CHANGED';
57
+ /**
58
+ * Why an upgrade to the same version was applied: the installed manifest differs (D-0037), or
59
+ * the package's content does (an unpublished version rebuilt and given as `--to <tgz>`).
60
+ */
61
+ reason?: 'MANIFEST_CHANGED' | 'PACKAGE_CHANGED';
39
62
  /** npm workspace root where `npm install` ran (or, in a dry run, would run) (D-0035). */
40
63
  workspaceInstall?: string;
41
64
  /**
42
- * Secrets `add` generated into .env for the plugins it installed (D-0073): variable names only,
43
- * the values are never shown. A variable already set in the environment or .env is kept.
65
+ * Secrets `add` generated for the plugins it installed (D-0073 addendum 2): the option in
66
+ * dokebi.yaml (`configSecrets`), or a variable in .env for a plugin that still declares the
67
+ * deprecated `envSecrets`. Names only, the values are never shown; an existing value is kept.
44
68
  */
45
69
  generatedSecrets?: GeneratedSecret[];
46
70
  }
47
- /** One generated secret of `add` (D-0073). */
48
- export interface GeneratedSecret {
49
- readonly variable: string;
71
+ /** One generated secret of `add`: an option in dokebi.yaml, or (deprecated) a .env variable. */
72
+ export type GeneratedSecret = {
73
+ readonly plugin: string;
74
+ readonly option: string;
50
75
  readonly file: string;
76
+ } | {
51
77
  readonly plugin: string;
78
+ readonly variable: string;
79
+ readonly file: typeof ENV_FILE;
80
+ };
81
+ export declare const ROTATE_KEEP = 2;
82
+ /** What `config secret` did at one option: names and counts only, never a value. */
83
+ export interface SecretOutcome {
84
+ readonly path: string;
85
+ readonly list: boolean;
86
+ readonly generated: boolean;
87
+ /** The value came from stdin (`--stdin`), not generated. */
88
+ readonly stdin?: boolean;
89
+ /** `--rotate` replaced an existing value. */
90
+ readonly rotated?: boolean;
91
+ /** Previous secrets kept after the new one (a list), and older ones dropped. */
92
+ readonly kept?: number;
93
+ readonly dropped?: number;
52
94
  }
53
95
  /** `dokebi add` choices beyond the package (D-0065). */
54
96
  export interface AddOptions {
55
97
  /** @dokebi/db: write this adapter (pg, mysql2, mariadb, mongodb), its connection and driver. */
56
98
  adapter?: string;
99
+ /**
100
+ * @dokebi/db with `adapter` (D-0127): written as connections.main.startup only when given;
101
+ * `optional` lets the app start and run while that database is down.
102
+ */
103
+ startup?: 'required' | 'optional';
57
104
  /** The plugin that hosts apps (D-0070): false skips the first `main` app (`--no-first-app`). */
58
105
  firstApp?: boolean;
59
106
  }
@@ -65,6 +112,9 @@ export interface NextStep {
65
112
  /** `dokebi init`: the created folder, plus what to do next (machine-readable). */
66
113
  export interface InitResult extends OperationResult {
67
114
  nextSteps: NextStep[];
115
+ deployment?: {
116
+ files: string[];
117
+ };
68
118
  }
69
119
  /**
70
120
  * Follow-ups after init (D-0065): read the guide, pick a recipe and ask its questions, find
@@ -87,15 +137,25 @@ staging?: string): Promise<{
87
137
  exists: boolean;
88
138
  kept: string[];
89
139
  }>;
140
+ /** D-0151: the app logger every new project gets. */
141
+ export declare const LOGGER_PACKAGE = "@dokebi/logger";
90
142
  export declare class Project {
91
143
  #private;
92
144
  private readonly npm;
93
145
  constructor(npm?: NpmClient);
94
- init(target: string, core?: string, dryRun?: boolean): Promise<InitResult>;
146
+ /**
147
+ * A new project (D-0065). D-0151: every new project gets @dokebi/logger, added by `add` once
148
+ * the project exists (stdout JSON, pretty output in dokebi dev, a file target to turn on for
149
+ * production). When that install fails (offline, a registry without it) the project stays on
150
+ * core's console logger and the result says so (warning LOGGER_NOT_INSTALLED and the command).
151
+ */
152
+ init(target: string, core?: string, dryRun?: boolean, deploy?: boolean, logger?: boolean): Promise<InitResult>;
95
153
  migrate(root: string, dryRun?: boolean): Promise<OperationResult>;
96
154
  add(root: string, spec: string, dryRun?: boolean, sets?: readonly SetOption[], options?: AddOptions): Promise<OperationResult>;
97
155
  remove(root: string, id: string, dryRun?: boolean): Promise<OperationResult>;
98
156
  upgrade(root: string, id: string, to?: string, dryRun?: boolean): Promise<OperationResult>;
157
+ /** Refresh only maintained AGENTS blocks; project instructions remain byte-for-byte intact. */
158
+ syncGuide(root: string, dryRun?: boolean): Promise<OperationResult>;
99
159
  /**
100
160
  * `dokebi config set <plugin>.<path>=<value>…`: non-secret options in dokebi.yaml, checked
101
161
  * against that plugin's schema (only missing required values are tolerated and reported).
@@ -103,11 +163,47 @@ export declare class Project {
103
163
  configSet(root: string, assignments: readonly {
104
164
  plugin: string;
105
165
  set: SetOption;
106
- }[], dryRun?: boolean): Promise<OperationResult>;
166
+ }[], dryRun?: boolean): Promise<OperationResult & {
167
+ file: string;
168
+ }>;
169
+ /**
170
+ * `dokebi config unset <plugin>.<path>…` (D-0153): removes options from dokebi.yaml, and from
171
+ * dokebi.example.yaml where the sample has them, in one transaction. A path that is not set is
172
+ * a warning (OPTION_NOT_SET), not an error, so a repeated call changes nothing. Values are never
173
+ * returned or logged; removing a secret is allowed and warned (SECRET_REMOVED: what it signed
174
+ * no longer verifies). The plugin need not be installed (a section kept by `dokebi remove`).
175
+ * Removing may only leave issues the options already had, or missing required values
176
+ * (configRequired); issues that remain are a warning that carries the next fix.
177
+ */
178
+ configUnset(root: string, targets: readonly {
179
+ plugin: string;
180
+ path: readonly string[];
181
+ }[], dryRun?: boolean): Promise<OperationResult & {
182
+ file: string;
183
+ removed: {
184
+ option: string;
185
+ files: string[];
186
+ }[];
187
+ }>;
107
188
  /**
108
- * `dokebi dev-infra` (D-0065): compose.yaml for the database of connection `main`, a generated
109
- * password in .env (git-ignored) and the matching URL in dokebi.yaml. An existing compose.yaml
110
- * with a `db` service and an existing password are kept; nothing is started here.
189
+ * `dokebi config diff [<id>] --write` (AI-M46): copies the options only in dokebi.yaml into
190
+ * dokebi.example.yaml without their secrets, in one transaction. Paths both files set keep the
191
+ * sample's value (a sample may differ) unless `values` (`--values`, Studio v2) writes
192
+ * dokebi.yaml's; secrets inside a copied path are left out. The written sample is compared
193
+ * again and refused if it would hold a secret (fail closed).
194
+ */
195
+ configSample(root: string, section: string | undefined, dryRun?: boolean, prune?: boolean, values?: boolean): Promise<OperationResult & {
196
+ file: string;
197
+ written: string[];
198
+ pruned: string[];
199
+ valuesWritten?: string[];
200
+ diff: ConfigDiffResult;
201
+ }>;
202
+ /**
203
+ * `dokebi dev-infra` (D-0065): compose.yaml for the database of connection `main` and the URL
204
+ * with a generated password in dokebi.yaml (no .env is written; a legacy .env password is reused
205
+ * only when the YAML has no URL). An existing compose.yaml with a `db` service and an existing
206
+ * password are kept; nothing is started here.
111
207
  */
112
208
  devInfra(root: string, options?: {
113
209
  dbPort?: number;
@@ -118,14 +214,59 @@ export declare class Project {
118
214
  /**
119
215
  * `dokebi config secret <plugin>.<path>`: a generated random secret (32 bytes, base64url) in
120
216
  * dokebi.yaml, as a one-item list when the schema wants a list. The value is never returned or
121
- * logged; an existing value is kept (SECRET_KEPT). Secrets never pass the command line.
217
+ * logged; an existing value is kept (SECRET_KEPT) unless `rotate` (`--rotate`, AI-M05): a string
218
+ * is replaced; a list gets the new secret first (it signs) and keeps the previous ones after it,
219
+ * at most ROTATE_KEEP of them (older ones are dropped: SECRETS_DROPPED), so what the old ones
220
+ * signed still verifies during the rotation. Secrets never pass the command line. `value`
221
+ * (`--stdin`, D-0151 follow-up): a secret someone else issued, such as the token of a log
222
+ * receiver (`logging.targets.studio.token`), written instead of a generated one; never returned
223
+ * or logged either. A list item is named by its `name` (else `type`) or its index.
122
224
  */
123
- configSecret(root: string, id: string, path: readonly string[], dryRun?: boolean): Promise<OperationResult & {
124
- secret: {
125
- path: string;
126
- list: boolean;
127
- generated: boolean;
225
+ configSecret(root: string, id: string, path: readonly string[], dryRun?: boolean, rotate?: boolean, value?: string): Promise<OperationResult & {
226
+ file: string;
227
+ secret: SecretOutcome;
228
+ }>;
229
+ /**
230
+ * `dokebi config init` (D-0163, R3 Claude T4 review): a fresh copy of a project (a clone, a CI
231
+ * checkout) has no dokebi.yaml, which stays out of version control, and no command made one:
232
+ * `dev-infra up` failed with INTERNAL_ERROR. Writes it from dokebi.example.yaml with a generated
233
+ * secret for every required secret option the sample leaves out (the sample holds none), and
234
+ * names the placeholders (`<set … here>`) still to fill. Never replaces an existing file.
235
+ */
236
+ configInit(root: string, dryRun?: boolean): Promise<OperationResult & {
237
+ file: string;
238
+ generatedSecrets: GeneratedSecret[];
239
+ placeholders: string[];
240
+ }>;
241
+ /**
242
+ * User code a recipe writes (D-0076 §6, `recipe blog --admin login`), in one transaction under
243
+ * the project lock. A new file is written; a file with the same content is left alone; a file
244
+ * marked `replaceTemplate` is replaced only while it still is the untouched template its plugin
245
+ * installed (the hash `state.files` recorded); anything else is RECIPE_FILE_CONFLICT. `edits`
246
+ * change existing files (they return the text unchanged when already applied). `config` sets
247
+ * values of a dokebi.yaml section no plugin owns; a `secret` value is generated (never returned
248
+ * or logged) and an existing one is kept. Nothing is written when nothing changes.
249
+ */
250
+ writeRecipeFiles(root: string, request: {
251
+ readonly files: readonly {
252
+ readonly path: string;
253
+ readonly content: string;
254
+ readonly replaceTemplate?: boolean;
255
+ }[];
256
+ readonly edits?: readonly {
257
+ readonly path: string;
258
+ edit(text: string): string;
259
+ }[];
260
+ readonly config?: {
261
+ readonly section: string;
262
+ readonly values: readonly {
263
+ readonly key: string;
264
+ readonly value?: string;
265
+ }[];
128
266
  };
267
+ }): Promise<OperationResult & {
268
+ written: string[];
269
+ kept: string[];
129
270
  }>;
130
271
  private coreVersion;
131
272
  /**
@@ -139,11 +280,19 @@ export declare class Project {
139
280
  inertia?: boolean;
140
281
  /** With `inertia`: render the first HTML of a page on the server (D-0039). */
141
282
  ssr?: boolean;
283
+ /** Seal these domains (`domains.<host>.seal: true`, @dokebi/seal, D-0062/D-0092). */
284
+ seal?: boolean;
285
+ /**
286
+ * `ejs` or `none` (no views, a JSON API). Unset: `none` when the project's recipe built no
287
+ * browser screens (the api recipe records view = none, D-0098), else `ejs`.
288
+ */
289
+ view?: AppView;
142
290
  }): Promise<OperationResult>;
143
291
  /** `dokebi app link <app> <domain> [--template t]`: maps one more domain to an existing app. */
144
292
  appLink(root: string, name: string, domain: string, options?: {
145
293
  template?: string;
146
294
  dryRun?: boolean;
295
+ seal?: boolean;
147
296
  }): Promise<OperationResult>;
148
297
  /** `dokebi app unlink <domain>`: removes one domain mapping from dokebi.yaml and the sample. */
149
298
  appUnlink(root: string, domain: string, dryRun?: boolean): Promise<OperationResult>;
@@ -177,5 +326,40 @@ export declare class Project {
177
326
  path: string;
178
327
  }[];
179
328
  }>;
329
+ /**
330
+ * D-0155: `dokebi settings add <section>`: the settings of the application in options.<section>.
331
+ * Writes src/shared/settings/<section>.ts (or keeps one that is already there and default-exports
332
+ * defineSettings for this section), its schema file from the declaration, the defaults of the
333
+ * section in dokebi.yaml and the example (with the reloadable marks), and registers it so the
334
+ * app checks the section at start. A plugin's section, logging or reload is refused.
335
+ */
336
+ settingsAdd(root: string, section: string, options?: {
337
+ dryRun?: boolean;
338
+ }): Promise<OperationResult>;
339
+ /**
340
+ * D-0155: `dokebi settings sync`: writes the schema file of every settings section again from
341
+ * its declaration and adds the defaults of new options to dokebi.yaml and the example (with the
342
+ * reloadable marks). Nothing is written when every schema is current. AI-M49 D2: a value that
343
+ * is still the old default (the CLI wrote it) follows a changed default (`followed`), and the
344
+ * options are checked against the new schema as doctor checks them: a missing required value
345
+ * is `configRequired`, anything else INVALID_PLUGIN_OPTIONS and nothing is written.
346
+ */
347
+ settingsSync(root: string, dryRun?: boolean): Promise<OperationResult & {
348
+ sections: {
349
+ section: string;
350
+ changed: boolean;
351
+ followed?: string[];
352
+ }[];
353
+ }>;
354
+ /** `dokebi settings remove <section>`: unregisters it; its files and its options stay. */
355
+ settingsRemove(root: string, section: string, dryRun?: boolean): Promise<OperationResult>;
356
+ /** `dokebi settings list`: the settings sections with their declaration and schema files. */
357
+ settingsList(root: string): Promise<{
358
+ settings: {
359
+ section: string;
360
+ file: string;
361
+ schema: string;
362
+ }[];
363
+ }>;
180
364
  private writeConfiguration;
181
365
  }