@alumbwe/anvil 1.0.49 → 1.0.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alumbwe/anvil",
3
- "version": "1.0.49",
3
+ "version": "1.0.51",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,7 +4,7 @@
4
4
  * This file is generated by scripts/prebuild-agents.ts
5
5
  * It contains all bundled agent definitions from the agents/ directory.
6
6
  *
7
- * Generated at: 2026-11-01T15:44:55.857Z
7
+ * Generated at: 2026-11-01T17:04:31.434Z
8
8
  * Agent count: 80
9
9
  */
10
10
 
package/src/index.tsx CHANGED
@@ -220,24 +220,27 @@ async function main(): Promise<void> {
220
220
 
221
221
  const isLoginCommand = command === 'login'
222
222
  const isPublishCommand = command === 'publish'
223
- const hasAgentOverride = Boolean(agent?.trim())
224
-
225
- await initializeApp({ cwd })
223
+ const hasAgentOverride = Boolean(agent?.trim())
224
+
225
+ // Login is intentionally independent of project initialization. It must
226
+ // work from any directory and must not create project state before auth.
227
+ if (isLoginCommand) {
228
+ await runPlainLogin()
229
+ return
230
+ }
231
+
232
+ await initializeApp({ cwd })
226
233
 
227
234
  // Load .env.local into process.env so API keys are available at runtime.
228
235
  // This replaces the old --env=inline build flag — keys are no longer baked
229
236
  // into the binary.
230
- loadEnvLocal()
237
+ if (!isManagedGatewayMode()) {
238
+ loadEnvLocal()
239
+ }
231
240
 
232
241
  // Set the auth token for the API client
233
242
  setApiClientAuthToken(getAuthToken())
234
243
 
235
- // Handle login command before rendering the app
236
- if (isLoginCommand) {
237
- await runPlainLogin()
238
- return
239
- }
240
-
241
244
  // Handle setup command (or first-run key wizard)
242
245
  const isSetupCommand = command === 'setup'
243
246
  if (isSetupCommand) {
@@ -5,9 +5,8 @@ import { cyan, green, red, yellow, bold } from 'picocolors'
5
5
  import { LOGIN_WEBSITE_URL } from './constants'
6
6
  import { generateLoginUrl, pollLoginStatus } from './login-flow'
7
7
  import {
8
- isSupabaseAuthConfigured,
8
+ hasSupabaseSession,
9
9
  loginViaBrowser,
10
- signInWithPassword,
11
10
  } from './supabase-auth'
12
11
  import {
13
12
  flushAnalytics,
@@ -40,18 +39,14 @@ export async function runSupabaseLogin(): Promise<void> {
40
39
  console.log(bold('Anvil Login'))
41
40
  console.log()
42
41
 
43
- const envEmail = process.env.ANVIL_LOGIN_EMAIL
44
- const envPassword = process.env.ANVIL_LOGIN_PASSWORD
42
+ if (hasSupabaseSession()) {
43
+ console.log(green('Already signed in to Anvil on this machine.'))
44
+ console.log('Run `anvil logout` before signing in with a different account.')
45
+ return
46
+ }
45
47
 
46
48
  try {
47
- let user
48
- if (envEmail && envPassword) {
49
- console.log(`Signing in as ${envEmail}...`)
50
- user = await signInWithPassword(envEmail, envPassword)
51
- } else {
52
- console.log('Waiting for you to finish signing in in your browser…')
53
- user = await loginViaBrowser()
54
- }
49
+ const user = await loginViaBrowser()
55
50
 
56
51
  if (user.id) {
57
52
  identifyUser(user.id, { email: user.email, anvil: IS_ANVIL })
@@ -80,7 +75,7 @@ export async function runSupabaseLogin(): Promise<void> {
80
75
  export async function runPlainLogin(): Promise<void> {
81
76
  // Managed gateway mode uses Supabase auth (the gateway verifies a Supabase
82
77
  // JWT), not the Anvil device-code flow.
83
- if (isManagedGatewayMode() && isSupabaseAuthConfigured()) {
78
+ if (isManagedGatewayMode()) {
84
79
  return runSupabaseLogin()
85
80
  }
86
81
 
@@ -20,6 +20,13 @@ import open from 'open'
20
20
  import { logger } from '../utils/logger'
21
21
  import { getUserCredentials, saveUserCredentials, type User } from '../utils/auth'
22
22
 
23
+ // Managed installs authenticate against the hosted Anvil Supabase project.
24
+ // This is a publishable client key; provider/service secrets remain server-side.
25
+ const MANAGED_SUPABASE_URL =
26
+ 'https://tqolntrdmbbaptmxihtq.supabase.co'
27
+ const MANAGED_SUPABASE_PUBLISHABLE_KEY =
28
+ 'sb_publishable_r6L6tZj0xSxwaY0nehNHAw_9XpkQkie'
29
+
23
30
  /** GoTrue session as returned by /token and /verify. */
24
31
  interface SupabaseSession {
25
32
  access_token: string
@@ -34,18 +41,12 @@ interface SupabaseSession {
34
41
  }
35
42
 
36
43
  function supabaseUrl(): string | undefined {
37
- const url = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL
38
- return url ? url.replace(/\/+$/, '') : undefined
44
+ return MANAGED_SUPABASE_URL
39
45
  }
40
46
 
41
47
  /** The anon/publishable key — GoTrue requires it as the `apikey` header. */
42
48
  function supabaseAnonKey(): string | undefined {
43
- return (
44
- process.env.SUPABASE_PUBLISHABLE_KEY ??
45
- process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY ??
46
- process.env.SUPABASE_ANON_KEY ??
47
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
48
- )
49
+ return MANAGED_SUPABASE_PUBLISHABLE_KEY
49
50
  }
50
51
 
51
52
  /** True when Supabase auth can run (URL + anon key configured). */
@@ -153,9 +154,7 @@ async function refreshSupabaseSession(refreshToken: string): Promise<User> {
153
154
  /** Hosted sign-in page that completes auth in the browser, then redirects the
154
155
  * session back to the CLI's loopback callback. Override with ANVIL_LOGIN_URL. */
155
156
  export function getLoginPageUrl(): string {
156
- return (
157
- process.env.ANVIL_LOGIN_URL ?? 'https://cli.tryanvil.dev/login'
158
- ).replace(/\/+$/, '')
157
+ return 'https://cli.tryanvil.dev/login'
159
158
  }
160
159
 
161
160
  /** Decode a JWT payload (no verification — only for display id/email). */
@@ -306,12 +305,6 @@ export function hasSupabaseSession(): boolean {
306
305
  */
307
306
  export async function ensureSignedIn(): Promise<void> {
308
307
  if (hasSupabaseSession()) return
309
- const email = process.env.ANVIL_LOGIN_EMAIL
310
- const password = process.env.ANVIL_LOGIN_PASSWORD
311
- if (email && password) {
312
- await signInWithPassword(email, password)
313
- return
314
- }
315
308
  await loginViaBrowser()
316
309
  }
317
310
 
package/src/utils/auth.ts CHANGED
@@ -122,7 +122,7 @@ export const getAuthTokenDetails = (
122
122
  return { token: userCredentials.authToken, source: 'credentials' }
123
123
  }
124
124
 
125
- const envToken = ciEnv.ANVIL_API_KEY
125
+ const envToken = isManagedGatewayMode() ? undefined : ciEnv.ANVIL_API_KEY
126
126
  if (envToken) {
127
127
  return { token: envToken, source: 'environment' }
128
128
  }
@@ -50,10 +50,7 @@ export const isDirectDeepSeekMode = (): boolean =>
50
50
  * identity (no external account backend is required).
51
51
  */
52
52
  export const getManagedGatewayUrl = (): string | undefined => {
53
- // ANVIL_GATEWAY_URL remains an escape hatch for development and tests, but
54
- // production installs must not depend on a locally supplied environment.
55
- const explicit = process.env.ANVIL_GATEWAY_URL?.trim()
56
- return (explicit || MANAGED_GATEWAY_URL).replace(/\/+$/, '')
53
+ return MANAGED_GATEWAY_URL
57
54
  }
58
55
 
59
56
  /** True when the managed gateway is configured (see {@link getManagedGatewayUrl}). */
@@ -34585,8 +34585,7 @@ var DEFAULT_DIRECT_DEEPSEEK_MODEL = "deepseek-v4-pro";
34585
34585
  var getDirectDeepSeekApiKey = () => process.env.DEEPSEEK_API_KEY;
34586
34586
  var isDirectDeepSeekMode = () => Boolean(getDirectDeepSeekApiKey());
34587
34587
  var getManagedGatewayUrl = () => {
34588
- const explicit = process.env.ANVIL_GATEWAY_URL?.trim();
34589
- return (explicit || MANAGED_GATEWAY_URL).replace(/\/+$/, "");
34588
+ return MANAGED_GATEWAY_URL;
34590
34589
  };
34591
34590
  var isManagedGatewayMode = () => Boolean(getManagedGatewayUrl());
34592
34591
  function remapModelForDirectDeepSeek(model) {
@@ -52329,5 +52328,5 @@ function setTreeSitterWasmPath2(wasmPath) {
52329
52328
  setTreeSitterWasmPath(wasmPath);
52330
52329
  }
52331
52330
 
52332
- //# debugId=5C15E7A7E1B3AA1764756E2164756E21
52331
+ //# debugId=91505A07A7B3B56B64756E2164756E21
52333
52332
  //# sourceMappingURL=index.cjs.map
@@ -34502,8 +34502,7 @@ var DEFAULT_DIRECT_DEEPSEEK_MODEL = "deepseek-v4-pro";
34502
34502
  var getDirectDeepSeekApiKey = () => process.env.DEEPSEEK_API_KEY;
34503
34503
  var isDirectDeepSeekMode = () => Boolean(getDirectDeepSeekApiKey());
34504
34504
  var getManagedGatewayUrl = () => {
34505
- const explicit = process.env.ANVIL_GATEWAY_URL?.trim();
34506
- return (explicit || MANAGED_GATEWAY_URL).replace(/\/+$/, "");
34505
+ return MANAGED_GATEWAY_URL;
34507
34506
  };
34508
34507
  var isManagedGatewayMode = () => Boolean(getManagedGatewayUrl());
34509
34508
  function remapModelForDirectDeepSeek(model) {
@@ -52322,5 +52321,5 @@ export {
52322
52321
  ANVIL_BINARY
52323
52322
  };
52324
52323
 
52325
- //# debugId=B50622D584101C2364756E2164756E21
52324
+ //# debugId=EA738E5B98C042E564756E2164756E21
52326
52325
  //# sourceMappingURL=index.mjs.map