@anvil-works/anvil-cli 0.8.0-canary.21 → 0.8.0-canary.22

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
@@ -135,11 +135,43 @@ Useful options:
135
135
 
136
136
  - `-O, --open` open the app folder after checkout
137
137
  - `-b, --branch <BRANCH>` check out a specific branch
138
+ - `--git-url <GIT_URL>` use a separate Git server
138
139
  - `-Q, --query <QUERY>` prefill the interactive search
139
140
  - `-u, --url <ANVIL_URL>` choose the Anvil installation explicitly
140
141
  - `-U, --user <USERNAME>` choose the logged-in account explicitly
141
142
  - `-f, --force` override destination safety checks
142
143
 
144
+ ### `anvil create`
145
+
146
+ Create a blank Anvil app and check it out locally. Without a name, the CLI prompts for one. The server supplies current Python 3 runtime defaults.
147
+
148
+ ```bash
149
+ anvil create "My App"
150
+ anvil create "My App" ./my-app --tag internal sales
151
+ anvil create "My App" --directory my-app --url anvil.works --user me@example.com
152
+ anvil create "My App" --no-checkout --tag internal sales
153
+ ```
154
+
155
+ Useful options:
156
+
157
+ - `-d, --directory <PATH>` choose the local directory (defaults to the app name with spaces replaced by underscores)
158
+ - `--no-checkout` create only the remote app and print its ID and editor URL
159
+ - `--tag <TAG...>` add space-separated tags or repeat the option; place after the name and destination
160
+ - `-u, --url <ANVIL_URL>` choose the Anvil installation
161
+ - `-U, --user <USERNAME>` choose the logged-in account
162
+ - `--git-url <GIT_URL>` use a separate Git server
163
+ - `-O, --open` open the checkout after creation
164
+
165
+ App names need quotes when they contain spaces. Leading and trailing whitespace is removed; the remaining name is preserved. Supply the destination as the second argument or with `--directory`, but not both. The destination must be empty and outside an existing Git repository. These checks run before creating the remote app.
166
+
167
+ With `--no-checkout`, no local directory is created or checked. It cannot be combined with a destination argument, `--directory`, `--git-url`, or `--open`; these combinations fail before login or creation. JSON output includes the app ID, name, server, account, tags, and `editorUrl`, without checkout fields.
168
+
169
+ Tags are combined, trimmed, lowercased, and deduplicated. An app can have at most 20 unique tags, each containing 1 to 50 letters, digits, hyphens, or underscores.
170
+
171
+ Server and account selection follow `checkout`, including interactive selection and login when needed. In scripts, supply the name and use `--url` and `--user` when the selection is ambiguous. `--json` disables prompts.
172
+
173
+ If creation succeeds but checkout fails, the error identifies the created app and explains how to recover it. Do not rerun `create`, which would create another app. JSON errors include the created app details in `data.created`. Failure to open an editor after checkout produces a warning and preserves the successful result.
174
+
143
175
  ### `anvil watch`
144
176
 
145
177
  Keep your local app folder synced with Anvil while you work.
package/dist/api.d.ts CHANGED
@@ -6,10 +6,12 @@ export { WatchSession };
6
6
  export type { WatchDiagnosticEventName, WatchDiagnosticEventPayload, WatchSessionEvents } from "./WatchSession";
7
7
  export { branchFromEnvironmentVersion, readEnvironmentPid, requireEnvironmentBranch, writeEnvironmentPid, } from "./environment";
8
8
  export type { AnvilEnvironmentBinding, AnvilEnvironmentVersion, EnvBranchChangeMode } from "./environment";
9
- export { AppIdCandidate, AppIdWithContext, CheckoutAppListItem, detectAppIdsByCommitLookup, detectAppIdsFromAllRemotes, filterCandidates, formatCandidateLabel, getGitFetchUrl, getGitPushUrl, getLatestVersion, getWebSocketUrl, listAppsForCheckout, lookupRemoteInfoForAppId, lookupByCommit, saveUpdates, ValidateAppIdResponse, validateAppId, } from "./services/anvil-api";
9
+ export { AppIdCandidate, AppIdWithContext, CheckoutAppListItem, CreatedAnvilApp, createAnvilApp, detectAppIdsByCommitLookup, detectAppIdsFromAllRemotes, filterCandidates, formatCandidateLabel, getGitFetchUrl, getGitPushUrl, getLatestVersion, getWebSocketUrl, listAppsForCheckout, lookupRemoteInfoForAppId, lookupByCommit, saveUpdates, ValidateAppIdResponse, validateAppId, } from "./services/anvil-api";
10
10
  export { ANVIL_SYNC_CLIENT_ID, getAccountsForUrl, getAvailableAnvilUrls, getValidAuthToken, GetValidAuthTokenOptions, hasTokensForUrl, REFRESH_REQUEST_TIMEOUT_MS, verifyAndStoreTokens, LoginResult, LogoutResult, logout, TokenData, clearInMemoryTokens, setInMemoryTokens, verifyAuth, } from "./services/auth";
11
11
  export { DeviceAuthorizationResponse, OAuthTokenResponse, pollDeviceAuthorization, requestDeviceAuthorization, } from "./services/oauth-login";
12
12
  export { CheckoutCloneOptions, CheckoutExecutionDeps, CheckoutOptions, CheckoutResult, executeCheckout, getDefaultDestinationDirectory, isDirectoryNonEmpty, isPathInsideGitRepo, parseCheckoutInput, ParsedCheckoutInput, sanitizeDirectoryName, validateCheckoutDestination, } from "./commands/checkout";
13
+ export { executeCreate, CreateCheckoutError } from "./commands/create";
14
+ export type { CreateExecutionDeps, CreateOptions, CreateResult, RemoteCreateResult, CreatedAppDetails } from "./commands/create";
13
15
  export { createCheckoutPickerSource, type CheckoutPickerDeps, type CheckoutPickerSourceController, type CheckoutPickerSourceOptions, } from "./commands/checkout-picker";
14
16
  export { buildGitAuthDoctorReport, formatGitAuthDoctorReport, inspectCredentialHelperCommand, parseCredentialHelperCommand, } from "./commands/gitAuth";
15
17
  export type { CredentialFillResult, GitAuthDoctorAppReport, GitAuthDoctorFinding, GitAuthDoctorRemote, GitAuthDoctorReport, GitAuthDoctorStatus, GitCredentialHelperDetails, GitCredentialSimulation, InspectCredentialHelperOptions, } from "./commands/gitAuth";
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -12875,12 +12875,25 @@ var __webpack_exports__ = {};
12875
12875
  if (!urlInput || "string" != typeof urlInput) return urlInput;
12876
12876
  let url = urlInput.trim();
12877
12877
  url = url.replace(/\/+$/, "");
12878
- if ("localhost" === url || url.startsWith("localhost:")) return "http://localhost:3000";
12879
- if ("http://localhost" === url || url.startsWith("http://localhost:")) return "http://localhost:3000";
12880
- if ("https://localhost" === url || url.startsWith("https://localhost:")) return "http://localhost:3000";
12881
- if (/^https?:\/\//.test(url)) return url;
12878
+ if ("localhost" === url) return "http://localhost:3000";
12879
+ if (url.startsWith("localhost:")) return `http://${url}`;
12880
+ if (/^https?:\/\//i.test(url)) return url;
12882
12881
  return `https://${url}`;
12883
12882
  }
12883
+ function normalizeAnvilOrigin(input) {
12884
+ try {
12885
+ const raw = input.trim();
12886
+ const normalized = normalizeAnvilUrl(raw);
12887
+ const url = new URL(raw.includes("://") ? raw : normalized);
12888
+ if (![
12889
+ "http:",
12890
+ "https:"
12891
+ ].includes(url.protocol) || url.username || url.password || "/" !== url.pathname || url.search || url.hash) throw new Error("Invalid origin");
12892
+ return normalized;
12893
+ } catch {
12894
+ throw new Error("Server URL must be an HTTP(S) origin without credentials, a path, query, or fragment.");
12895
+ }
12896
+ }
12884
12897
  function resolveAnvilUrl() {
12885
12898
  const fromConfig = getConfig("anvilUrl");
12886
12899
  if ("string" == typeof fromConfig && fromConfig.trim()) return fromConfig.trim();
@@ -12904,6 +12917,9 @@ var __webpack_exports__ = {};
12904
12917
  function getGlobalOutputConfig() {
12905
12918
  return globalOutputConfig;
12906
12919
  }
12920
+ function canPrompt() {
12921
+ return !globalOutputConfig.jsonMode && !!(process.stdin.isTTY && process.stdout.isTTY);
12922
+ }
12907
12923
  function assertCanPrompt(action = "This command", explicitAlternative = "Pass explicit flags instead.") {
12908
12924
  if (globalOutputConfig.jsonMode) throw new Error(`${action} requires interactive input, but --json disables prompts. ${explicitAlternative}`);
12909
12925
  if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error(`${action} requires interactive input, but stdin/stdout is not a TTY. ${explicitAlternative}`);
@@ -14751,6 +14767,39 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
14751
14767
  function anvil_api_getDefaultAnvilUrl() {
14752
14768
  return resolveAnvilUrl();
14753
14769
  }
14770
+ async function createAnvilApp(options) {
14771
+ let response;
14772
+ try {
14773
+ response = await fetch(`${options.anvilUrl}/ide/api/_/apps`, {
14774
+ method: "POST",
14775
+ headers: {
14776
+ Authorization: `Bearer ${options.authToken}`,
14777
+ "Content-Type": "application/json"
14778
+ },
14779
+ body: JSON.stringify({
14780
+ name: options.name,
14781
+ tags: options.tags
14782
+ })
14783
+ });
14784
+ } catch (error) {
14785
+ throw errors_createNetworkError.network(error.message);
14786
+ }
14787
+ const data = await response.json().catch(()=>({}));
14788
+ if (!response.ok) {
14789
+ if (401 === response.status || 403 === response.status) throw errors_createAuthError.invalid(data.error || "Not authorized to create an app");
14790
+ throw new Error(data.error || `Failed to create app: ${response.status} ${response.statusText}`);
14791
+ }
14792
+ if ("string" != typeof data.id || !data.id) throw new Error("App creation response did not contain an app ID.");
14793
+ return {
14794
+ id: data.id,
14795
+ ..."string" == typeof data.name ? {
14796
+ name: data.name
14797
+ } : {},
14798
+ ...data.tags ? {
14799
+ tags: data.tags
14800
+ } : {}
14801
+ };
14802
+ }
14754
14803
  async function validateAppId(appId, anvilUrl = anvil_api_getDefaultAnvilUrl(), username) {
14755
14804
  const authToken = await auth_getValidAuthToken(anvilUrl, username);
14756
14805
  try {
@@ -21288,7 +21337,7 @@ print(json.dumps({"issues": issues}))
21288
21337
  value: null
21289
21338
  });
21290
21339
  return logger_logger.select("Multiple logged-in Anvil URLs found. Which one would you like to use?", choices, decision.urls[0], {
21291
- action: "`anvil checkout` URL selection",
21340
+ action: "Anvil server selection",
21292
21341
  nonInteractiveHint: `Use --url <ANVIL_URL>. Available URLs: ${decision.urls.join(", ")}.`
21293
21342
  });
21294
21343
  }
@@ -21367,8 +21416,8 @@ print(json.dumps({"issues": issues}))
21367
21416
  name: "Cancel",
21368
21417
  value: null
21369
21418
  });
21370
- return logger_logger.select(`Multiple accounts found for ${anvilUrl}. Which account should be used for checkout?`, choices, accounts[0], {
21371
- action: "`anvil checkout` account selection",
21419
+ return logger_logger.select(`Multiple accounts found for ${anvilUrl}. Which account should be used?`, choices, accounts[0], {
21420
+ action: "Anvil account selection",
21372
21421
  nonInteractiveHint: `Use --user <USERNAME>. Available accounts: ${accounts.join(", ")}.`
21373
21422
  });
21374
21423
  }
@@ -21387,7 +21436,7 @@ print(json.dumps({"issues": issues}))
21387
21436
  logger_logger.verbose(external_chalk_default().cyan("Resolved app ID: ") + external_chalk_default().bold(parsed.appId));
21388
21437
  const anvilUrl = await resolveCheckoutUrlForApi(options.anvilUrl, parsed.detectedUrl);
21389
21438
  if (!anvilUrl) throw new Error("Anvil URL is required. Use --url <ANVIL_URL> or pass an input URL containing the host.");
21390
- const gitUrl = options.gitUrl ?? anvilUrl;
21439
+ const gitUrl = void 0 === options.gitUrl ? anvilUrl : normalizeAnvilOrigin(options.gitUrl);
21391
21440
  const resolvedUsername = await resolveCheckoutUsernameForApi(anvilUrl, options.user);
21392
21441
  if (resolvedUsername) logger_logger.verbose(external_chalk_default().cyan("Using account: ") + external_chalk_default().bold(resolvedUsername));
21393
21442
  else logger_logger.verbose(external_chalk_default().cyan("No account preselected; resolving after auth token lookup."));
@@ -21498,7 +21547,7 @@ print(json.dumps({"issues": issues}))
21498
21547
  await openPathInEditorOrDefault(destinationPath, preferredEditorCommand, deps);
21499
21548
  }
21500
21549
  function registerCheckoutCommand(program) {
21501
- const checkoutCommand = program.command("checkout [input] [directory]").description("Check out an Anvil app locally from editor URL, git URL, app ID, or interactive selection").alias("co").option("-O, --open", "Open destination after checkout").option("-b, --branch <BRANCH>", "Checkout a specific branch").option("--depth <N>", "Create a shallow clone with history truncated to N commits", (value)=>parseInt(value, 10)).option("--single-branch", "Clone only one branch").option("--origin <NAME>", "Use a custom remote name instead of origin").option("--quiet", "Suppress git clone progress output").option("--verbose", "Enable verbose git clone output").option("-u, --url <ANVIL_URL>", "Specify Anvil server URL").option("-U, --user <USERNAME>", "Specify which user account to use").option("-f, --force", "Override safety checks for destination path").option("-Q, --query <QUERY>", "Initial search query for interactive checkout picker").action(async (input, directory, options, command)=>{
21550
+ const checkoutCommand = program.command("checkout [input] [directory]").description("Check out an Anvil app locally from editor URL, git URL, app ID, or interactive selection").alias("co").option("-O, --open", "Open destination after checkout").option("-b, --branch <BRANCH>", "Checkout a specific branch").option("--depth <N>", "Create a shallow clone with history truncated to N commits", (value)=>parseInt(value, 10)).option("--single-branch", "Clone only one branch").option("--origin <NAME>", "Use a custom remote name instead of origin").option("--quiet", "Suppress git clone progress output").option("--verbose", "Enable verbose git clone output").option("-u, --url <ANVIL_URL>", "Specify Anvil server URL").option("--git-url <GIT_URL>", "Git server URL, if separate from the Anvil server").option("-U, --user <USERNAME>", "Specify which user account to use").option("-f, --force", "Override safety checks for destination path").option("-Q, --query <QUERY>", "Initial search query for interactive checkout picker").action(async (input, directory, options, command)=>{
21502
21551
  try {
21503
21552
  const globalOptions = command?.optsWithGlobals() || options || {};
21504
21553
  if ("number" == typeof options?.depth && (!Number.isFinite(options.depth) || options.depth <= 0)) throw new Error("--depth must be a positive integer");
@@ -21513,6 +21562,7 @@ print(json.dumps({"issues": issues}))
21513
21562
  quiet: options?.quiet,
21514
21563
  verbose: globalOptions.verbose,
21515
21564
  anvilUrl: options?.url,
21565
+ gitUrl: options?.gitUrl,
21516
21566
  user: options?.user,
21517
21567
  force: options?.force,
21518
21568
  query: options?.query
@@ -21524,6 +21574,229 @@ print(json.dumps({"issues": issues}))
21524
21574
  });
21525
21575
  checkoutCommand.addHelpText("after", "\n" + external_chalk_default().bold("Examples:") + '\n anvil checkout http://localhost:3000/build/apps/APPID/code/assets/theme.css\n anvil checkout https://anvil.works/git/APPID.git\n anvil checkout APPID --url anvil.works\n anvil checkout APPID --branch master --depth 1 --single-branch\n anvil checkout APPID -O # open editor/file browser after checkout\n anvil checkout APPID my-local-folder --force\n anvil checkout # interactive search/select app list\n anvil checkout -Q "dashboard" # preseed picker search\n');
21526
21576
  }
21577
+ class CreateCheckoutError extends Error {
21578
+ created;
21579
+ constructor(message, created, options){
21580
+ super(message, options), this.created = created;
21581
+ this.name = "CreateCheckoutError";
21582
+ }
21583
+ }
21584
+ const create_defaultDeps = {
21585
+ getAccountsForUrl: auth_getAccountsForUrl,
21586
+ getValidAuthToken: auth_getValidAuthToken,
21587
+ createApp: createAnvilApp,
21588
+ checkout: executeCheckout
21589
+ };
21590
+ function validateCheckoutOptions(options) {
21591
+ if (false === options.checkout && (void 0 !== options.directory || void 0 !== options.gitUrl || options.open)) throw new Error("--no-checkout cannot be combined with a destination argument, --directory, --git-url, or --open.");
21592
+ }
21593
+ async function validateCreateInput(options) {
21594
+ validateCheckoutOptions(options);
21595
+ const name = options.name.trim();
21596
+ if (!name) throw new Error("App name is required.");
21597
+ const tags = void 0 === options.tags ? void 0 : [
21598
+ ...new Set(options.tags.map((tag)=>tag.trim().toLowerCase()))
21599
+ ];
21600
+ if (tags && (tags.length > 20 || tags.some((tag)=>tag.length > 50 || !/^[a-z0-9_-]+$/.test(tag)))) throw new Error("Use at most 20 unique tags, each 1–50 characters: letters, numbers, hyphens, or underscores.");
21601
+ if (false === options.checkout) return {
21602
+ name,
21603
+ tags,
21604
+ destinationPath: void 0
21605
+ };
21606
+ const directory = options.directory ?? sanitizeDirectoryName(name);
21607
+ if (!directory) throw new Error("App name cannot be used as a directory. Pass --directory <PATH>.");
21608
+ const destinationPath = external_path_default().resolve(directory);
21609
+ await validateCheckoutDestination(destinationPath);
21610
+ return {
21611
+ name,
21612
+ tags,
21613
+ destinationPath
21614
+ };
21615
+ }
21616
+ async function executeCreate(options, deps = create_defaultDeps) {
21617
+ const { name, tags, destinationPath } = await validateCreateInput(options);
21618
+ const anvilUrl = normalizeAnvilOrigin(options.anvilUrl ?? await resolveCheckoutUrlForApi() ?? "");
21619
+ const gitUrl = void 0 === options.gitUrl ? void 0 : normalizeAnvilOrigin(options.gitUrl);
21620
+ const accounts = options.user ? [] : await deps.getAccountsForUrl(anvilUrl);
21621
+ const username = options.user ?? accounts[0];
21622
+ if (!username) throw new Error(`Not logged in to ${anvilUrl}. Run 'anvil login ${anvilUrl}' and retry.`);
21623
+ if (!options.user && accounts.length > 1) throw new Error(`Multiple accounts found for ${anvilUrl}: ${accounts.join(", ")}. Use --user <USERNAME>.`);
21624
+ const authToken = await deps.getValidAuthToken(anvilUrl, username);
21625
+ const created = await deps.createApp({
21626
+ name,
21627
+ anvilUrl,
21628
+ authToken,
21629
+ ...tags ? {
21630
+ tags
21631
+ } : {}
21632
+ });
21633
+ if (void 0 === destinationPath) return {
21634
+ appId: created.id,
21635
+ appName: created.name,
21636
+ anvilUrl,
21637
+ username,
21638
+ tags: created.tags ?? tags ?? [],
21639
+ editorUrl: `${anvilUrl}/build/apps/${encodeURIComponent(created.id)}`
21640
+ };
21641
+ try {
21642
+ const checkout = await deps.checkout({
21643
+ input: created.id,
21644
+ directory: destinationPath,
21645
+ anvilUrl,
21646
+ ...gitUrl ? {
21647
+ gitUrl
21648
+ } : {},
21649
+ user: username
21650
+ });
21651
+ return {
21652
+ ...checkout,
21653
+ tags: created.tags ?? tags ?? []
21654
+ };
21655
+ } catch (error) {
21656
+ const details = {
21657
+ appId: created.id,
21658
+ appName: created.name,
21659
+ anvilUrl,
21660
+ gitUrl,
21661
+ destinationPath,
21662
+ username,
21663
+ tags: created.tags ?? tags ?? []
21664
+ };
21665
+ const retry = buildShellCommandLine([
21666
+ "anvil",
21667
+ "checkout",
21668
+ created.id,
21669
+ destinationPath,
21670
+ "--url",
21671
+ anvilUrl,
21672
+ "--user",
21673
+ username,
21674
+ ...gitUrl ? [
21675
+ "--git-url",
21676
+ gitUrl
21677
+ ] : []
21678
+ ]);
21679
+ const remainingFiles = await isDirectoryNonEmpty(destinationPath).catch(()=>true);
21680
+ const recovery = remainingFiles ? `Inspect the existing checkout at ${destinationPath} before retrying. For Git authentication problems, run ${buildShellCommandLine([
21681
+ "anvil",
21682
+ "git-auth",
21683
+ "doctor",
21684
+ "--repo",
21685
+ destinationPath
21686
+ ])}.` : `Retry checkout with: ${retry}`;
21687
+ const message = errors_getErrorMessage(error).replaceAll(authToken, "[REDACTED]").replaceAll(encodeURIComponent(authToken), "[REDACTED]");
21688
+ throw new CreateCheckoutError(`Created app ${created.id} at ${anvilUrl}, but checkout failed: ${message}. Do not rerun create. ${recovery}`, details, {
21689
+ cause: error
21690
+ });
21691
+ }
21692
+ }
21693
+ async function resolveCreateAccountInteractive(anvilUrl, options) {
21694
+ const user = await resolveCheckoutUsername(anvilUrl, options.user);
21695
+ if (null === user) return null;
21696
+ try {
21697
+ await auth_getValidAuthToken(anvilUrl, user);
21698
+ return user;
21699
+ } catch (error) {
21700
+ const loginNeeded = isAnvilError(error) && ([
21701
+ "auth_required",
21702
+ "auth_expired",
21703
+ "auth_invalid"
21704
+ ].includes(error.type) || "token_refresh_failed" === error.type && [
21705
+ 400,
21706
+ 401,
21707
+ 403
21708
+ ].includes(error.status ?? 0));
21709
+ if (!loginNeeded) throw error;
21710
+ if (!canPrompt()) throw new Error(`${errors_getErrorMessage(error)} Run 'anvil login ${anvilUrl}' and retry.`, {
21711
+ cause: error
21712
+ });
21713
+ if (!await logger_logger.confirm(`${errors_getErrorMessage(error)} Log in to ${anvilUrl} now?`, true)) return null;
21714
+ const login = await (options.login ?? runInteractiveLoginFlow)(anvilUrl);
21715
+ if (user && login.email !== user) throw new Error(`Logged in as ${login.email}, but the selected account is ${user}. No app was created.`);
21716
+ return login.email;
21717
+ }
21718
+ }
21719
+ function registerCreateCommand(program, deps = {
21720
+ executeCreate
21721
+ }) {
21722
+ program.command("create [name] [directory]").description("Create a new Anvil app and check it out locally").option("--no-checkout", "Create the app without a local checkout").option("-d, --directory <PATH>", "Local directory for the new app").option("--tag <TAG...>", "App tags (space-separated or repeated; place after name and directory)", (tag, tags)=>[
21723
+ ...tags,
21724
+ tag
21725
+ ], []).option("-u, --url <ANVIL_URL>", "Anvil server URL").option("-U, --user <USERNAME>", "Logged-in account to create the app").option("--git-url <GIT_URL>", "Git server URL, if separate from the Anvil server").option("-O, --open", "Open the new app directory after checkout").action(async (name, directory, options)=>{
21726
+ try {
21727
+ if (void 0 !== directory && void 0 !== options.directory) throw new Error("Pass the directory once, either as an argument or with --directory.");
21728
+ validateCheckoutOptions({
21729
+ ...options,
21730
+ directory: directory ?? options.directory
21731
+ });
21732
+ if (void 0 === name) {
21733
+ assertCanPrompt("`anvil create` without a name", "Pass a name: anvil create <NAME>.");
21734
+ const answer = await logger_logger.prompt([
21735
+ {
21736
+ type: "input",
21737
+ name: "name",
21738
+ message: "App name",
21739
+ validate: (value)=>value.trim() ? true : "App name is required."
21740
+ }
21741
+ ]);
21742
+ name = answer.name;
21743
+ }
21744
+ const input = await validateCreateInput({
21745
+ name,
21746
+ directory: directory ?? options.directory,
21747
+ tags: options.tag,
21748
+ checkout: options.checkout
21749
+ });
21750
+ const explicitUrl = void 0 === options.url ? void 0 : normalizeAnvilOrigin(options.url);
21751
+ const gitUrl = void 0 === options.gitUrl ? void 0 : normalizeAnvilOrigin(options.gitUrl);
21752
+ const selectedUrl = await resolveCheckoutUrl(explicitUrl);
21753
+ if (!selectedUrl) return void logger_logger.info("Create cancelled.");
21754
+ const anvilUrl = normalizeAnvilOrigin(selectedUrl);
21755
+ const user = await resolveCreateAccountInteractive(anvilUrl, {
21756
+ user: options.user,
21757
+ login: deps.login
21758
+ });
21759
+ if (null === user) return void logger_logger.info("Create cancelled.");
21760
+ const result = await deps.executeCreate({
21761
+ name: input.name,
21762
+ directory: input.destinationPath,
21763
+ tags: input.tags,
21764
+ anvilUrl,
21765
+ ...false === options.checkout ? {
21766
+ checkout: false
21767
+ } : {},
21768
+ ...gitUrl ? {
21769
+ gitUrl
21770
+ } : {},
21771
+ user
21772
+ });
21773
+ if (options.open && "destinationPath" in result) {
21774
+ const preferredEditor = String(getConfig("preferredEditor") || "").trim();
21775
+ try {
21776
+ await (deps.openPath ?? checkout_openPathInEditorOrDefault)(result.destinationPath, preferredEditor ? getPreferredEditorCommand(preferredEditor) : void 0);
21777
+ } catch (error) {
21778
+ logger_logger.warn(`App created and checked out at ${result.destinationPath}, but opening it failed: ${errors_getErrorMessage(error)}`);
21779
+ }
21780
+ }
21781
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(true, {
21782
+ data: result
21783
+ });
21784
+ else logger_logger.success("destinationDisplay" in result ? `Created ${result.appName ?? result.appId} (${result.appId}) in ${result.destinationDisplay}` : `Created ${result.appName ?? result.appId} (${result.appId}) at ${result.editorUrl}`);
21785
+ } catch (error) {
21786
+ const message = errors_getErrorMessage(error);
21787
+ if (getGlobalOutputConfig().jsonMode) logJsonResult(false, {
21788
+ error: message,
21789
+ ...error instanceof CreateCheckoutError ? {
21790
+ data: {
21791
+ created: error.created
21792
+ }
21793
+ } : {}
21794
+ });
21795
+ else logger_logger.error(`Error: ${message}`);
21796
+ process.exitCode = 1;
21797
+ }
21798
+ });
21799
+ }
21527
21800
  const defaultGitAuthDoctorDeps = {
21528
21801
  getAppAuthBinding: getAppAuthBinding,
21529
21802
  getAccountsForUrl: auth_getAccountsForUrl,
@@ -24693,6 +24966,7 @@ Examples:
24693
24966
  });
24694
24967
  const watchCommand = registerWatchCommand(program);
24695
24968
  registerCheckoutCommand(program);
24969
+ registerCreateCommand(program);
24696
24970
  registerGitAuthCommand(program);
24697
24971
  registerGitCredentialCommand(program);
24698
24972
  registerLoginCommand(program);
@@ -78,6 +78,7 @@ export declare function parseCheckoutInput(input: string): ParsedCheckoutInput;
78
78
  export declare function sanitizeDirectoryName(name: string): string;
79
79
  export declare function getDefaultDestinationDirectory(appId: string, appName?: string): string;
80
80
  export declare function resolveCheckoutUrl(explicitUrl?: string, parsedUrl?: string): Promise<string | null>;
81
+ export declare function resolveCheckoutUrlForApi(explicitUrl?: string, parsedUrl?: string): Promise<string | null>;
81
82
  export declare function isPathInsideGitRepo(targetPath: string): Promise<boolean>;
82
83
  export declare function isDirectoryNonEmpty(destinationPath: string): Promise<boolean>;
83
84
  export declare function validateCheckoutDestination(destinationPath: string, force?: boolean): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { Command } from "commander";
2
+ import { createAnvilApp } from "../services/anvil-api";
3
+ import { getAccountsForUrl, getValidAuthToken } from "../services/auth";
4
+ import { runInteractiveLoginFlow } from "../services/oauth-login";
5
+ import { openPathInEditorOrDefault, type CheckoutOptions, type CheckoutResult } from "./checkout";
6
+ export interface CreateOptions {
7
+ name: string;
8
+ directory?: string;
9
+ anvilUrl?: string;
10
+ gitUrl?: string;
11
+ user?: string;
12
+ tags?: string[];
13
+ checkout?: boolean;
14
+ }
15
+ export interface RemoteCreateResult {
16
+ appId: string;
17
+ appName?: string;
18
+ anvilUrl: string;
19
+ username: string;
20
+ tags: string[];
21
+ editorUrl: string;
22
+ }
23
+ export type CreateResult = (CheckoutResult & {
24
+ tags?: string[];
25
+ }) | RemoteCreateResult;
26
+ export interface CreatedAppDetails {
27
+ appId: string;
28
+ appName?: string;
29
+ anvilUrl: string;
30
+ gitUrl?: string;
31
+ destinationPath: string;
32
+ username: string;
33
+ tags: string[];
34
+ }
35
+ /** Creation succeeded; callers should recover this app rather than create another. */
36
+ export declare class CreateCheckoutError extends Error {
37
+ readonly created: CreatedAppDetails;
38
+ constructor(message: string, created: CreatedAppDetails, options?: ErrorOptions);
39
+ }
40
+ export interface CreateExecutionDeps {
41
+ getAccountsForUrl: typeof getAccountsForUrl;
42
+ getValidAuthToken: typeof getValidAuthToken;
43
+ createApp: typeof createAnvilApp;
44
+ checkout: (options: CheckoutOptions) => Promise<CheckoutResult>;
45
+ }
46
+ export declare function executeCreate(options: CreateOptions, deps?: CreateExecutionDeps): Promise<CreateResult>;
47
+ export declare function registerCreateCommand(program: Command, deps?: {
48
+ executeCreate: typeof executeCreate;
49
+ openPath?: typeof openPathInEditorOrDefault;
50
+ login?: typeof runInteractiveLoginFlow;
51
+ }): void;
52
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,EAAE,cAAc,EAAwB,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAGH,yBAAyB,EAMzB,KAAK,eAAe,EACpB,KAAK,cAAc,EACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,cAAc,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAAG,kBAAkB,CAAC;AAEvF,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,sFAAsF;AACtF,qBAAa,mBAAoB,SAAQ,KAAK;aACG,OAAO,EAAE,iBAAiB;gBAA3D,OAAO,EAAE,MAAM,EAAkB,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,YAAY;CAIlG;AAED,MAAM,WAAW,mBAAmB;IAChC,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,SAAS,EAAE,OAAO,cAAc,CAAC;IACjC,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACnE;AAsCD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,GAAE,mBAAiC,GAAG,OAAO,CAAC,YAAY,CAAC,CAoD1H;AA8BD,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE;IACF,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,yBAAyB,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,uBAAuB,CAAC;CACtB,GACtB,IAAI,CA2EN"}
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export { registerWatchCommand } from "./watch";
6
6
  export { registerCheckoutCommand } from "./checkout";
7
+ export { registerCreateCommand } from "./create";
7
8
  export { registerGitCredentialCommand } from "./gitCredential";
8
9
  export { registerGitAuthCommand } from "./gitAuth";
9
10
  export { registerLoginCommand } from "./login";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC"}
package/dist/config.d.ts CHANGED
@@ -31,10 +31,12 @@ export declare function getAllConfig(): Record<string, any>;
31
31
  * - "https://anvil.works" -> "https://anvil.works" (unchanged)
32
32
  */
33
33
  export declare function normalizeAnvilUrl(urlInput: string): string;
34
+ /** Validate server origins before operations that create remote state. */
35
+ export declare function normalizeAnvilOrigin(input: string): string;
34
36
  /**
35
37
  * Detect Anvil URL and username from git remotes in the repository.
36
38
  * Returns the base URL (without /git/APPID.git) and username if found.
37
- * Uses normalizeAnvilUrl to ensure proper protocol (http for localhost, https for others).
39
+ * Uses normalizeAnvilUrl to add a protocol when one is omitted.
38
40
  * SSH URLs may contain URL-encoded usernames (e.g., stu%40anvil.works = stu@anvil.works).
39
41
  */
40
42
  export declare function detectAnvilUrlFromRemotes(repoPath: string): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,OAAO,EAIH,gBAAgB,EAChB,KAAK,aAAa,EACrB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,gBAAgB,qEAAsE,CAAC;AACpG,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAWhE,QAAA,MAAM,kBAAkB,gEAAiE,CAAC;AAC1F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGpE,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAuDD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE1C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAa9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAalC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAiDjE;AAED,wBAAgB,qBAAqB,IAAI,SAAS,iBAAiB,EAAE,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CA2BnE;AAED,wBAAgB,yBAAyB,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAS9E;AA+BD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CA0CjG;AAED,wBAAgB,4BAA4B,IAAI,eAAe,EAAE,CAEhE;AAED,wBAAgB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4B1D;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA8BpH;AAED,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,KAAK,aAAa,EAAE,CAAC;AAI3E,wBAAgB,eAAe,IAAI,MAAM,CAcxC;AAID,wBAAgB,SAAS,IAAI,OAAO,CASnC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,OAAO,EAIH,gBAAgB,EAChB,KAAK,aAAa,EACrB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,gBAAgB,qEAAsE,CAAC;AACpG,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAWhE,QAAA,MAAM,kBAAkB,gEAAiE,CAAC;AAC1F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGpE,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAuDD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE1C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAa9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAalC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAiDjE;AAED,wBAAgB,qBAAqB,IAAI,SAAS,iBAAiB,EAAE,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CA2BnE;AAED,wBAAgB,yBAAyB,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAS9E;AA+BD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CA0CjG;AAED,wBAAgB,4BAA4B,IAAI,eAAe,EAAE,CAEhE;AAED,wBAAgB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyB1D;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA8BpH;AAED,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,KAAK,aAAa,EAAE,CAAC;AAI3E,wBAAgB,eAAe,IAAI,MAAM,CAcxC;AAID,wBAAgB,SAAS,IAAI,OAAO,CASnC"}
package/dist/index.js CHANGED
@@ -7373,6 +7373,7 @@ var __webpack_exports__ = {};
7373
7373
  AppIdWithContext: ()=>anvil_api_namespaceObject.AppIdWithContext,
7374
7374
  inspectCredentialHelperCommand: ()=>inspectCredentialHelperCommand,
7375
7375
  executeCheckout: ()=>executeCheckout,
7376
+ executeCreate: ()=>executeCreate,
7376
7377
  validateCheckoutDestination: ()=>validateCheckoutDestination,
7377
7378
  DeviceAuthorizationResponse: ()=>oauth_login_namespaceObject.DeviceAuthorizationResponse,
7378
7379
  OAuthTokenResponse: ()=>oauth_login_namespaceObject.OAuthTokenResponse,
@@ -7446,7 +7447,9 @@ var __webpack_exports__ = {};
7446
7447
  setInMemoryTokens: ()=>setInMemoryTokens,
7447
7448
  validateAppId: ()=>anvil_api_validateAppId,
7448
7449
  pollDeviceAuthorization: ()=>pollDeviceAuthorization,
7450
+ createAnvilApp: ()=>createAnvilApp,
7449
7451
  getValidAuthToken: ()=>auth_getValidAuthToken,
7452
+ CreatedAnvilApp: ()=>anvil_api_namespaceObject.CreatedAnvilApp,
7450
7453
  watch: ()=>src_api_watch,
7451
7454
  deleteConfig: ()=>deleteConfig,
7452
7455
  installModelTokenHelperScript: ()=>installModelTokenHelperScript,
@@ -7462,11 +7465,12 @@ var __webpack_exports__ = {};
7462
7465
  CheckoutResult: ()=>checkout_namespaceObject.CheckoutResult,
7463
7466
  ParsedCheckoutInput: ()=>checkout_namespaceObject.ParsedCheckoutInput,
7464
7467
  parseCredentialHelperCommand: ()=>parseCredentialHelperCommand,
7465
- MODEL_TOKEN_LOCK_TIMEOUT_MS: ()=>MODEL_TOKEN_LOCK_TIMEOUT_MS,
7468
+ CreateCheckoutError: ()=>CreateCheckoutError,
7466
7469
  GetValidAuthTokenOptions: ()=>auth_namespaceObject.GetValidAuthTokenOptions,
7467
- clearInMemoryTokens: ()=>clearInMemoryTokens,
7470
+ MODEL_TOKEN_LOCK_TIMEOUT_MS: ()=>MODEL_TOKEN_LOCK_TIMEOUT_MS,
7468
7471
  getDefaultDestinationDirectory: ()=>getDefaultDestinationDirectory,
7469
7472
  AUTH_FILE_LOCK_DEFAULTS: ()=>AUTH_FILE_LOCK_DEFAULTS,
7473
+ clearInMemoryTokens: ()=>clearInMemoryTokens,
7470
7474
  lookupByCommit: ()=>lookupByCommit,
7471
7475
  AppIdCandidate: ()=>anvil_api_namespaceObject.AppIdCandidate,
7472
7476
  verifyAuth: ()=>auth_verifyAuth
@@ -7483,6 +7487,7 @@ var __webpack_exports__ = {};
7483
7487
  P$: ()=>config_isCommandAvailable,
7484
7488
  n: ()=>config_isDevMode,
7485
7489
  Wj: ()=>config_isTestMode,
7490
+ Wc: ()=>config_normalizeAnvilOrigin,
7486
7491
  Vl: ()=>config_normalizeAnvilUrl,
7487
7492
  PW: ()=>parseConfigSetValue,
7488
7493
  cx: ()=>preferredEditors,
@@ -7511,6 +7516,7 @@ var __webpack_exports__ = {};
7511
7516
  var anvil_api_namespaceObject = {};
7512
7517
  __webpack_require__.r(anvil_api_namespaceObject);
7513
7518
  __webpack_require__.d(anvil_api_namespaceObject, {
7519
+ gr: ()=>createAnvilApp,
7514
7520
  lx: ()=>anvil_api_detectAppIdsByCommitLookup,
7515
7521
  NZ: ()=>anvil_api_detectAppIdsFromAllRemotes,
7516
7522
  rZ: ()=>anvil_api_filterCandidates,
@@ -7553,6 +7559,7 @@ var __webpack_exports__ = {};
7553
7559
  A9: ()=>isDirectoryNonEmpty,
7554
7560
  oU: ()=>isPathInsideGitRepo,
7555
7561
  Qx: ()=>parseCheckoutInput,
7562
+ B6: ()=>resolveCheckoutUrlForApi,
7556
7563
  KV: ()=>sanitizeDirectoryName,
7557
7564
  Bc: ()=>validateCheckoutDestination
7558
7565
  });
@@ -13109,12 +13116,25 @@ var __webpack_exports__ = {};
13109
13116
  if (!urlInput || "string" != typeof urlInput) return urlInput;
13110
13117
  let url = urlInput.trim();
13111
13118
  url = url.replace(/\/+$/, "");
13112
- if ("localhost" === url || url.startsWith("localhost:")) return "http://localhost:3000";
13113
- if ("http://localhost" === url || url.startsWith("http://localhost:")) return "http://localhost:3000";
13114
- if ("https://localhost" === url || url.startsWith("https://localhost:")) return "http://localhost:3000";
13115
- if (/^https?:\/\//.test(url)) return url;
13119
+ if ("localhost" === url) return "http://localhost:3000";
13120
+ if (url.startsWith("localhost:")) return `http://${url}`;
13121
+ if (/^https?:\/\//i.test(url)) return url;
13116
13122
  return `https://${url}`;
13117
13123
  }
13124
+ function config_normalizeAnvilOrigin(input) {
13125
+ try {
13126
+ const raw = input.trim();
13127
+ const normalized = config_normalizeAnvilUrl(raw);
13128
+ const url = new URL(raw.includes("://") ? raw : normalized);
13129
+ if (![
13130
+ "http:",
13131
+ "https:"
13132
+ ].includes(url.protocol) || url.username || url.password || "/" !== url.pathname || url.search || url.hash) throw new Error("Invalid origin");
13133
+ return normalized;
13134
+ } catch {
13135
+ throw new Error("Server URL must be an HTTP(S) origin without credentials, a path, query, or fragment.");
13136
+ }
13137
+ }
13118
13138
  function resolveAnvilUrl() {
13119
13139
  const fromConfig = config_getConfig("anvilUrl");
13120
13140
  if ("string" == typeof fromConfig && fromConfig.trim()) return fromConfig.trim();
@@ -14774,6 +14794,39 @@ Promise.resolve()
14774
14794
  function anvil_api_getDefaultAnvilUrl() {
14775
14795
  return resolveAnvilUrl();
14776
14796
  }
14797
+ async function createAnvilApp(options) {
14798
+ let response;
14799
+ try {
14800
+ response = await fetch(`${options.anvilUrl}/ide/api/_/apps`, {
14801
+ method: "POST",
14802
+ headers: {
14803
+ Authorization: `Bearer ${options.authToken}`,
14804
+ "Content-Type": "application/json"
14805
+ },
14806
+ body: JSON.stringify({
14807
+ name: options.name,
14808
+ tags: options.tags
14809
+ })
14810
+ });
14811
+ } catch (error) {
14812
+ throw createNetworkError.network(error.message);
14813
+ }
14814
+ const data = await response.json().catch(()=>({}));
14815
+ if (!response.ok) {
14816
+ if (401 === response.status || 403 === response.status) throw createAuthError.invalid(data.error || "Not authorized to create an app");
14817
+ throw new Error(data.error || `Failed to create app: ${response.status} ${response.statusText}`);
14818
+ }
14819
+ if ("string" != typeof data.id || !data.id) throw new Error("App creation response did not contain an app ID.");
14820
+ return {
14821
+ id: data.id,
14822
+ ..."string" == typeof data.name ? {
14823
+ name: data.name
14824
+ } : {},
14825
+ ...data.tags ? {
14826
+ tags: data.tags
14827
+ } : {}
14828
+ };
14829
+ }
14777
14830
  async function anvil_api_validateAppId(appId, anvilUrl = anvil_api_getDefaultAnvilUrl(), username) {
14778
14831
  const authToken = await auth_getValidAuthToken(anvilUrl, username);
14779
14832
  try {
@@ -20166,6 +20219,18 @@ print(json.dumps({"issues": issues}))
20166
20219
  }
20167
20220
  throw new Error("Device login expired before it was approved.");
20168
20221
  }
20222
+ function quoteForPosixShell(value) {
20223
+ if ("" === value) return "''";
20224
+ return `'${value.replace(/'/g, "'\"'\"'")}'`;
20225
+ }
20226
+ function quoteForCmdShell(value) {
20227
+ const escaped = value.replace(/[%^&|<>()"!]/g, "^$&");
20228
+ return `"${escaped}"`;
20229
+ }
20230
+ function buildShellCommandLine(tokens) {
20231
+ if ("win32" === process.platform) return tokens.map(quoteForCmdShell).join(" ");
20232
+ return tokens.map(quoteForPosixShell).join(" ");
20233
+ }
20169
20234
  const CHECKOUT_ERROR_VALUE = "__ERROR__";
20170
20235
  function isAbortLikeError(error) {
20171
20236
  if (error instanceof Error && "AbortError" === error.name) return true;
@@ -20344,6 +20409,122 @@ print(json.dumps({"issues": issues}))
20344
20409
  }
20345
20410
  require("inquirer");
20346
20411
  require("ora");
20412
+ class CreateCheckoutError extends Error {
20413
+ created;
20414
+ constructor(message, created, options){
20415
+ super(message, options), this.created = created;
20416
+ this.name = "CreateCheckoutError";
20417
+ }
20418
+ }
20419
+ const create_defaultDeps = {
20420
+ getAccountsForUrl: auth_getAccountsForUrl,
20421
+ getValidAuthToken: auth_getValidAuthToken,
20422
+ createApp: createAnvilApp,
20423
+ checkout: executeCheckout
20424
+ };
20425
+ function validateCheckoutOptions(options) {
20426
+ if (false === options.checkout && (void 0 !== options.directory || void 0 !== options.gitUrl || options.open)) throw new Error("--no-checkout cannot be combined with a destination argument, --directory, --git-url, or --open.");
20427
+ }
20428
+ async function validateCreateInput(options) {
20429
+ validateCheckoutOptions(options);
20430
+ const name = options.name.trim();
20431
+ if (!name) throw new Error("App name is required.");
20432
+ const tags = void 0 === options.tags ? void 0 : [
20433
+ ...new Set(options.tags.map((tag)=>tag.trim().toLowerCase()))
20434
+ ];
20435
+ if (tags && (tags.length > 20 || tags.some((tag)=>tag.length > 50 || !/^[a-z0-9_-]+$/.test(tag)))) throw new Error("Use at most 20 unique tags, each 1–50 characters: letters, numbers, hyphens, or underscores.");
20436
+ if (false === options.checkout) return {
20437
+ name,
20438
+ tags,
20439
+ destinationPath: void 0
20440
+ };
20441
+ const directory = options.directory ?? sanitizeDirectoryName(name);
20442
+ if (!directory) throw new Error("App name cannot be used as a directory. Pass --directory <PATH>.");
20443
+ const destinationPath = external_path_default().resolve(directory);
20444
+ await validateCheckoutDestination(destinationPath);
20445
+ return {
20446
+ name,
20447
+ tags,
20448
+ destinationPath
20449
+ };
20450
+ }
20451
+ async function executeCreate(options, deps = create_defaultDeps) {
20452
+ const { name, tags, destinationPath } = await validateCreateInput(options);
20453
+ const anvilUrl = config_normalizeAnvilOrigin(options.anvilUrl ?? await resolveCheckoutUrlForApi() ?? "");
20454
+ const gitUrl = void 0 === options.gitUrl ? void 0 : config_normalizeAnvilOrigin(options.gitUrl);
20455
+ const accounts = options.user ? [] : await deps.getAccountsForUrl(anvilUrl);
20456
+ const username = options.user ?? accounts[0];
20457
+ if (!username) throw new Error(`Not logged in to ${anvilUrl}. Run 'anvil login ${anvilUrl}' and retry.`);
20458
+ if (!options.user && accounts.length > 1) throw new Error(`Multiple accounts found for ${anvilUrl}: ${accounts.join(", ")}. Use --user <USERNAME>.`);
20459
+ const authToken = await deps.getValidAuthToken(anvilUrl, username);
20460
+ const created = await deps.createApp({
20461
+ name,
20462
+ anvilUrl,
20463
+ authToken,
20464
+ ...tags ? {
20465
+ tags
20466
+ } : {}
20467
+ });
20468
+ if (void 0 === destinationPath) return {
20469
+ appId: created.id,
20470
+ appName: created.name,
20471
+ anvilUrl,
20472
+ username,
20473
+ tags: created.tags ?? tags ?? [],
20474
+ editorUrl: `${anvilUrl}/build/apps/${encodeURIComponent(created.id)}`
20475
+ };
20476
+ try {
20477
+ const checkout = await deps.checkout({
20478
+ input: created.id,
20479
+ directory: destinationPath,
20480
+ anvilUrl,
20481
+ ...gitUrl ? {
20482
+ gitUrl
20483
+ } : {},
20484
+ user: username
20485
+ });
20486
+ return {
20487
+ ...checkout,
20488
+ tags: created.tags ?? tags ?? []
20489
+ };
20490
+ } catch (error) {
20491
+ const details = {
20492
+ appId: created.id,
20493
+ appName: created.name,
20494
+ anvilUrl,
20495
+ gitUrl,
20496
+ destinationPath,
20497
+ username,
20498
+ tags: created.tags ?? tags ?? []
20499
+ };
20500
+ const retry = buildShellCommandLine([
20501
+ "anvil",
20502
+ "checkout",
20503
+ created.id,
20504
+ destinationPath,
20505
+ "--url",
20506
+ anvilUrl,
20507
+ "--user",
20508
+ username,
20509
+ ...gitUrl ? [
20510
+ "--git-url",
20511
+ gitUrl
20512
+ ] : []
20513
+ ]);
20514
+ const remainingFiles = await isDirectoryNonEmpty(destinationPath).catch(()=>true);
20515
+ const recovery = remainingFiles ? `Inspect the existing checkout at ${destinationPath} before retrying. For Git authentication problems, run ${buildShellCommandLine([
20516
+ "anvil",
20517
+ "git-auth",
20518
+ "doctor",
20519
+ "--repo",
20520
+ destinationPath
20521
+ ])}.` : `Retry checkout with: ${retry}`;
20522
+ const message = errors_getErrorMessage(error).replaceAll(authToken, "[REDACTED]").replaceAll(encodeURIComponent(authToken), "[REDACTED]");
20523
+ throw new CreateCheckoutError(`Created app ${created.id} at ${anvilUrl}, but checkout failed: ${message}. Do not rerun create. ${recovery}`, details, {
20524
+ cause: error
20525
+ });
20526
+ }
20527
+ }
20347
20528
  const defaultGitAuthDoctorDeps = {
20348
20529
  getAppAuthBinding: git_auth_getAppAuthBinding,
20349
20530
  getAccountsForUrl: auth_getAccountsForUrl,
@@ -20945,7 +21126,7 @@ print(json.dumps({"issues": issues}))
20945
21126
  logger_logger.verbose(external_chalk_default().cyan("Resolved app ID: ") + external_chalk_default().bold(parsed.appId));
20946
21127
  const anvilUrl = await resolveCheckoutUrlForApi(options.anvilUrl, parsed.detectedUrl);
20947
21128
  if (!anvilUrl) throw new Error("Anvil URL is required. Use --url <ANVIL_URL> or pass an input URL containing the host.");
20948
- const gitUrl = options.gitUrl ?? anvilUrl;
21129
+ const gitUrl = void 0 === options.gitUrl ? anvilUrl : config_normalizeAnvilOrigin(options.gitUrl);
20949
21130
  const resolvedUsername = await resolveCheckoutUsernameForApi(anvilUrl, options.user);
20950
21131
  if (resolvedUsername) logger_logger.verbose(external_chalk_default().cyan("Using account: ") + external_chalk_default().bold(resolvedUsername));
20951
21132
  else logger_logger.verbose(external_chalk_default().cyan("No account preselected; resolving after auth token lookup."));
@@ -21185,6 +21366,8 @@ exports.CheckoutCloneOptions = __webpack_exports__.CheckoutCloneOptions;
21185
21366
  exports.CheckoutExecutionDeps = __webpack_exports__.CheckoutExecutionDeps;
21186
21367
  exports.CheckoutOptions = __webpack_exports__.CheckoutOptions;
21187
21368
  exports.CheckoutResult = __webpack_exports__.CheckoutResult;
21369
+ exports.CreateCheckoutError = __webpack_exports__.CreateCheckoutError;
21370
+ exports.CreatedAnvilApp = __webpack_exports__.CreatedAnvilApp;
21188
21371
  exports.DeviceAuthorizationResponse = __webpack_exports__.DeviceAuthorizationResponse;
21189
21372
  exports.FormTemplateValidationResult = __webpack_exports__.FormTemplateValidationResult;
21190
21373
  exports.GetValidAuthTokenOptions = __webpack_exports__.GetValidAuthTokenOptions;
@@ -21208,6 +21391,7 @@ exports.branchFromEnvironmentVersion = __webpack_exports__.branchFromEnvironment
21208
21391
  exports.buildGitAuthDoctorReport = __webpack_exports__.buildGitAuthDoctorReport;
21209
21392
  exports.checkUncommittedChanges = __webpack_exports__.checkUncommittedChanges;
21210
21393
  exports.clearInMemoryTokens = __webpack_exports__.clearInMemoryTokens;
21394
+ exports.createAnvilApp = __webpack_exports__.createAnvilApp;
21211
21395
  exports.createCheckoutPickerSource = __webpack_exports__.createCheckoutPickerSource;
21212
21396
  exports.createWatchDiagnostic = __webpack_exports__.createWatchDiagnostic;
21213
21397
  exports.createWatchDiagnosticFromMessage = __webpack_exports__.createWatchDiagnosticFromMessage;
@@ -21215,6 +21399,7 @@ exports.deleteConfig = __webpack_exports__.deleteConfig;
21215
21399
  exports.detectAppIdsByCommitLookup = __webpack_exports__.detectAppIdsByCommitLookup;
21216
21400
  exports.detectAppIdsFromAllRemotes = __webpack_exports__.detectAppIdsFromAllRemotes;
21217
21401
  exports.executeCheckout = __webpack_exports__.executeCheckout;
21402
+ exports.executeCreate = __webpack_exports__.executeCreate;
21218
21403
  exports.executeGitCredentialOperation = __webpack_exports__.executeGitCredentialOperation;
21219
21404
  exports.executeModelTokenOperation = __webpack_exports__.executeModelTokenOperation;
21220
21405
  exports.filterCandidates = __webpack_exports__.filterCandidates;
@@ -21288,6 +21473,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
21288
21473
  "CheckoutExecutionDeps",
21289
21474
  "CheckoutOptions",
21290
21475
  "CheckoutResult",
21476
+ "CreateCheckoutError",
21477
+ "CreatedAnvilApp",
21291
21478
  "DeviceAuthorizationResponse",
21292
21479
  "FormTemplateValidationResult",
21293
21480
  "GetValidAuthTokenOptions",
@@ -21311,6 +21498,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
21311
21498
  "buildGitAuthDoctorReport",
21312
21499
  "checkUncommittedChanges",
21313
21500
  "clearInMemoryTokens",
21501
+ "createAnvilApp",
21314
21502
  "createCheckoutPickerSource",
21315
21503
  "createWatchDiagnostic",
21316
21504
  "createWatchDiagnosticFromMessage",
@@ -21318,6 +21506,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
21318
21506
  "detectAppIdsByCommitLookup",
21319
21507
  "detectAppIdsFromAllRemotes",
21320
21508
  "executeCheckout",
21509
+ "executeCreate",
21321
21510
  "executeGitCredentialOperation",
21322
21511
  "executeModelTokenOperation",
21323
21512
  "filterCandidates",
@@ -1 +1 @@
1
- {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiCpC,OAAO,EAAyD,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAiC3G,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAoKF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAO7F;AAmLD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,EAAE,CAezE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwFzD;AAiBD,wBAAgB,YAAY,IAAI,OAAO,CAqGtC"}
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC,OAAO,EAAyD,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAiC3G,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAoKF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAO7F;AAmLD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,EAAE,CAezE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwFzD;AAiBD,wBAAgB,YAAY,IAAI,OAAO,CAsGtC"}
@@ -21,6 +21,17 @@ export interface ListAppsResponse {
21
21
  apps: CheckoutAppListItem[];
22
22
  next_cursor: string | null;
23
23
  }
24
+ export interface CreatedAnvilApp {
25
+ id: string;
26
+ name?: string;
27
+ tags?: string[];
28
+ }
29
+ export declare function createAnvilApp(options: {
30
+ name: string;
31
+ anvilUrl: string;
32
+ authToken: string;
33
+ tags?: string[];
34
+ }): Promise<CreatedAnvilApp>;
24
35
  export interface SaveRequestPayload {
25
36
  edit_session: string;
26
37
  save_sequence: number;
@@ -1 +1 @@
1
- {"version":3,"file":"anvil-api.d.ts","sourceRoot":"","sources":["../../src/services/anvil-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anvil-api.d.ts","sourceRoot":"","sources":["../../src/services/anvil-api.ts"],"names":[],"mappings":"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"}
@@ -4,5 +4,6 @@ export interface OpenPathDeps {
4
4
  spawnShellCommand: (commandLine: string) => Promise<void>;
5
5
  }
6
6
  export declare function parseCommandTokens(command: string): string[];
7
+ export declare function buildShellCommandLine(tokens: string[]): string;
7
8
  export declare function openPathInEditorOrDefault(targetPath: string, preferredEditorCommand?: string, deps?: OpenPathDeps): Promise<void>;
8
9
  //# sourceMappingURL=path-open.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-open.d.ts","sourceRoot":"","sources":["../../src/services/path-open.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,iBAAiB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAuBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA6D5D;AA6BD,wBAAsB,yBAAyB,CAC3C,UAAU,EAAE,MAAM,EAClB,sBAAsB,CAAC,EAAE,MAAM,EAC/B,IAAI,GAAE,YAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
1
+ {"version":3,"file":"path-open.d.ts","sourceRoot":"","sources":["../../src/services/path-open.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,iBAAiB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAuBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA6D5D;AAcD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAK9D;AAUD,wBAAsB,yBAAyB,CAC3C,UAAU,EAAE,MAAM,EAClB,sBAAsB,CAAC,EAAE,MAAM,EAC/B,IAAI,GAAE,YAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvil-works/anvil-cli",
3
- "version": "0.8.0-canary.21",
3
+ "version": "0.8.0-canary.22",
4
4
  "description": "CLI tool for developing Anvil apps locally",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/api.d.ts",