@cellajs/cli 0.3.2 → 0.4.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/README.md CHANGED
@@ -20,7 +20,7 @@ pnpm cella audit
20
20
  | `analyze` | Dry run to see what would change on sync. It leaves your files and branches alone but updates git metadata: it fetches upstream and writes `refs/cella/last-sync` and a graft for the sync base |
21
21
  | `sync` | Merge upstream changes onto a fresh branch, sync package.json and open a squash-merge PR into `main` |
22
22
  | `migrate` | List the upstream migration notes this app has not handled yet, read them, run their codemods, record them |
23
- | `audit` | Check for outdated packages and vulnerabilities |
23
+ | `audit` | Update outdated packages, then rebuild the security overrides from a fresh audit |
24
24
  | `stats` | Count files by category and workspace package; with `--since <ref>`, count what the current branch changed, by kind of file |
25
25
  | `forks` * | Run normal sync inside local fork repositories |
26
26
  | `contributions` * | Pull and adopt changes from local forks |
@@ -37,13 +37,13 @@ Per-service help: `pnpm cella <service> --help`.
37
37
 
38
38
  | Service | Useful options |
39
39
  |---------|----------------|
40
- | analyze | `--log`, `--list`, `--json`, `--scope <all\|risk\|protected>`, `--track <release\|branch>`, `--ref <ref>`, `--diff <path>`, `--open-diff <path>` |
41
- | sync | `--log`, `--hard`, `--unpinned`, `--track <release\|branch>`, `--ref <ref>`, `--keep-config` |
42
- | migrate | `--all`, `--json`, `--show <id>`, `--extract <id>`, `--run <id> [-- <codemod args>]`, `--script <file>`, `--mark <ids...>` |
43
- | audit | `--list`, `--force`, `--check-overrides` |
44
- | forks | `--fork <name>`, `--log`, `--hard`, `--keep-config`, `-V, --verbose` |
45
- | contributions | `--fork <name>`, `--list`, `--json`, `--diff <path>` |
46
- | stats | `--coverage`, `--since <ref>`, `--md`, `-V, --verbose` |
40
+ | analyze | `--list`, `--json`, `--scope <all\|risk\|protected>`, `--track <release\|branch>`, `--ref <ref>`, `--unpinned` |
41
+ | sync | `--track <release\|branch>`, `--ref <ref>`, `--keep-config`, `--unpinned` |
42
+ | migrate | `--all`, `--json`, `--show <id>`, `--extract <id>`, `--run <id> [-- <codemod args>]`, `--mark <ids...>` |
43
+ | audit | `--list` |
44
+ | forks | `--fork <name>`, `--keep-config` |
45
+ | contributions | `--fork <name>`, `--json` |
46
+ | stats | `--since <ref>`, `--md`, `-V, --verbose` |
47
47
 
48
48
  | Global flag | Description |
49
49
  |-------------|-------------|
@@ -63,6 +63,10 @@ has and your app deleted). Every run warns `ignored entry not found` only when n
63
63
  upstream has the path. Upstream is read at `settings.upstreamBranch` as last fetched; before the
64
64
  first fetch, every `ignored` entry missing from your app warns.
65
65
 
66
+ Every run also warns about a `pinned` entry that does nothing: one inside an `ignored` path (app
67
+ modules included), one upstream no longer has (the file is your app's own now), and one identical
68
+ to upstream, which only drops upstream's next change to it.
69
+
66
70
  ## Upstream tracking
67
71
 
68
72
  The sync CLI tracks upstream cella one of two ways, set via `settings.upstreamTrack`:
@@ -109,7 +113,8 @@ drift triage (`pnpm cella analyze` diffs committed HEAD) and follow-up commits h
109
113
  committed; then the run stops on the branch. A conflicted merge stops earlier so you can
110
114
  resolve in your IDE (`git add` the resolved files) and re-run to commit.
111
115
  2. **Final re-run `pnpm cella sync`** on the committed branch ships it: pushes to `origin`,
112
- opens a PR into `main` (via `gh`), and switches you back to `main`.
116
+ opens a PR into `main` (via `gh`) titled like the sync commit, even with follow-up commits on
117
+ top, and switches you back to `main`.
113
118
 
114
119
  Before the merge starts, a first run checks that it can go ahead, and stops without changing
115
120
  anything when it cannot: the temporary branch is removed again and you are back on the branch you
@@ -173,8 +178,7 @@ pnpm cella migrate --mark <id> [...] # record notes as handled
173
178
 
174
179
  `--run` extracts the note and runs its codemod with `tsx` from your app root. Everything after `--`
175
180
  goes to the codemod as given; without it the codemod gets `inventory` and the note's `roots`, the
176
- report-only run. The codemod is the one script in the note folder; when a folder holds several,
177
- name it with `--script <file>`.
181
+ report-only run.
178
182
 
179
183
  A codemod's roots cover template-owned files too, and a file that is identical to upstream already
180
184
  is the way upstream wants it: upstream may have changed it after writing the codemod, so a rewrite
@@ -203,15 +207,6 @@ out:
203
207
  assets, config you own). `pinned` = your version always wins but stays visible (files you
204
208
  customize). Unconfigured = syncs automatically. Run `pnpm cella analyze` first to preview.
205
209
 
206
- ### Aggressive sync flags
207
-
208
- Two opt-in flags make `sync` more aggressive. Both resurface full upstream history (natural merge-base, not the last-sync point), so expect a larger diff and a post-run warning: cherry-pick deliberately. They compose (`--hard --unpinned`).
209
-
210
- | Flag | Effect |
211
- |------|--------|
212
- | `--hard` | Overwrites `drifted` files with upstream (local-only changes are replaced) |
213
- | `--unpinned` | Ignores `pinned` files so upstream surfaces as `behind`/`diverged`; managed files stay pinned |
214
-
215
210
  ## Status indicators
216
211
 
217
212
  During analysis and sync, files are displayed with status indicators:
@@ -249,18 +244,23 @@ Both lists end with one `git diff <last-sync>..<upstream> -- <entry>` line per `
249
244
  ⨀ frontend/src/styling/tailwind.css · 21 lines changed upstream
250
245
  ⨂ shared/config/default.ts · 4 lines changed upstream
251
246
  ⨂ shared/config/staging.ts · 2 lines changed upstream
252
- pinned/ignored files where upstream also changed since the last sync; the fork side wins on conflict, so diff each against upstream (analyze --open-diff <path>) and adopt what you need.
247
+ pinned/ignored files where upstream also changed since the last sync; the fork side wins on conflict, so diff each against upstream and adopt what you need.
253
248
  what upstream changed since the last sync, per pinned/ignored entry:
254
249
  git diff e9a8d485e..a81e3353b -- frontend/src/styling/tailwind.css
255
250
  git diff e9a8d485e..a81e3353b -- shared/config
256
251
  ```
257
252
 
258
- Diff each against upstream (`cella analyze --open-diff <path>`) and adopt what you need. The
259
- check is relative to the last sync point: a drop that happened in an earlier sync only shows up
260
- as plain `ahead` afterwards. For that case the `↑ protected in fork` section annotates pinned
261
- files with `· N upstream lines absent` (lines upstream has that the fork lacks, compared at the
262
- tips, `--json`: `upstreamLinesAbsent`). That is upstream content the fork never received,
263
- deliberately or not: diff and decide. Ignored files are not annotated.
253
+ Paste those lines to see what upstream changed and adopt what you need. The check is relative to
254
+ the last sync point: a drop that happened in an earlier sync only shows up as plain `ahead`
255
+ afterwards. For that case the `↑ protected in fork` section annotates pinned files with
256
+ `· N upstream lines absent` (lines upstream has that the fork lacks, compared at the tips,
257
+ `--json`: `upstreamLinesAbsent`). That is upstream content the fork never received, deliberately
258
+ or not: diff and decide. Ignored files are not annotated.
259
+
260
+ To pull upstream into every pinned file at once, run `sync --unpinned`: pins are lifted for that
261
+ run (managed files stay pinned) and the merge uses the full upstream history, so changes earlier
262
+ syncs dropped come back too. Review the staged merge in your editor and keep what you want;
263
+ `analyze --unpinned` previews it.
264
264
 
265
265
  ### Upstream changes that never sync
266
266
 
@@ -326,12 +326,50 @@ command that runs the script. The sync lists every change and warns about each e
326
326
  way, so you can remove it once your code no longer needs it. `exports` are add-only: an entry your fork
327
327
  already defines is never rewritten, and `exports` only merges when both sides are subpath maps
328
328
  (`{ ".": …, "./config": … }`). A workspace upstream added since your last sync arrives with its
329
- package.json copied verbatim.
329
+ package.json copied verbatim. A merged section is sorted alphabetically, except `scripts`: they
330
+ keep upstream's order, and a script only your fork has stays after the one it follows.
330
331
 
331
332
  `type` always syncs, whatever `packageJsonSync` lists: it follows upstream where your fork kept the
332
333
  previous value, and a package.json without `type` gets upstream's. Set it yourself (for example
333
334
  `"commonjs"`) to keep your own.
334
335
 
336
+ ## Audit
337
+
338
+ `pnpm cella audit` works in two layers, in this order:
339
+
340
+ 1. **Updates.** It lists the outdated packages and updates the ones you pick.
341
+ 2. **Security.** It audits what is left and brings three settings in `pnpm-workspace.yaml` in line
342
+ with that audit.
343
+
344
+ The security layer treats its overrides as output, not as configuration. Every run it drops them,
345
+ resolves the workspace without them in a temporary copy, and puts back only the ones a current
346
+ advisory still needs. An override whose package now resolves to a fixed version, because you
347
+ updated a parent or the parent widened its range, is gone after the next run. The workspace
348
+ changes once, at the end, and only when the outcome differs from what is there.
349
+
350
+ | Setting | What the audit owns | What it leaves alone |
351
+ |---------|---------------------|----------------------|
352
+ | `overrides` | keys with a version selector: `pkg@<1.2.3` | keys without one (`pkg`) and parent-scoped keys (`parent>pkg`) |
353
+ | `minimumReleaseAgeExclude` | `pkg@1.2.3` entries, removed once that version is older than `minimumReleaseAge` | name-only entries |
354
+ | `auditConfig.ignoreGhsas` | every entry, removed when the advisory no longer applies or a fix arrives | |
355
+
356
+ To keep an override whatever the audit finds, write it without a version selector.
357
+
358
+ For each advisory the audit looks up the published versions itself; it does not trust the patched
359
+ version an advisory claims. Most outcomes need no answer from you:
360
+
361
+ - **A fix that fits.** The audit writes an override. When the fix lies inside the range the
362
+ parents ask for, the lockfile holds the fixed version on its own, and the following run drops
363
+ the override.
364
+ - **A breaking fix** (another major, or another minor below 1.0), or a fix for a package you
365
+ depend on directly: you choose between leaving it open, applying the override and ignoring the
366
+ advisory. An override that was in place before the run is applied again without asking.
367
+ - **A fix younger than `minimumReleaseAge`**: you choose between waiting and installing it now
368
+ with an exclude.
369
+ - **No fix published**: you are asked whether to ignore the advisory until one is.
370
+
371
+ `--list` prints the same report without prompts and writes nothing.
372
+
335
373
  ## Contributions (pull from forks)
336
374
 
337
375
  Upstream can pull modifications from local forks and selectively adopt them.
@@ -349,7 +387,6 @@ forks: [
349
387
  Run `pnpm cella contributions` (or pick **contributions** from the menu). Select a fork; cella
350
388
  fetches its `pullBranch` and builds a clean local `contrib/<fork>` branch with only that fork's
351
389
  contributed files. Accepted files are checked out from the contrib branch and staged for review.
352
- `--list` prints the result as tab-separated rows (fork, status, kind, changedAt, path) for tooling.
353
390
 
354
391
  ## Stats of a branch
355
392
 
package/dist/config.d.ts CHANGED
@@ -20,7 +20,7 @@ interface SyncSettings {
20
20
  upstreamBranch?: string;
21
21
  /**
22
22
  * How to track upstream cella. Defaults to 'release'.
23
- * - 'release' (default): sync to a published cella release tag (`v*`). Stable and
23
+ * - 'release' (default): sync to a published cella release tag (`0.18.1`, with or without `v`). Stable and
24
24
  * reviewable: each bump maps to a changelog. Uses the latest release.
25
25
  * - 'branch': follow the bleeding-edge tip of `upstreamBranch`. For cella
26
26
  * maintainers and forks doing active development on top of unreleased changes.
@@ -40,9 +40,8 @@ interface SyncSettings {
40
40
  * How to link files in CLI output.
41
41
  * - 'commit' (default): Link to the commit that changed the file on GitHub.
42
42
  * - 'file': Link to the file in the repo at the upstream branch on GitHub.
43
- * - 'local': Deprecated (the upstream view worktree was replaced by browser diffs); treated as 'file'.
44
43
  */
45
- fileLinkMode?: 'commit' | 'file' | 'local';
44
+ fileLinkMode?: 'commit' | 'file';
46
45
  }
47
46
  /**
48
47
  * Configuration for a downstream fork repository that cella interacts with.
@@ -83,10 +82,11 @@ interface CellaCliConfig {
83
82
  */
84
83
  ignored?: string[];
85
84
  /**
86
- * Paths pinned to the fork: fork wins on conflicts.
85
+ * Paths pinned to the fork: the fork copy wins whole-file.
87
86
  * Exact paths or directory prefixes, not globs: 'bench' matches 'bench/' and
88
87
  * everything under it, 'README.md' matches that exact file.
89
- * Non-conflicting upstream changes merge normally.
88
+ * Upstream changes to a pinned file are dropped, not merged: analyze lists them under
89
+ * "protected but behind upstream" to adopt by hand.
90
90
  * If fork deleted a pinned file, deletion is respected.
91
91
  */
92
92
  pinned?: string[];
package/dist/config.js CHANGED
@@ -23,7 +23,7 @@ var cellaConfigSchema = z.object({
23
23
  releaseBase: z.string().min(1).optional(),
24
24
  packageJsonSync: z.array(z.enum(PACKAGE_JSON_SYNC_KEYS)).optional(),
25
25
  syncWithPackages: z.boolean().optional(),
26
- fileLinkMode: z.enum(["commit", "file", "local"]).optional()
26
+ fileLinkMode: z.enum(["commit", "file"]).optional()
27
27
  }).strict(),
28
28
  overrides: z.object({
29
29
  ignored: z.array(z.string()).optional(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/types.ts"],"sourcesContent":["/**\n * Configuration types: the public cella/cella.config.ts surface, its runtime\n * schema, and the internal types the services share.\n */\n\nimport { z } from 'zod';\n\n// Public API for cella/cella.config.ts.\n\nconst PACKAGE_JSON_SYNC_KEYS = [\n 'dependencies',\n 'devDependencies',\n 'peerDependencies',\n 'optionalDependencies',\n 'scripts',\n 'engines',\n 'packageManager',\n 'overrides',\n 'exports',\n 'pnpm',\n] as const;\n\n/** Valid package.json keys that can be synced */\nexport type PackageJsonSyncKey = (typeof PACKAGE_JSON_SYNC_KEYS)[number];\n\n/**\n * Sync settings: all configurable options for the sync CLI.\n * Hover over each property for documentation.\n */\nexport interface SyncSettings {\n /** Upstream repository URL (e.g., 'git@github.com:cellajs/cella.git') */\n upstreamUrl: string;\n\n /**\n * Upstream branch, used for `upstreamTrack: 'branch'` and for GitHub file links.\n * Defaults to 'main'.\n */\n upstreamBranch?: string;\n\n /**\n * How to track upstream cella. Defaults to 'release'.\n * - 'release' (default): sync to a published cella release tag (`v*`). Stable and\n * reviewable: each bump maps to a changelog. Uses the latest release.\n * - 'branch': follow the bleeding-edge tip of `upstreamBranch`. For cella\n * maintainers and forks doing active development on top of unreleased changes.\n */\n upstreamTrack?: 'release' | 'branch';\n\n /**\n * Trunk branch that `pnpm cella sync` cuts the temporary branch from and that you open the\n * squash-merge PR into. Defaults to 'main'. Cutting fresh from trunk each cycle keeps every\n * PR limited to that cycle's upstream delta (no accumulation) and `main` linear.\n */\n releaseBase?: string;\n\n /** Which package.json keys to sync (default: ['dependencies', 'devDependencies']). `type` always syncs. */\n packageJsonSync?: PackageJsonSyncKey[];\n\n /** Automatic package.json sync after the sync service completes (default: true). Set to false to turn it off. */\n syncWithPackages?: boolean;\n\n /**\n * How to link files in CLI output.\n * - 'commit' (default): Link to the commit that changed the file on GitHub.\n * - 'file': Link to the file in the repo at the upstream branch on GitHub.\n * - 'local': Deprecated (the upstream view worktree was replaced by browser diffs); treated as 'file'.\n */\n fileLinkMode?: 'commit' | 'file' | 'local';\n}\n\n/**\n * Configuration for a downstream fork repository that cella interacts with.\n *\n * Cella is the upstream/source-of-truth. For each fork it can:\n * - pull contributions FROM the fork's `pullBranch` (contributions service)\n * - run the normal temporary-branch sync flow inside the fork (forks service)\n */\nexport interface ForkConfig {\n /** Display name for the fork (also used as the contrib/<name> branch slug) */\n name: string;\n /** Local path to the fork repository (relative to this config or absolute) */\n localPath: string;\n /**\n * Git remote URL of the fork (e.g. 'git@github.com:org/fork.git').\n * When set, the contributions service fetches the fork's `pullBranch` from this\n * remote (the authoritative committed ref), so the comparison does not depend on\n * the local checkout being up to date. The local clone is still used to read the\n * fork's owned-folder territory when available.\n */\n remoteUrl?: string;\n /** Fork branch that cella pulls contributions from (contributions service) */\n pullBranch: string;\n}\n\n/** User-configurable sync options for cella/cella.config.ts. */\nexport interface CellaCliConfig {\n /** Core sync settings */\n settings: SyncSettings;\n\n /**\n * File overrides for controlling sync behavior per folder/file.\n */\n overrides?: {\n /**\n * Paths the fork fully owns: never synced (existing or new).\n * Exact paths or directory prefixes, not globs: 'bench' matches 'bench/' and\n * everything under it, 'README.md' matches that exact file.\n * Local territory: upstream cannot add, modify, or delete anything under these.\n */\n ignored?: string[];\n\n /**\n * Paths pinned to the fork: fork wins on conflicts.\n * Exact paths or directory prefixes, not globs: 'bench' matches 'bench/' and\n * everything under it, 'README.md' matches that exact file.\n * Non-conflicting upstream changes merge normally.\n * If fork deleted a pinned file, deletion is respected.\n */\n pinned?: string[];\n };\n\n /**\n * Downstream fork repositories that cella interacts with (for upstream template repos).\n * When configured, the 'forks' and 'contributions' services appear in the CLI menu.\n */\n forks?: ForkConfig[];\n}\n\n/**\n * Helper function for defining cella/cella.config.ts with type checking.\n */\nexport function defineConfig(config: CellaCliConfig): CellaCliConfig {\n return config;\n}\n\n/**\n * Strict runtime schema mirroring {@link CellaCliConfig}.\n *\n * The TS interfaces above stay the source of truth (and keep their hover docs for\n * config authors). This schema is what's enforced at load time: `.strict()` rejects\n * unknown keys, so a typo like `ignoredFolders` for `ignored` fails closed; a silent\n * fallback would drop sync protection (tsx does not typecheck the config).\n *\n * The `satisfies z.ZodType<CellaCliConfig>` assertion keeps schema and interface in\n * lockstep: if either drifts (a renamed/removed/mis-typed field), TypeScript errors here.\n */\nexport const cellaConfigSchema = z\n .object({\n settings: z\n .object({\n upstreamUrl: z.string().min(1),\n upstreamBranch: z.string().min(1).optional(),\n upstreamTrack: z.enum(['release', 'branch']).optional(),\n releaseBase: z.string().min(1).optional(),\n packageJsonSync: z.array(z.enum(PACKAGE_JSON_SYNC_KEYS)).optional(),\n syncWithPackages: z.boolean().optional(),\n fileLinkMode: z.enum(['commit', 'file', 'local']).optional(),\n })\n .strict(),\n overrides: z\n .object({\n ignored: z.array(z.string()).optional(),\n pinned: z.array(z.string()).optional(),\n })\n .strict()\n .optional(),\n forks: z\n .array(\n z\n .object({\n name: z.string().min(1),\n localPath: z.string().min(1),\n remoteUrl: z.string().optional(),\n pullBranch: z.string().min(1),\n })\n .strict(),\n )\n .optional(),\n })\n .strict() satisfies z.ZodType<CellaCliConfig>;\n\n// Internal types for the services.\n\n/** Sync services available in the CLI */\nexport type SyncService = 'analyze' | 'sync' | 'migrate' | 'audit' | 'forks' | 'contributions' | 'stats';\n\n/** Analyze output scope for interactive and machine-readable flows */\nexport type AnalyzeScope = 'all' | 'risk' | 'protected';\n\n/** Runtime configuration with all resolved values */\nexport interface RuntimeConfig extends CellaCliConfig {\n /** Resolved fork repository path */\n forkPath: string;\n\n /** Full upstream remote ref (e.g., 'cella-upstream/development') */\n upstreamRef: string;\n\n /** Selected sync service */\n service: SyncService;\n\n /** Write full file list to log file */\n logFile: boolean;\n\n /** Non-interactive list output (for LLM/agent usage) */\n list: boolean;\n\n /** Machine-readable JSON output (for tooling/agent usage) */\n json: boolean;\n\n /** Print the unified diff for one file, then exit (analyze and contributions; for tooling/agents) */\n diff?: string;\n\n /** Open a browser diff for one file, then exit (analyze) */\n openDiff?: string;\n\n /** Scope of files returned in analyze list/json output */\n scope?: AnalyzeScope;\n\n /** Show verbose output */\n verbose: boolean;\n\n /** Pre-selected fork name (skips fork selection prompt) */\n fork?: string;\n\n /** Overwrite drifted files with upstream version (aggressive realignment) */\n hard?: boolean;\n\n /**\n * Disable pinned entries (cella/cella.config.ts overrides.pinned) for this sync so upstream\n * versions surface as behind/diverged. Managed files stay pinned because cella\n * handles them separately. Like --hard, uses the natural merge-base to resurface\n * full upstream history.\n */\n unpinned?: boolean;\n\n /**\n * Override upstream tracking for this run (analyze/sync), ignoring `settings.upstreamTrack`.\n * 'branch' follows the upstream branch tip (bleeding edge); 'release' uses a release tag.\n */\n track?: 'release' | 'branch';\n\n /**\n * Pin the upstream ref for this run (analyze/sync), overriding `track`: a commit sha, a release\n * tag or an upstream branch name. Must be on the upstream branch or in an upstream release.\n */\n ref?: string;\n\n /**\n * Merge with the fork's sync config as it stands (sync service). Without it, a new merge stops\n * before anything changes when upstream changed its own `overrides` or `packageJsonSync` in ways\n * the fork config does not follow.\n */\n keepConfig?: boolean;\n\n /** Bypass pnpm metadata cache for fresh registry data (audit service) */\n force?: boolean;\n\n /** Check which pnpm.overrides are still needed (audit service) */\n checkOverrides?: boolean;\n\n /** Regenerate test coverage before showing the stats summary (stats service) */\n coverage?: boolean;\n\n /** Count what the current branch changed since it left this ref, by kind of file (stats service) */\n since?: string;\n\n /** Print the `since` table as markdown for a pull request description (stats service) */\n md?: boolean;\n\n /** List every upstream migration note, not only the open ones (migrate service) */\n all?: boolean;\n\n /** Print one migration note's README (migrate service) */\n show?: string;\n\n /** Write one migration note's folder where its codemod can run (migrate service) */\n extract?: string;\n\n /** Run one migration note's codemod, keeping files identical to upstream as they are (migrate service) */\n run?: string;\n\n /** The script to run with `run`, when the note folder holds more than one (migrate service) */\n script?: string;\n\n /** Arguments after `--`, passed to the codemod as given (migrate service, with `run`) */\n runArgs?: string[];\n\n /** Migration note ids to record as handled (migrate service) */\n mark?: string[];\n}\n\n/** File status after analysis */\nexport type FileStatus =\n | 'identical' // No changes needed\n | 'ahead' // Fork is ahead, protected (pinned/ignored)\n | 'local' // Local file (never existed upstream)\n | 'drifted' // Fork is ahead, NOT protected (at risk)\n | 'behind' // Upstream has changes to sync\n | 'diverged' // Both changed, will merge\n | 'pinned' // Fork wins on conflict\n | 'ignored' // Excluded from sync entirely\n | 'deleted' // Fork deleted, will stay deleted\n | 'renamed'; // Upstream renamed file\n\n/** Statuses the sync applies changes for: a staged sync holds at least one file with one of these. */\nexport const SYNC_APPLIED_STATUSES: readonly FileStatus[] = ['behind', 'diverged', 'renamed', 'ignored', 'pinned'];\n\n/** Commit metadata for a single log entry */\nexport interface CommitRangeEntry {\n hash: string;\n message: string;\n date: string;\n}\n\n/** Analyzed file with status and metadata */\nexport interface AnalyzedFile {\n path: string;\n status: FileStatus;\n /** True if file is in ignored list */\n isIgnored: boolean;\n /** True if file is in pinned list */\n isPinned: boolean;\n /** True if file exists in fork */\n existsInFork: boolean;\n /** True if file exists in upstream */\n existsInUpstream: boolean;\n /** Relative date when file was last changed (since merge-base) */\n changedAt?: string;\n /** Unix epoch seconds of the last change, for sorting */\n changedTs?: number;\n /** Short commit hash of the last change */\n changedCommit?: string;\n /** For diverged files: relative date of upstream change */\n upstreamChangedAt?: string;\n /** For diverged files: Unix epoch seconds of the upstream change, for sorting */\n upstreamChangedTs?: number;\n /** For diverged files: short commit hash of the upstream change */\n upstreamCommit?: string;\n /** For renamed files: the original path before rename */\n renamedFrom?: string;\n /**\n * Protected (pinned/ignored) files only: both sides changed since the merge-base. The fork\n * side wins whole-file, so upstream's changes to this path are dropped by the sync.\n */\n upstreamChanged?: boolean;\n /** For `upstreamChanged` files: lines upstream changed since the merge-base (undefined for binary) */\n upstreamChangedLines?: number;\n /**\n * Ignored files only: upstream changed, added or deleted the file since the merge-base and the\n * fork did not touch it. Ignored paths never sync, so without this flag the change stays unseen\n * (new config keys, version bumps). Managed files and generated output (`isGeneratedFile`) are\n * never flagged.\n */\n upstreamOnly?: boolean;\n /**\n * Pinned `ahead` files only: lines present upstream but absent from the fork (undefined for\n * binary). Independent of the sync point, so it also shows upstream content dropped by an\n * earlier sync, or removed on purpose; only a diff can tell.\n */\n upstreamLinesAbsent?: number;\n}\n\n/** Summary counts by status */\nexport interface AnalysisSummary {\n /** Changed package/config files that are handled separately from normal sync categories */\n managed: number;\n identical: number;\n ahead: number;\n local: number;\n drifted: number;\n behind: number;\n diverged: number;\n pinned: number;\n ignored: number;\n deleted: number;\n renamed: number;\n}\n\n/** Merge result from merge-engine */\nexport interface MergeResult {\n success: boolean;\n /** Upstream branch name for file links */\n upstreamBranch?: string;\n /** Resolved concrete upstream ref that was merged (branch ref or release tag ref) */\n upstreamRef?: string;\n /** Upstream release tag synced (when tracking releases) */\n upstreamTag?: string;\n files: AnalyzedFile[];\n summary: AnalysisSummary;\n conflicts: string[];\n /** Upstream GitHub URL base for commit links */\n upstreamGitHubUrl?: string;\n /** Upstream commit info */\n upstreamCommit?: CommitRangeEntry;\n /** Commits included in this sync range (oldest-first when rendered) */\n upstreamCommits?: CommitRangeEntry[];\n /** Files that were auto-merged by git (diverged without remaining conflicts) */\n autoMergedFiles?: string[];\n /**\n * Protected (pinned/ignored) files resolved to the fork side although upstream also changed\n * them: upstream's hunks were dropped, not merged. Review each against upstream.\n */\n protectedConflicts?: string[];\n /** `protectedConflicts` grouped by the `pinned` or `ignored` entry they fall under, for one diff hint per entry. */\n protectedUpstreamChanges?: ProtectedUpstreamGroup[];\n /** Pasteable `<merge-base>..<upstream>` range of short SHAs, for `git diff` hints. */\n upstreamDiffRange?: string;\n /** How upstream's own sync config changed since the merge-base, where the fork config does not follow. */\n upstreamOverrides?: UpstreamOverridesReport;\n /** Files flagged `upstreamOnly`, grouped by the `ignored` entry they fall under (config order). */\n ignoredUpstreamChanges?: IgnoredUpstreamGroup[];\n /**\n * Upstream migration notes: how many the incoming ref holds, which ones upstream added since the\n * sync point, and how many stay open in the fork once those are added.\n */\n migrationNotes?: { total: number; arrived: string[]; open: number };\n}\n\n/** Entries of one sync config list (`pinned`, `ignored` or `packageJsonSync`) that the fork config does not mirror. */\nexport interface OverrideListChanges {\n /** Entries upstream added since the merge-base that the fork list lacks. */\n added: string[];\n /** Entries upstream removed since the merge-base that the fork list still carries. */\n removed: string[];\n}\n\n/**\n * Upstream sync config changes the fork should review. The sync config is managed (never merged),\n * so new upstream `pinned`/`ignored` entries and `packageJsonSync` keys only reach the fork by\n * hand. `unreadable` means upstream's config was missing or unparsable at one side (`base` =\n * merge-base, `incoming` = upstream ref), so nothing was compared.\n */\nexport type UpstreamOverridesReport =\n | {\n kind: 'changes';\n pinned: OverrideListChanges;\n ignored: OverrideListChanges;\n packageJsonSync: OverrideListChanges;\n }\n | { kind: 'unreadable'; side: 'base' | 'incoming' };\n\n/** Protected paths upstream also changed, under one `pinned` or `ignored` entry. */\nexport interface ProtectedUpstreamGroup {\n /** The `pinned` or `ignored` entry the paths fall under; the path itself when no entry covers it (a managed file). */\n entry: string;\n /** Paths under the entry, sorted. */\n paths: string[];\n}\n\n/** Upstream-only changes under one `ignored` entry. */\nexport interface IgnoredUpstreamGroup {\n /** The `ignored` entry (configured or derived from an app-owned module) the files fall under. */\n entry: string;\n /** Changed paths under the entry, sorted. */\n paths: string[];\n /** Paths the fork lacks (new upstream files). */\n added: number;\n /** Paths upstream deleted (the fork keeps them). */\n deleted: number;\n}\n"],"mappings":";AAKA,SAAS,SAAS;AAIlB,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA+GO,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;AAaO,IAAM,oBAAoB,EAC9B,OAAO;AAAA,EACN,UAAU,EACP,OAAO;AAAA,IACN,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC7B,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IAC3C,eAAe,EAAE,KAAK,CAAC,WAAW,QAAQ,CAAC,EAAE,SAAS;AAAA,IACtD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACxC,iBAAiB,EAAE,MAAM,EAAE,KAAK,sBAAsB,CAAC,EAAE,SAAS;AAAA,IAClE,kBAAkB,EAAE,QAAQ,EAAE,SAAS;AAAA,IACvC,cAAc,EAAE,KAAK,CAAC,UAAU,QAAQ,OAAO,CAAC,EAAE,SAAS;AAAA,EAC7D,CAAC,EACA,OAAO;AAAA,EACV,WAAW,EACR,OAAO;AAAA,IACN,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACtC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,CAAC,EACA,OAAO,EACP,SAAS;AAAA,EACZ,OAAO,EACJ;AAAA,IACC,EACG,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MAC3B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,MAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC9B,CAAC,EACA,OAAO;AAAA,EACZ,EACC,SAAS;AACd,CAAC,EACA,OAAO;","names":[]}
1
+ {"version":3,"sources":["../src/config/types.ts"],"sourcesContent":["/**\n * Configuration types: the public cella/cella.config.ts surface, its runtime\n * schema, and the internal types the services share.\n */\n\nimport { z } from 'zod';\n\n// Public API for cella/cella.config.ts.\n\nconst PACKAGE_JSON_SYNC_KEYS = [\n 'dependencies',\n 'devDependencies',\n 'peerDependencies',\n 'optionalDependencies',\n 'scripts',\n 'engines',\n 'packageManager',\n 'overrides',\n 'exports',\n 'pnpm',\n] as const;\n\n/** Valid package.json keys that can be synced */\nexport type PackageJsonSyncKey = (typeof PACKAGE_JSON_SYNC_KEYS)[number];\n\n/**\n * Sync settings: all configurable options for the sync CLI.\n * Hover over each property for documentation.\n */\nexport interface SyncSettings {\n /** Upstream repository URL (e.g., 'git@github.com:cellajs/cella.git') */\n upstreamUrl: string;\n\n /**\n * Upstream branch, used for `upstreamTrack: 'branch'` and for GitHub file links.\n * Defaults to 'main'.\n */\n upstreamBranch?: string;\n\n /**\n * How to track upstream cella. Defaults to 'release'.\n * - 'release' (default): sync to a published cella release tag (`0.18.1`, with or without `v`). Stable and\n * reviewable: each bump maps to a changelog. Uses the latest release.\n * - 'branch': follow the bleeding-edge tip of `upstreamBranch`. For cella\n * maintainers and forks doing active development on top of unreleased changes.\n */\n upstreamTrack?: 'release' | 'branch';\n\n /**\n * Trunk branch that `pnpm cella sync` cuts the temporary branch from and that you open the\n * squash-merge PR into. Defaults to 'main'. Cutting fresh from trunk each cycle keeps every\n * PR limited to that cycle's upstream delta (no accumulation) and `main` linear.\n */\n releaseBase?: string;\n\n /** Which package.json keys to sync (default: ['dependencies', 'devDependencies']). `type` always syncs. */\n packageJsonSync?: PackageJsonSyncKey[];\n\n /** Automatic package.json sync after the sync service completes (default: true). Set to false to turn it off. */\n syncWithPackages?: boolean;\n\n /**\n * How to link files in CLI output.\n * - 'commit' (default): Link to the commit that changed the file on GitHub.\n * - 'file': Link to the file in the repo at the upstream branch on GitHub.\n */\n fileLinkMode?: 'commit' | 'file';\n}\n\n/**\n * Configuration for a downstream fork repository that cella interacts with.\n *\n * Cella is the upstream/source-of-truth. For each fork it can:\n * - pull contributions FROM the fork's `pullBranch` (contributions service)\n * - run the normal temporary-branch sync flow inside the fork (forks service)\n */\nexport interface ForkConfig {\n /** Display name for the fork (also used as the contrib/<name> branch slug) */\n name: string;\n /** Local path to the fork repository (relative to this config or absolute) */\n localPath: string;\n /**\n * Git remote URL of the fork (e.g. 'git@github.com:org/fork.git').\n * When set, the contributions service fetches the fork's `pullBranch` from this\n * remote (the authoritative committed ref), so the comparison does not depend on\n * the local checkout being up to date. The local clone is still used to read the\n * fork's owned-folder territory when available.\n */\n remoteUrl?: string;\n /** Fork branch that cella pulls contributions from (contributions service) */\n pullBranch: string;\n}\n\n/** User-configurable sync options for cella/cella.config.ts. */\nexport interface CellaCliConfig {\n /** Core sync settings */\n settings: SyncSettings;\n\n /**\n * File overrides for controlling sync behavior per folder/file.\n */\n overrides?: {\n /**\n * Paths the fork fully owns: never synced (existing or new).\n * Exact paths or directory prefixes, not globs: 'bench' matches 'bench/' and\n * everything under it, 'README.md' matches that exact file.\n * Local territory: upstream cannot add, modify, or delete anything under these.\n */\n ignored?: string[];\n\n /**\n * Paths pinned to the fork: the fork copy wins whole-file.\n * Exact paths or directory prefixes, not globs: 'bench' matches 'bench/' and\n * everything under it, 'README.md' matches that exact file.\n * Upstream changes to a pinned file are dropped, not merged: analyze lists them under\n * \"protected but behind upstream\" to adopt by hand.\n * If fork deleted a pinned file, deletion is respected.\n */\n pinned?: string[];\n };\n\n /**\n * Downstream fork repositories that cella interacts with (for upstream template repos).\n * When configured, the 'forks' and 'contributions' services appear in the CLI menu.\n */\n forks?: ForkConfig[];\n}\n\n/**\n * Helper function for defining cella/cella.config.ts with type checking.\n */\nexport function defineConfig(config: CellaCliConfig): CellaCliConfig {\n return config;\n}\n\n/**\n * Strict runtime schema mirroring {@link CellaCliConfig}.\n *\n * The TS interfaces above stay the source of truth (and keep their hover docs for\n * config authors). This schema is what's enforced at load time: `.strict()` rejects\n * unknown keys, so a typo like `ignoredFolders` for `ignored` fails closed; a silent\n * fallback would drop sync protection (tsx does not typecheck the config).\n *\n * The `satisfies z.ZodType<CellaCliConfig>` assertion keeps schema and interface in\n * lockstep: if either drifts (a renamed/removed/mis-typed field), TypeScript errors here.\n */\nexport const cellaConfigSchema = z\n .object({\n settings: z\n .object({\n upstreamUrl: z.string().min(1),\n upstreamBranch: z.string().min(1).optional(),\n upstreamTrack: z.enum(['release', 'branch']).optional(),\n releaseBase: z.string().min(1).optional(),\n packageJsonSync: z.array(z.enum(PACKAGE_JSON_SYNC_KEYS)).optional(),\n syncWithPackages: z.boolean().optional(),\n fileLinkMode: z.enum(['commit', 'file']).optional(),\n })\n .strict(),\n overrides: z\n .object({\n ignored: z.array(z.string()).optional(),\n pinned: z.array(z.string()).optional(),\n })\n .strict()\n .optional(),\n forks: z\n .array(\n z\n .object({\n name: z.string().min(1),\n localPath: z.string().min(1),\n remoteUrl: z.string().optional(),\n pullBranch: z.string().min(1),\n })\n .strict(),\n )\n .optional(),\n })\n .strict() satisfies z.ZodType<CellaCliConfig>;\n\n// Internal types for the services.\n\n/** Sync services available in the CLI */\nexport type SyncService = 'analyze' | 'sync' | 'migrate' | 'audit' | 'forks' | 'contributions' | 'stats';\n\n/** Analyze output scope for interactive and machine-readable flows */\nexport type AnalyzeScope = 'all' | 'risk' | 'protected';\n\n/** Runtime configuration with all resolved values */\nexport interface RuntimeConfig extends CellaCliConfig {\n /** Resolved fork repository path */\n forkPath: string;\n\n /** Full upstream remote ref (e.g., 'cella-upstream/development') */\n upstreamRef: string;\n\n /** Selected sync service */\n service: SyncService;\n\n /** Non-interactive list output (for LLM/agent usage) */\n list: boolean;\n\n /** Machine-readable JSON output (for tooling/agent usage) */\n json: boolean;\n\n /** Scope of files returned in analyze list/json output */\n scope?: AnalyzeScope;\n\n /** Show verbose output */\n verbose: boolean;\n\n /** Pre-selected fork name (skips fork selection prompt) */\n fork?: string;\n\n /**\n * Override upstream tracking for this run (analyze/sync), ignoring `settings.upstreamTrack`.\n * 'branch' follows the upstream branch tip (bleeding edge); 'release' uses a release tag.\n */\n track?: 'release' | 'branch';\n\n /**\n * Pin the upstream ref for this run (analyze/sync), overriding `track`: a commit sha, a release\n * tag or an upstream branch name. Must be on the upstream branch or in an upstream release.\n */\n ref?: string;\n\n /**\n * Merge with the fork's sync config as it stands (sync service). Without it, a new merge stops\n * before anything changes when upstream changed its own `overrides` or `packageJsonSync` in ways\n * the fork config does not follow.\n */\n keepConfig?: boolean;\n\n /**\n * Lift every pinned entry for this run (analyze, sync): managed files stay pinned, and the merge\n * uses the full upstream history, so upstream changes that earlier syncs dropped come back too.\n */\n unpinned?: boolean;\n\n /** Count what the current branch changed since it left this ref, by kind of file (stats service) */\n since?: string;\n\n /** Print the `since` table as markdown for a pull request description (stats service) */\n md?: boolean;\n\n /** List every upstream migration note, not only the open ones (migrate service) */\n all?: boolean;\n\n /** Print one migration note's README (migrate service) */\n show?: string;\n\n /** Write one migration note's folder where its codemod can run (migrate service) */\n extract?: string;\n\n /** Run one migration note's codemod, keeping files identical to upstream as they are (migrate service) */\n run?: string;\n\n /** Arguments after `--`, passed to the codemod as given (migrate service, with `run`) */\n runArgs?: string[];\n\n /** Migration note ids to record as handled (migrate service) */\n mark?: string[];\n}\n\n/** File status after analysis */\nexport type FileStatus =\n | 'identical' // No changes needed\n | 'ahead' // Fork is ahead, protected (pinned/ignored)\n | 'local' // Local file (never existed upstream)\n | 'drifted' // Fork is ahead, NOT protected (at risk)\n | 'behind' // Upstream has changes to sync\n | 'diverged' // Both changed, will merge\n | 'pinned' // Fork wins on conflict\n | 'ignored' // Excluded from sync entirely\n | 'deleted' // Fork deleted, will stay deleted\n | 'renamed'; // Upstream renamed file\n\n/** Statuses the sync applies changes for: a staged sync holds at least one file with one of these. */\nexport const SYNC_APPLIED_STATUSES: readonly FileStatus[] = ['behind', 'diverged', 'renamed', 'ignored', 'pinned'];\n\n/** Commit metadata for a single log entry */\nexport interface CommitRangeEntry {\n hash: string;\n message: string;\n date: string;\n}\n\n/** Analyzed file with status and metadata */\nexport interface AnalyzedFile {\n path: string;\n status: FileStatus;\n /** True if file is in ignored list */\n isIgnored: boolean;\n /** True if file is in pinned list */\n isPinned: boolean;\n /** True if file exists in fork */\n existsInFork: boolean;\n /** True if file exists in upstream */\n existsInUpstream: boolean;\n /** Relative date when file was last changed (since merge-base) */\n changedAt?: string;\n /** Unix epoch seconds of the last change, for sorting */\n changedTs?: number;\n /** Short commit hash of the last change */\n changedCommit?: string;\n /** For diverged files: relative date of upstream change */\n upstreamChangedAt?: string;\n /** For diverged files: Unix epoch seconds of the upstream change, for sorting */\n upstreamChangedTs?: number;\n /** For diverged files: short commit hash of the upstream change */\n upstreamCommit?: string;\n /** For renamed files: the original path before rename */\n renamedFrom?: string;\n /**\n * Protected (pinned/ignored) files only: both sides changed since the merge-base. The fork\n * side wins whole-file, so upstream's changes to this path are dropped by the sync.\n */\n upstreamChanged?: boolean;\n /** For `upstreamChanged` files: lines upstream changed since the merge-base (undefined for binary) */\n upstreamChangedLines?: number;\n /**\n * Ignored files only: upstream changed, added or deleted the file since the merge-base and the\n * fork did not touch it. Ignored paths never sync, so without this flag the change stays unseen\n * (new config keys, version bumps). Managed files and generated output (`isGeneratedFile`) are\n * never flagged.\n */\n upstreamOnly?: boolean;\n /**\n * Pinned `ahead` files only: lines present upstream but absent from the fork (undefined for\n * binary). Independent of the sync point, so it also shows upstream content dropped by an\n * earlier sync, or removed on purpose; only a diff can tell.\n */\n upstreamLinesAbsent?: number;\n}\n\n/** Summary counts by status */\nexport interface AnalysisSummary {\n /** Changed package/config files that are handled separately from normal sync categories */\n managed: number;\n identical: number;\n ahead: number;\n local: number;\n drifted: number;\n behind: number;\n diverged: number;\n pinned: number;\n ignored: number;\n deleted: number;\n renamed: number;\n}\n\n/** Merge result from merge-engine */\nexport interface MergeResult {\n success: boolean;\n /** Upstream branch name for file links */\n upstreamBranch?: string;\n /** Resolved concrete upstream ref that was merged (branch ref or release tag ref) */\n upstreamRef?: string;\n /** Upstream release tag synced (when tracking releases) */\n upstreamTag?: string;\n files: AnalyzedFile[];\n summary: AnalysisSummary;\n conflicts: string[];\n /** Upstream GitHub URL base for commit links */\n upstreamGitHubUrl?: string;\n /** Upstream commit info */\n upstreamCommit?: CommitRangeEntry;\n /** Files that were auto-merged by git (diverged without remaining conflicts) */\n autoMergedFiles?: string[];\n /**\n * Protected (pinned/ignored) files resolved to the fork side although upstream also changed\n * them: upstream's hunks were dropped, not merged. Review each against upstream.\n */\n protectedConflicts?: string[];\n /** `protectedConflicts` grouped by the `pinned` or `ignored` entry they fall under, for one diff hint per entry. */\n protectedUpstreamChanges?: ProtectedUpstreamGroup[];\n /** Pasteable `<merge-base>..<upstream>` range of short SHAs, for `git diff` hints. */\n upstreamDiffRange?: string;\n /** How upstream's own sync config changed since the merge-base, where the fork config does not follow. */\n upstreamOverrides?: UpstreamOverridesReport;\n /** Files flagged `upstreamOnly`, grouped by the `ignored` entry they fall under (config order). */\n ignoredUpstreamChanges?: IgnoredUpstreamGroup[];\n /**\n * Upstream migration notes: how many the incoming ref holds, which ones upstream added since the\n * sync point, and how many stay open in the fork once those are added.\n */\n migrationNotes?: { total: number; arrived: string[]; open: number };\n}\n\n/** Entries of one sync config list (`pinned`, `ignored` or `packageJsonSync`) that the fork config does not mirror. */\nexport interface OverrideListChanges {\n /** Entries upstream added since the merge-base that the fork list lacks. */\n added: string[];\n /** Entries upstream removed since the merge-base that the fork list still carries. */\n removed: string[];\n}\n\n/**\n * Upstream sync config changes the fork should review. The sync config is managed (never merged),\n * so new upstream `pinned`/`ignored` entries and `packageJsonSync` keys only reach the fork by\n * hand. `unreadable` means upstream's config was missing or unparsable at one side (`base` =\n * merge-base, `incoming` = upstream ref), so nothing was compared.\n */\nexport type UpstreamOverridesReport =\n | {\n kind: 'changes';\n pinned: OverrideListChanges;\n ignored: OverrideListChanges;\n packageJsonSync: OverrideListChanges;\n }\n | { kind: 'unreadable'; side: 'base' | 'incoming' };\n\n/** Protected paths upstream also changed, under one `pinned` or `ignored` entry. */\nexport interface ProtectedUpstreamGroup {\n /** The `pinned` or `ignored` entry the paths fall under; the path itself when no entry covers it (a managed file). */\n entry: string;\n /** Paths under the entry, sorted. */\n paths: string[];\n}\n\n/** Upstream-only changes under one `ignored` entry. */\nexport interface IgnoredUpstreamGroup {\n /** The `ignored` entry (configured or derived from an app-owned module) the files fall under. */\n entry: string;\n /** Changed paths under the entry, sorted. */\n paths: string[];\n /** Paths the fork lacks (new upstream files). */\n added: number;\n /** Paths upstream deleted (the fork keeps them). */\n deleted: number;\n}\n"],"mappings":";AAKA,SAAS,SAAS;AAIlB,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA+GO,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;AAaO,IAAM,oBAAoB,EAC9B,OAAO;AAAA,EACN,UAAU,EACP,OAAO;AAAA,IACN,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC7B,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IAC3C,eAAe,EAAE,KAAK,CAAC,WAAW,QAAQ,CAAC,EAAE,SAAS;AAAA,IACtD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACxC,iBAAiB,EAAE,MAAM,EAAE,KAAK,sBAAsB,CAAC,EAAE,SAAS;AAAA,IAClE,kBAAkB,EAAE,QAAQ,EAAE,SAAS;AAAA,IACvC,cAAc,EAAE,KAAK,CAAC,UAAU,MAAM,CAAC,EAAE,SAAS;AAAA,EACpD,CAAC,EACA,OAAO;AAAA,EACV,WAAW,EACR,OAAO;AAAA,IACN,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACtC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,CAAC,EACA,OAAO,EACP,SAAS;AAAA,EACZ,OAAO,EACJ;AAAA,IACC,EACG,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MAC3B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,MAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC9B,CAAC,EACA,OAAO;AAAA,EACZ,EACC,SAAS;AACd,CAAC,EACA,OAAO;","names":[]}