@pithy-sh/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +72 -0
  3. package/scripts/templateManifest.ts +49 -0
  4. package/scripts/tsconfig.json +26 -0
  5. package/scripts/vendorTemplate.ts +84 -0
  6. package/scripts/verifyPack.ts +88 -0
  7. package/src/audit/cliAudit.ts +406 -0
  8. package/src/bin.ts +111 -0
  9. package/src/capabilities/add.ts +288 -0
  10. package/src/capabilities/addBootstrap.ts +275 -0
  11. package/src/capabilities/catalog.ts +175 -0
  12. package/src/capabilities/compose.ts +39 -0
  13. package/src/capabilities/configConstants.ts +74 -0
  14. package/src/capabilities/configImports.ts +397 -0
  15. package/src/capabilities/eject.ts +331 -0
  16. package/src/capabilities/emailProvisioner.ts +346 -0
  17. package/src/capabilities/entitlementGap.ts +70 -0
  18. package/src/capabilities/entryExports.ts +162 -0
  19. package/src/capabilities/flow.ts +550 -0
  20. package/src/capabilities/hostRegistry.ts +368 -0
  21. package/src/capabilities/loadFailure.ts +208 -0
  22. package/src/capabilities/manifests.ts +238 -0
  23. package/src/capabilities/mediaProvisioner.ts +471 -0
  24. package/src/capabilities/mintSecrets.ts +306 -0
  25. package/src/capabilities/paymentsProvisioner.ts +207 -0
  26. package/src/capabilities/prerequisites.ts +168 -0
  27. package/src/capabilities/r2Bucket.ts +113 -0
  28. package/src/capabilities/reconcile.ts +1483 -0
  29. package/src/capabilities/remove.ts +597 -0
  30. package/src/capabilities/requiredOptions.ts +92 -0
  31. package/src/capabilities/rotateSecrets.ts +305 -0
  32. package/src/capabilities/secrets.ts +178 -0
  33. package/src/capabilities/secretsDispatcher.ts +29 -0
  34. package/src/capabilities/secretsProvisioner.ts +389 -0
  35. package/src/capabilities/storageProvisioner.ts +414 -0
  36. package/src/capabilities/supportProvisioner.ts +515 -0
  37. package/src/capabilities/testersLoader.ts +52 -0
  38. package/src/capabilities/testersProvisioner.ts +236 -0
  39. package/src/capabilities/turnstileProvisioner.ts +347 -0
  40. package/src/capabilities/vectorProvisioner.ts +260 -0
  41. package/src/ci/fileModes.ts +223 -0
  42. package/src/ci/sourceFiles.ts +200 -0
  43. package/src/ci/workflowDrivers.ts +524 -0
  44. package/src/cloudflare/accountAnswer.ts +110 -0
  45. package/src/cloudflare/config.ts +685 -0
  46. package/src/cloudflare/storeId.ts +129 -0
  47. package/src/commands/add.ts +372 -0
  48. package/src/commands/alias.ts +205 -0
  49. package/src/commands/dashboard.ts +651 -0
  50. package/src/commands/deploy.ts +150 -0
  51. package/src/commands/dev.ts +37 -0
  52. package/src/commands/doctor.ts +2059 -0
  53. package/src/commands/email.ts +425 -0
  54. package/src/commands/env.ts +155 -0
  55. package/src/commands/feature.ts +359 -0
  56. package/src/commands/init.ts +538 -0
  57. package/src/commands/media.ts +303 -0
  58. package/src/commands/migrate.ts +129 -0
  59. package/src/commands/payments.ts +336 -0
  60. package/src/commands/provision.ts +368 -0
  61. package/src/commands/remove.ts +151 -0
  62. package/src/commands/secrets.ts +652 -0
  63. package/src/commands/seed.ts +229 -0
  64. package/src/commands/storage.ts +309 -0
  65. package/src/commands/support.ts +331 -0
  66. package/src/commands/testers.ts +1020 -0
  67. package/src/commands/token.ts +364 -0
  68. package/src/commands/turnstile.ts +271 -0
  69. package/src/commands/ui.ts +222 -0
  70. package/src/commands/upgrade.ts +517 -0
  71. package/src/commands/vector.ts +390 -0
  72. package/src/commands/worker.ts +295 -0
  73. package/src/dashboard/api.ts +323 -0
  74. package/src/dashboard/connect.ts +758 -0
  75. package/src/dashboard/contract.ts +289 -0
  76. package/src/dashboard/grant.ts +124 -0
  77. package/src/dashboard/registry.ts +519 -0
  78. package/src/dashboard/resolveTarget.ts +119 -0
  79. package/src/dev/delivery.ts +174 -0
  80. package/src/dev/devLogin.ts +155 -0
  81. package/src/dev/devLoginTargets.ts +91 -0
  82. package/src/dev/env.ts +206 -0
  83. package/src/dev/hostWorkers.ts +290 -0
  84. package/src/dev/keys.ts +111 -0
  85. package/src/dev/logging.ts +87 -0
  86. package/src/dev/openUrl.ts +75 -0
  87. package/src/dev/orchestrator.ts +1014 -0
  88. package/src/dev/ports.ts +220 -0
  89. package/src/dev/readyWatch.ts +142 -0
  90. package/src/dev/state.ts +90 -0
  91. package/src/devSecrets/bootstrapVars.ts +265 -0
  92. package/src/devSecrets/devVars.ts +240 -0
  93. package/src/devSecrets/edit.ts +256 -0
  94. package/src/devSecrets/file.ts +277 -0
  95. package/src/devSecrets/generate.ts +428 -0
  96. package/src/devSecrets/location.ts +80 -0
  97. package/src/devSecrets/mode.ts +71 -0
  98. package/src/devSecrets/records.ts +30 -0
  99. package/src/devSecrets/report.ts +99 -0
  100. package/src/devSecrets/seed.ts +344 -0
  101. package/src/devSecrets/store.ts +262 -0
  102. package/src/devSecrets/targets.ts +204 -0
  103. package/src/dispatch.ts +147 -0
  104. package/src/docs/catalog.ts +246 -0
  105. package/src/docs/writeCatalog.ts +45 -0
  106. package/src/doctor/cloudflare.ts +287 -0
  107. package/src/doctor/devPreferences.ts +155 -0
  108. package/src/doctor/devSecrets.ts +464 -0
  109. package/src/doctor/devVars.ts +414 -0
  110. package/src/doctor/devVarsLocal.ts +138 -0
  111. package/src/doctor/environments.ts +155 -0
  112. package/src/doctor/health.ts +354 -0
  113. package/src/doctor/localDelivery.ts +91 -0
  114. package/src/doctor/portsRegistry.ts +252 -0
  115. package/src/doctor/projectName.ts +584 -0
  116. package/src/doctor/secretBindings.ts +166 -0
  117. package/src/doctor/settings.ts +274 -0
  118. package/src/doctor/settingsSources.ts +202 -0
  119. package/src/doctor/workerName.ts +174 -0
  120. package/src/doctor/wranglerVars.ts +33 -0
  121. package/src/feature/bindings.ts +93 -0
  122. package/src/feature/create.ts +179 -0
  123. package/src/feature/destroy.ts +160 -0
  124. package/src/feature/devConfig.ts +201 -0
  125. package/src/feature/identity.ts +100 -0
  126. package/src/feature/manifest.ts +132 -0
  127. package/src/feature/ports.ts +615 -0
  128. package/src/feature/provision.ts +362 -0
  129. package/src/feature/sync.ts +148 -0
  130. package/src/feature/worktree.ts +282 -0
  131. package/src/help/groups.ts +47 -0
  132. package/src/help/rootUsage.ts +135 -0
  133. package/src/main.ts +73 -0
  134. package/src/migrations/ledger.ts +129 -0
  135. package/src/migrations/registry.ts +47 -0
  136. package/src/migrations/run.ts +1066 -0
  137. package/src/notifier/check.ts +129 -0
  138. package/src/notifier/installer.ts +48 -0
  139. package/src/notifier/notify.ts +152 -0
  140. package/src/notifier/state.ts +248 -0
  141. package/src/notifier/version.ts +59 -0
  142. package/src/platform/editor.ts +333 -0
  143. package/src/platform/rc.ts +118 -0
  144. package/src/platform/shell.ts +83 -0
  145. package/src/project/appBindings.ts +184 -0
  146. package/src/project/appWorkflows.ts +266 -0
  147. package/src/project/applyDomains.ts +166 -0
  148. package/src/project/askDomains.ts +220 -0
  149. package/src/project/atomic.ts +466 -0
  150. package/src/project/bindingEntries.ts +425 -0
  151. package/src/project/config.ts +701 -0
  152. package/src/project/dashboard.ts +118 -0
  153. package/src/project/deploy.ts +364 -0
  154. package/src/project/devVars.ts +113 -0
  155. package/src/project/domainPrompt.ts +191 -0
  156. package/src/project/domains.ts +386 -0
  157. package/src/project/envInventory.ts +356 -0
  158. package/src/project/environment.ts +125 -0
  159. package/src/project/extensions.ts +69 -0
  160. package/src/project/jsonc.ts +289 -0
  161. package/src/project/packageManager.ts +238 -0
  162. package/src/project/readOptionalFile.ts +342 -0
  163. package/src/project/rollback.ts +145 -0
  164. package/src/project/scaffold.ts +1088 -0
  165. package/src/project/templateFiles.ts +53 -0
  166. package/src/project/verifyDeploy.ts +230 -0
  167. package/src/project/versionMetadata.ts +77 -0
  168. package/src/project/workerAddress.ts +176 -0
  169. package/src/project/workerCommand.ts +564 -0
  170. package/src/project/workerIdentity.ts +50 -0
  171. package/src/project/workerManifest.ts +135 -0
  172. package/src/project/workerScaffold.ts +289 -0
  173. package/src/project/workerScope.ts +394 -0
  174. package/src/project/workers.ts +86 -0
  175. package/src/project/workflows.ts +281 -0
  176. package/src/project/wrangler.ts +168 -0
  177. package/src/provision/confirm.ts +86 -0
  178. package/src/provision/environment.ts +407 -0
  179. package/src/provision/featureConfig.ts +98 -0
  180. package/src/provision/mode.ts +62 -0
  181. package/src/provision/pendingSecrets.ts +96 -0
  182. package/src/provision/resources.ts +126 -0
  183. package/src/provision/secretBindings.ts +149 -0
  184. package/src/provision/store.ts +33 -0
  185. package/src/provision/unprovisioned.ts +114 -0
  186. package/src/provision/wranglerEnv.ts +220 -0
  187. package/src/rootFlags.ts +48 -0
  188. package/src/seed/drivers.ts +423 -0
  189. package/src/seed/media.ts +187 -0
  190. package/src/seed/plan.ts +137 -0
  191. package/src/seed/prepare.ts +224 -0
  192. package/src/seed/registry.ts +25 -0
  193. package/src/seed/run.ts +793 -0
  194. package/src/seed/safety.ts +206 -0
  195. package/src/terminal/logger.ts +42 -0
  196. package/src/terminal/output.ts +64 -0
  197. package/src/terminal/style.ts +132 -0
  198. package/src/test-utils/doctorHarness.ts +190 -0
  199. package/src/test-utils/migrateHarness.ts +126 -0
  200. package/src/test-utils/seedHarness.ts +173 -0
  201. package/src/test-utils/tempRepo.ts +45 -0
  202. package/src/tokens/config.ts +16 -0
  203. package/src/tokens/engine.ts +345 -0
  204. package/src/tokens/mintedTokens.ts +233 -0
  205. package/src/tokens/sinks.ts +84 -0
  206. package/src/ui/flow.ts +451 -0
  207. package/src/ui/react.ts +112 -0
  208. package/src/ui/routeAllowlist.ts +208 -0
  209. package/src/ui/scaffold.ts +113 -0
  210. package/src/ui/screenStyles.ts +127 -0
  211. package/src/ui/stubs.ts +135 -0
  212. package/src/ui/templates.ts +52 -0
  213. package/src/ui/wire.ts +311 -0
  214. package/src/ui/workerUi.ts +172 -0
  215. package/templates/starter/.dev.secrets.example.jsonc +43 -0
  216. package/templates/starter/.dev.vars.example +30 -0
  217. package/templates/starter/apps/api/package.json +22 -0
  218. package/templates/starter/apps/api/pithy.config.ts +65 -0
  219. package/templates/starter/apps/api/pithy.worker.jsonc +11 -0
  220. package/templates/starter/apps/api/src/bindings.workers.test.ts +18 -0
  221. package/templates/starter/apps/api/src/cloudflare-test.d.ts +11 -0
  222. package/templates/starter/apps/api/src/index.ts +8 -0
  223. package/templates/starter/apps/api/tsconfig.json +26 -0
  224. package/templates/starter/apps/api/wrangler.jsonc +68 -0
  225. package/templates/starter/biome.template.jsonc +75 -0
  226. package/templates/starter/gitignore +37 -0
  227. package/templates/starter/package.json +28 -0
  228. package/templates/starter/pithy.config.ts +67 -0
  229. package/templates/starter/plugins/no-console.grit +25 -0
  230. package/templates/starter/plugins/no-process-io.grit +25 -0
  231. package/templates/starter/tsconfig.json +14 -0
  232. package/templates/starter/tsconfig.tools.json +30 -0
  233. package/templates/starter/vitest.config.ts +124 -0
  234. package/templates/starter/vitest.workers.config.ts +26 -0
@@ -0,0 +1,200 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { type Dirent, readdirSync, readFileSync } from "node:fs";
5
+ import { join, sep } from "node:path";
6
+
7
+ /**
8
+ * The one walk over this repository's own source.
9
+ *
10
+ * Several tripwires here read every source file in the tree and assert something about the set —
11
+ * which modules can reach a `rename` (`project/atomic.test.ts`), which can probe with something that
12
+ * follows a link or run a recursive delete (`project/scaffold.test.ts`), which can resolve an editor
13
+ * (`platform/editor.test.ts`), which can export a pure value out of a Workers-runtime module
14
+ * (`capabilities/configEntrypoints.test.ts`) — and both halves of CI's own planner read every test file,
15
+ * one to work out which suites assert about which paths (`.github/scripts/crossPackageReads.ts`) and one
16
+ * to weight the shards they are dealt into (`.github/scripts/planShards.ts`).
17
+ *
18
+ * Each of those had written its own traversal, which made each one a separate place to get the same
19
+ * two things wrong. #157's was hardened when it was written and `atomic.test.ts`'s was not, so
20
+ * `atomic.test.ts` kept the bug: `ENOENT … packages/cli/.smoke-OXGbGb/pithy.config.ts` on a full-suite
21
+ * run (#185). A tripwire that flakes gets muted, and a muted tripwire is the defect it was built to
22
+ * catch, shipping.
23
+ *
24
+ * **Both halves of that failure live here, once.**
25
+ *
26
+ * 1. **The tree is not still.** Other suites scaffold whole projects into `packages/cli/.smoke-*` and
27
+ * `.e2e-*` and delete them on the way out, and `.worktrees/` holds entire second checkouts of this
28
+ * repository. A dotted directory is skipped — `.github` excepted, because its scripts are source
29
+ * this repository runs its CI on — which removes most of that outright, and a directory that
30
+ * cannot be listed and a file that vanished between the listing and the read are both skipped
31
+ * rather than fatal. A file that is not there is not a file that breaks a rule.
32
+ * `packages/cli/templates/`, which appears and disappears around `bun pm pack`, is the one that
33
+ * cannot be dotted; see {@link VENDORED_TEMPLATES}. The dotted rule is the one thing a caller may
34
+ * turn off — `dotted: true`, off by default, for the caller asking about *shipped files* rather than
35
+ * about this tree's source; see {@link SourceWalk.dotted} (#215).
36
+ * 2. **A symlink is not descended.** `withFileTypes` reports a link as a link rather than as the
37
+ * directory behind it, so a walk cannot loop on a link to an ancestor or read a package twice
38
+ * through the `node_modules` entry that points at it.
39
+ *
40
+ * Synchronous on purpose. It is read-only, it is called from tests and from the two CI scripts that run
41
+ * before `bun install`, and the async form bought a sequential `await` per directory rather than any
42
+ * concurrency. This module imports nothing but `node:fs` and `node:path` for the same reason: the
43
+ * `plan` job in `ci.yml` has no install step, so its whole import graph has to be builtins and relative
44
+ * paths. Adding a package dependency here breaks both scripts at once and is a change to that job.
45
+ *
46
+ * **That this is the only walk is a gate, not a claim.** #185 said it in a changeset and it was not true —
47
+ * five private traversals were never migrated, and none of them received the ENOENT tolerance above or
48
+ * #192's `templates` exclusion (#202). `sourceFiles.test.ts` now fails the build on any module that defines
49
+ * a function which lists a directory and calls itself, with the handful that cannot reach this one written
50
+ * down by name and reason. That list is now only the ones that *cannot*: `planShards.ts` was the last that
51
+ * merely had not been, and its `statSync` was the #185 race sitting in the script the whole matrix hangs
52
+ * off (#211).
53
+ *
54
+ * **The comment stripper these gates read with is no longer here.** `blankComments` was written beside
55
+ * this walk (#437) and moved to `@pithy-sh/core/src/text/comments` (#439), because
56
+ * `packages/core/src/worker-safety.test.ts` needs it and `@pithy-sh/core` must not depend on
57
+ * `@pithy-sh/cli`. Its own docblock carries the reasoning. Nothing in this module uses it, so the import
58
+ * graph above is unchanged: builtins and relative paths, still loadable by the `plan` job.
59
+ */
60
+
61
+ /** A file the walk found, with the text it still held when the walk read it. */
62
+ export interface SourceFile {
63
+ /** Absolute path to the file. */
64
+ readonly path: string;
65
+ /** Its contents at the moment it was read. */
66
+ readonly text: string;
67
+ }
68
+
69
+ /** How a walk narrows the tree — and, in one case, widens it. */
70
+ export interface SourceWalk {
71
+ /** Directory names never descended into, on top of the built-in set. */
72
+ readonly skip?: readonly string[];
73
+ /** Which files to keep, by base name. Defaults to {@link isShippedSource}. */
74
+ readonly keep?: (name: string) => boolean;
75
+ /**
76
+ * Enter dotted directories as well. **Off unless a caller says otherwise**, because the rule it lifts
77
+ * is what keeps `.smoke-*`, `.e2e-*` and `.worktrees/` out of every other caller (#185).
78
+ *
79
+ * For the caller whose question is about *shipped files* rather than about this repository's source: a
80
+ * license audit asks that every file a template carries has the right header, and a template that grew
81
+ * a `.vscode/` or a `.husky/` would ship every file in it unchecked. A gate whose reach is narrower
82
+ * than the rule it enforces under-reports in silence (#215).
83
+ *
84
+ * It widens the dotted rule and nothing else. `node_modules`, `dist`, `coverage`, whatever the caller
85
+ * named in `skip`, the vendored template copy and a symlinked directory are all still refused, and
86
+ * `keep` still decides which files are taken.
87
+ *
88
+ * **It has no caller in this repository, deliberately, and it stays (#222).** The caller it was built
89
+ * for is `tooling/license-headers`, which cannot import `@pithy-sh/cli` — #211 declined that edge on
90
+ * direction of narrowing, since the linter that stamps this package's own headers running in
91
+ * `lint-staged` must not become a dependent of the largest thing it lints. What the option buys is not
92
+ * a call site. It is that the exception recorded against that walk in `./sourceFiles.test.ts` states a
93
+ * true reason: #202's entry named the `templates` skip as the blocker and #211 found that false, and
94
+ * the real blocker it recorded in its place — this walker cannot enter a dotted directory, and the
95
+ * license audit must — would be false in the other direction if this were removed. An exception list
96
+ * whose reasons have quietly stopped being true is the failure mode #211 corrected, and removing the
97
+ * option to re-add it with the edge would cost the same work twice. One branch, asserted where it is.
98
+ */
99
+ readonly dotted?: boolean;
100
+ }
101
+
102
+ /**
103
+ * Never walked: dependencies, build output, coverage. Every other exclusion is the dotted rule, which
104
+ * covers `.git`, `.turbo`, `.changeset`, `.worktrees`, and the test scaffolds this exists for.
105
+ */
106
+ const NEVER = ["node_modules", "dist", "coverage"];
107
+
108
+ /** The one dotted directory that holds source: this repository's CI scripts. */
109
+ const DOTTED_SOURCE = ".github";
110
+
111
+ /**
112
+ * The one transient the dotted rule cannot cover: `packages/cli/templates`, the copy of the repo root's
113
+ * `templates/starter` that `prepack` vendors in and `postpack` takes out again.
114
+ *
115
+ * It cannot be dotted and it cannot move. `files` in the CLI's manifest carries exactly this path, and
116
+ * that is the entire mechanism by which a published `@pithy-sh/cli` ships a starter at all (#143, #152).
117
+ * So the walk skips it by where it is instead — by path, never by name, because the repo root's
118
+ * `templates/` is the source of truth these tripwires exist to read.
119
+ *
120
+ * **Skipping is right whether or not a pack is in flight.** It is a file-by-file copy of a directory the
121
+ * same walk already visits at the repo root, so descending into it can only ever report a source twice,
122
+ * under a second path that `postpack` is about to delete — and a pack that fails after `prepack` leaves
123
+ * the copy behind for good, gitignored and silent, which makes the duplicate permanent rather than
124
+ * transient. Either way a gate that reports a path, counts files, or asserts a set gets a different
125
+ * answer depending on what a packer did, and a report naming the copy names a file nobody can open (#192).
126
+ */
127
+ const VENDORED_TEMPLATES = join("packages", "cli", "templates");
128
+
129
+ /** A `.ts` file that ships — neither a test nor a generated declaration. */
130
+ export function isShippedSource(name: string): boolean {
131
+ return name.endsWith(".ts") && !name.endsWith(".test.ts") && !name.endsWith(".d.ts");
132
+ }
133
+
134
+ /** A test file, in every spelling this repository uses — `x.test.ts` and `x.workers.test.ts` alike. */
135
+ export function isTestFile(name: string): boolean {
136
+ return name.endsWith(".test.ts");
137
+ }
138
+
139
+ /** A walk with every default resolved, so {@link descend} decides nothing for itself. */
140
+ interface Walk {
141
+ /** Directory names never descended into: the built-in set and the caller's own. */
142
+ readonly skip: ReadonlySet<string>;
143
+ /** Which files to keep, by base name. */
144
+ readonly keep: (name: string) => boolean;
145
+ /** Whether a dotted directory is entered. See {@link SourceWalk.dotted}. */
146
+ readonly dotted: boolean;
147
+ }
148
+
149
+ /** Every file under `root` that `keep` accepts, absolute and sorted. A root that is not there is empty. */
150
+ export function sourcePaths(root: string, options: SourceWalk = {}): string[] {
151
+ const walk: Walk = {
152
+ skip: new Set([...NEVER, ...(options.skip ?? [])]),
153
+ keep: options.keep ?? isShippedSource,
154
+ dotted: options.dotted ?? false,
155
+ };
156
+ const found: string[] = [];
157
+ descend(root, walk, found);
158
+ return found.sort();
159
+ }
160
+
161
+ /** `path`'s contents, or null if it is no longer there — or was never readable. */
162
+ export function readSource(path: string): string | null {
163
+ try {
164
+ return readFileSync(path, "utf8");
165
+ } catch {
166
+ return null;
167
+ }
168
+ }
169
+
170
+ /** Every file {@link sourcePaths} finds, with its text. One that vanished before the read is dropped. */
171
+ export function sourceFiles(root: string, options?: SourceWalk): SourceFile[] {
172
+ const found: SourceFile[] = [];
173
+ for (const path of sourcePaths(root, options)) {
174
+ const text = readSource(path);
175
+ if (text !== null) found.push({ path, text });
176
+ }
177
+ return found;
178
+ }
179
+
180
+ /** One directory, and everything below it. A directory that cannot be listed contributes nothing. */
181
+ function descend(directory: string, walk: Walk, into: string[]): void {
182
+ let entries: Dirent[];
183
+ try {
184
+ entries = readdirSync(directory, { withFileTypes: true });
185
+ } catch {
186
+ return;
187
+ }
188
+ for (const entry of entries) {
189
+ const path = join(directory, entry.name);
190
+ if (entry.isDirectory()) {
191
+ if (walk.skip.has(entry.name)) continue;
192
+ if (!walk.dotted && entry.name.startsWith(".") && entry.name !== DOTTED_SOURCE) continue;
193
+ // Whatever root the walk began at, the path it built carries the ancestry that identifies the copy.
194
+ if (path === VENDORED_TEMPLATES || path.endsWith(`${sep}${VENDORED_TEMPLATES}`)) continue;
195
+ descend(path, walk, into);
196
+ continue;
197
+ }
198
+ if (entry.isFile() && walk.keep(entry.name)) into.push(path);
199
+ }
200
+ }